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).
The Document Service is a data-access layer: it interacts with the database and is not aware of user permissions or field visibility. Results may include private fields, passwords, and restricted relations.
The built-in REST and GraphQL APIs automatically sanitize responses before sending them to the client. But if you build custom controllers or plugin routes that call Document Service methods directly, you must sanitize the output yourself before returning it. Use strapi.contentAPI.sanitize.output() in your controller (see Sanitization and validation when building custom controllers for details and code 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. |
The publish(), unpublish(), and discardDraft() methods are only available when the Draft & Publish feature is enabled on the content-type. Calling these methods on a content-type that does not have Draft & Publish enabled will throw an error. To enable Draft & Publish, see the Draft & Publish documentation.
findOne()
Find a document matching the passed documentId and parameters.
Syntax: findOne(parameters: Params) => Document
Parameters
| Parameter | Description | Default | Type |
|---|---|---|---|
documentId | Document id | ID | |
locale | Locale of the document to find. | Default locale | String or undefined |
status | If Draft & Publish is enabled for the content-type: Publication status, can be:
| 'draft' | 'published' or 'draft' |
fields | Select fields to return | All fields (except those not populated by default) | Object |
populate | Populate results with additional fields. | null | Object |
Example
If only a documentId is passed without any other parameters, findOne() returns the draft version of a document in the default locale:
await strapi.documents('api::restaurant.restaurant').findOne({
documentId: 'a1b2c3d4e5f6g7h8i9j0klm',
});
{
documentId: "a1b2c3d4e5f6g7h8i9j0klm",
name: "Biscotte Restaurant",
publishedAt: null, // draft version (default)
locale: "en", // default locale
// …
}
The findOne() method returns the matching document if found, otherwise returns null.
findFirst()
Find the first document matching the parameters.
Syntax: findFirst(parameters: Params) => Document
Parameters
| Parameter | Description | Default | Type |
|---|---|---|---|
locale | Locale of the documents to find. | Default locale | String or undefined |
status | If Draft & Publish is enabled for the content-type: Publication status, can be:
| 'draft' | 'published' or 'draft' |
filters | Filters to use | null | Object |
fields | Select fields to return | All fields (except those not populate by default) | Object |
populate | Populate results with additional fields. | null | Object |
Examples
Generic example
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):
await strapi.documents('api::restaurant.restaurant').findFirst()
{
documentId: "a1b2c3d4e5f6g7h8i9j0klm",
name: "Restaurant Biscotte",
publishedAt: null,
locale: "en"
// …
}