REST API: publicationFilter
The REST API accepts an optional publicationFilter query parameter when Draft & Publish is enabled. Use it to query derived publication cohorts such as never-published or modified documents. The status parameter still selects whether each matching document returns its draft or published row.
The Draft & Publish feature must be enabled on the content-type.
Default status
When status is omitted, the REST API defaults to status=published before applying publicationFilter.
| Query | Effective behavior |
|---|---|
?publicationFilter=never-published | Empty (cohort is draft-only; default status is published) |
?status=draft&publicationFilter=never-published | Never-published draft rows |
?publicationFilter=modified | Published rows in the modified cohort |
?status=draft&publicationFilter=modified | Draft rows in the modified cohort |
?publicationFilter=published-without-draft | Orphan published rows (default status=published is correct) |
The Document Service API defaults to status=draft instead. See Document Service API: default status.
Cohort definitions, the full status × publicationFilter matrix, Content Manager mapping, and validation rules are documented on Document Service API: publicationFilter.
Accepted kebab-case values: never-published, has-published-version, modified, unmodified, never-published-document, has-published-version-document, published-without-draft, published-with-draft. Invalid values return HTTP 400.
Get never-published draft documents
Pair-scoped never-published only matches draft rows. Pass status=draft because REST defaults to status=published.
GET /api/restaurants?status=draft&publicationFilter=never-published
JavaScript query (built with the qs library):
The query URL above was built using the `qs` library.
qs can be run locally on your machine, as shown in the following code example, or you can use our interactive query builder online tool.
const qs = require('qs');
const query = qs.stringify(
{
status: 'draft',
publicationFilter: 'never-published',
},
{
encodeValuesOnly: true,
}
);
await request(`/api/restaurants?${query}`);
{
"data": [
{
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"name": "New Restaurant",
"publishedAt": null,
"locale": "en"
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
Get modified documents
The modified cohort includes pairs where the draft row is newer than its published peer. With no status parameter, REST returns published rows from that cohort. Pass status=draft to return the draft rows instead.
GET /api/restaurants?publicationFilter=modified
JavaScript query (built with the qs library):
The query URL above was built using the `qs` library.
qs can be run locally on your machine, as shown in the following code example, or you can use our interactive query builder online tool.
const qs = require('qs');
const query = qs.stringify(
{
publicationFilter: 'modified',
},
{
encodeValuesOnly: true,
}
);
await request(`/api/restaurants?${query}`);
{
"data": [
{
"documentId": "znrlzntu9ei5onjvwfaalu2v",
"name": "Biscotte Restaurant",
"publishedAt": "2024-03-14T15:40:45.330Z",
"locale": "en"
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
Get published rows without a draft peer
The published-without-draft cohort matches published rows that have no draft sibling for the same (documentId, locale). Because REST defaults to status=published, you can omit status in the query URL.
GET /api/restaurants?publicationFilter=published-without-draft
JavaScript query (built with the qs library):
The query URL above was built using the `qs` library.
qs can be run locally on your machine, as shown in the following code example, or you can use our interactive query builder online tool.
const qs = require('qs');
const query = qs.stringify(
{
publicationFilter: 'published-without-draft',
},
{
encodeValuesOnly: true,
}
);
await request(`/api/restaurants?${query}`);
{
"data": [
{
"documentId": "abcdefghijklmno456",
"name": "Legacy Restaurant",
"publishedAt": "2024-01-10T09:15:00.000Z",
"locale": "en"
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}
Combine with other parameters
publicationFilter can be combined with filters, locale, populate, and other REST parameters. All conditions are applied together.
Deprecated hasPublishedVersion parameter
The boolean hasPublishedVersion query parameter is deprecated. Accepted values: true, false, 'true', or 'false'. Strapi maps it to document-scoped publicationFilter values:
hasPublishedVersion | Maps to |
|---|---|
false / 'false' | never-published-document |
true / 'true' | has-published-version-document |
Example: GET /api/restaurants?status=draft&hasPublishedVersion=false
If both publicationFilter and hasPublishedVersion are sent, publicationFilter takes precedence.
Prefer publicationFilter for new integrations.