Document Service API
The Document Service API is built on top of the Query Engine API and is used to perform CRUD (create, retrieve, update, and delete) operations on documents .
The Document Service API also supports counting documents and, if Draft & Publish is enabled on the content-type, performing Strapi-specific operations such as publishing, unpublishing, and discarding drafts.
In Strapi 5, documents are uniquely identified by their documentId at the API level.
The Document Service API replaces the Entity Service API used in Strapi v4 (see Strapi v4 documentation).
Additional information on how to migrate from the Entity Service API to the Document Service API can be found in the migration reference.
Relations can also be connected, disconnected, and set through the Document Service API, just like with the REST API (see the REST API relations documentation for examples).
Configuration
The documents.strictParams option enables strict validation of parameters passed to Document Service methods such as findMany and findOne. Configure it in the API configuration file (./config/api.js or ./config/api.ts). See the API configuration table for details on documents.strictParams.
Document objects
Document methods return a document object or a list of document objects, which represent a version of a content entry grouped under a stable documentId. Returned objects typically include:
documentId: Persistent identifier for the entry across locales and draft/published versions.id: Database identifier for the specific locale/version record.- model fields: All fields defined in the content-type schema. Relations, components, and dynamic zones are not populated unless you opt in with
populate(see Populating fields) or limit fields withfields(see Selecting fields). - metadata:
publishedAt,createdAt,updatedAt, andcreatedBy/updatedBywhen available.
Optionally, document objects can also include a status and locale property if Draft & Publish and Internationalization are enabled for the content-type.
Method overview
Each section below documents the parameters and examples for a specific method:
| Method | Purpose |
|---|---|
findOne() | Fetch a document by documentId, optionally scoping to a locale or status. |
findFirst() | Return the first document that matches filters. |
findMany() | List documents with filters, sorting, and pagination. |
create() | Create a document, optionally targeting a locale. |
update() | Update a document by documentId. |
delete() | Delete a document or a specific locale version. |
publish() | Publish the draft version of a document. |
unpublish() | Move a published document back to draft. |
discardDraft() | Drop draft data and keep only the published version. |
count() | Count how many documents match the parameters. |
findOne()
Syntax: findOne(parameters: Params) => Document
Find a document matching the passed documentId and parameters. If only a documentId is passed without any other parameters, findOne() returns the draft version of a document in the default locale. Returns the matching document if found, otherwise returns null.
published or draft. Default: draft. See status docs.await strapi.documents('api::restaurant.restaurant').findOne({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm'
}){
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"name": "Biscotte Restaurant",
"publishedAt": null,
"locale": "en"
}findFirst()
Syntax: findFirst(parameters: Params) => Document
Find the first document matching the parameters. By default, findFirst() returns the draft version, in the default locale, of the first document for the passed unique identifier (collection type id or single type id).
published or draft. Default: draft. See status docs.If no locale or status parameters are passed, results return the draft version for the default locale.
await strapi.documents('api::restaurant.restaurant').findFirst(){
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"name": "Restaurant Biscotte",
"publishedAt": null,
"locale": "en"
}findMany()
Syntax: findMany(parameters: Params) => Document[]
Find documents matching the parameters. When no parameter is passed, findMany() returns the draft version in the default locale for each document.
published or draft. Default: draft. See status docs.Available filters are detailed in the filters page of the Document Service API reference.
If no locale or status parameters are passed, results return the draft version for the default locale.
await strapi.documents('api::restaurant.restaurant').findMany()[
{
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"name": "Biscotte Restaurant",
"publishedAt": null,
"locale": "en"
},
{
"documentId": "j9k8l7m6n5o4p3q2r1s0tuv",
"name": "Pizzeria Arrivederci",
"publishedAt": null,
"locale": "en"
}
]create()
Syntax: create(parameters: Params) => Document
Create a new document. If no locale parameter is passed, create() creates the draft version of the document for the default locale.
published to automatically publish the draft version of a document while creating it. See status docs.If the Draft & Publish feature is enabled on the content-type, you can automatically publish a document while creating it (see status documentation).
await strapi.documents('api::restaurant.restaurant').create({
data: {
name: 'Restaurant B'
}
}){
"documentId": "ln1gkzs6ojl9d707xn6v86mw",
"name": "Restaurant B",
"publishedAt": null,
"locale": "en"
}update()
Syntax: update(parameters: Params) => Promise<Document>
Update a document by documentId. If no locale parameter is passed, update() updates the document for the default locale.
published to automatically publish the draft version of a document while updating it. See status docs.Published versions are read-only, so you can not technically update the published version of a document. To update a document and publish the new version right away, you can:
- update its draft version with
update(), then publish it withpublish(), - or directly add
status: 'published'along with the other parameters passed toupdate()(seestatusdocumentation).
It's not recommended to update repeatable components with the Document Service API (see the related breaking change entry for more details).
await strapi.documents('api::restaurant.restaurant').update({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm',
data: { name: "New restaurant name" }
}){
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"name": "New restaurant name",
"locale": "en",
"publishedAt": null
}delete()
Syntax: delete(parameters: Params): Promise<{ documentId: ID, entries: Number }>
Delete a document or a specific locale version. If no locale parameter is passed, delete() only deletes the default locale version of a document. This deletes both the draft and published versions.
null (deletes only the default locale). See locale docs.await strapi.documents('api::restaurant.restaurant').delete({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm',
}){
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"entries": [
{
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"name": "Biscotte Restaurant",
"publishedAt": "2024-03-14T18:30:48.870Z",
"locale": "en"
}
]
}publish()
Syntax: publish(parameters: Params): Promise<{ documentId: ID, entries: Number }>
Publish the draft version of a document. This method is only available if Draft & Publish is enabled on the content-type. If no locale parameter is passed, publish() only publishes the default locale version of the document.
await strapi.documents('api::restaurant.restaurant').publish({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm',
});{
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"entries": [
{
"documentId": "a1b2c3d4e5f6g7h8i9j0klm",
"name": "Biscotte Restaurant",
"publishedAt": "2024-03-14T18:30:48.870Z",
"locale": "en"
}
]
}unpublish()
Syntax: unpublish(parameters: Params): Promise<{ documentId: ID, entries: Number }>
Move a published document back to draft. This method is only available if Draft & Publish is enabled on the content-type. If no locale parameter is passed, unpublish() only unpublishes the default locale version of the document.
await strapi.documents('api::restaurant.restaurant').unpublish({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm'
});{
"documentId": "lviw819d5htwvga8s3kovdij",
"entries": [
{
"documentId": "lviw819d5htwvga8s3kovdij",
"name": "Biscotte Restaurant",
"publishedAt": null,
"locale": "en"
}
]
}discardDraft()
Syntax: discardDraft(parameters: Params): Promise<{ documentId: ID, entries: Number }>
Drop draft data and keep only the published version. This method is only available if Draft & Publish is enabled on the content-type. If no locale parameter is passed, discardDraft() discards draft data and overrides it with the published version only for the default locale.
strapi.documents.discardDraft({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm',
});{
"documentId": "lviw819d5htwvga8s3kovdij",
"entries": [
{
"documentId": "lviw819d5htwvga8s3kovdij",
"name": "Biscotte Restaurant",
"publishedAt": null,
"locale": "en"
}
]
}count()
Syntax: count(parameters: Params) => number
Count how many documents match the parameters. If no parameter is passed, the count() method returns the total number of documents for the default locale.
published to count only published documents, draft to count draft documents (returns all documents). Default: draft. See status docs.Since published documents necessarily also have a draft counterpart, a published document is still counted as having a draft version.
This means that counting with the status: 'draft' parameter still returns the total number of documents matching other parameters, even if some documents have already been published and are not displayed as "draft" or "modified" in the Content Manager anymore. There currently is no way to prevent already published documents from being counted.
await strapi.documents('api::restaurant.restaurant').count()