Skip to content
Talk to our solutions team

Content API

Every route requires a bearer token:

Authorization: Bearer <token>

The four CEPT headers resolve the tenant, and every content type, store and asset is scoped to it.

X-Customer: acme
X-Product: site
X-Env: prod
X-Tenant: acme

A request that cannot resolve a tenant is refused rather than served against a default. The :contentstore and :contentapp path segments select within the tenant and are not a substitute for it.

The health and readiness probes are the only unauthenticated surface.

MethodPathPurpose
GET/api/:pluralStrapi: a page of entries
GET/api/:plural/:documentIdStrapi: one document
POST/api/:pluralStrapi: create
PUT/api/:plural/:documentIdStrapi: update
DELETE/api/:plural/:documentIdStrapi: delete
GET/spaces/:space/environments/:env/entriesContentful: a page of entries
GET/spaces/:space/environments/:env/entries/:idContentful: one entry
GET/spaces/:space/environments/:env/content_typesContentful: the type catalogue
GET/spaces/:space/entriesContentful, environment-scoped base URL
GET/spaces/:space/entries/:idas above
GET/spaces/:space/content_typesas above
GET/contentapp/listApps visible to the tenant
POST/app/:contentapp/preview-tokenMint a preview grant
GET/contentstore/listStores available to the tenant
POST/store/:contentstore/assetUpload
GET/store/:contentstore/assetRead by id or path
GET/store/:contentstore/asset/id/:idRead by id
GET/store/:contentstore/asset/path/*pathRead by path
PUT/store/:contentstore/assetReplace the bytes, or add a version
PATCH/store/:contentstore/assetRename or move
DELETE/store/:contentstore/assetDelete
POST/store/:contentstore/folderCreate a folder
GET/store/:contentstore/listList a folder
PUT/store/:contentstore/folderRename or move a folder
DELETE/store/:contentstore/folderDelete a folder

Full dialect reference: Strapi delivery.

ParameterDefaultNotes
localeevery locale
statuspublisheddraft requires entitlement or a preview token
filters[field][$op]See the operator table
sort(documentId, locale)field:asc, field:desc
fieldsevery fieldComma-separated
populatenoneRelation names or dotted paths, to depth 10
pagination[page]1
pagination[pageSize]25Clamped to 100
pagination[start] / pagination[limit]The offset form
pagination[withCount]true
previewA preview token

200 with { "data": [...], "meta": { "pagination": {...} } }.

Takes locale, status, fields, populate and preview.

200 with { "data": {...}, "meta": {} }. 404 when the document has no row in the requested locale.

Body {"data": {...}, "publish": false}, up to 8 MiB. Takes locale.

201 with the row that landed. A new entry is a draft unless publish is true.

Body {"data": {...}, "publish": true}. Takes locale.

200 with the row that landed. Omitting publish leaves the publish state alone.

Takes locale. 204 No Content.

Statuserror.nameWhen
400ValidationErrorMalformed query or body, unknown field, unsupported operator
403ForbiddenErrorThe entity’s rules refused this caller
404NotFoundErrorNo such type, ambiguous plural, or no such document in that locale
400ApplicationErrorThe request could not be served

Full dialect reference: Contentful delivery.

GET /spaces/:space/environments/:env/entries

Section titled “GET /spaces/:space/environments/:env/entries”
ParameterDefaultNotes
content_typerequiredType name or plural
localethe row’s own* pivots every locale into one entry
fields.x, fields.x[op], sys.idne, in, nin, lt, lte, gt, gte, exists, match
order(documentId, locale)- prefixes a descending term
selectevery fieldComma-separated
limit100Clamped to 1000
skip0
include1Link depth, up to 10
previewA preview token

X-Contentful-Preview: true selects the draft view for a caller entitled to it.

200 with { "sys": {"type":"Array"}, "total", "skip", "limit", "items", "includes" }.

GET /spaces/:space/environments/:env/entries/:id

Section titled “GET /spaces/:space/environments/:env/entries/:id”

No content_type needed: the id is a document identity, so the type is found across the space. Takes locale and preview.

200 with one { "sys": {...}, "fields": {...} } entry.

GET /spaces/:space/environments/:env/content_types

Section titled “GET /spaces/:space/environments/:env/content_types”

200 with the space’s content types, their fields, each field’s CDA type, and whether it is required and localized.

Statussys.idWhen
400BadRequestMissing content_type, or a malformed query string
400InvalidQueryUnknown field, or include above the ceiling
403AccessDeniedThe entity’s rules refused this caller
404NotFoundUnknown space, unknown type, or no such entry

200 with the content apps configured for this tenant.

{ "type": "posts", "space": "blog", "documentId": "01J9Y…", "locale": "en", "ttlSeconds": 900 }

Only type is required. ttlSeconds defaults to 1800 and is clamped to 86400.

{ "token": "kp1.…", "expiresAt": "…", "type": "blog.post", "space": "blog",
"documentId": "01J9Y…", "locale": "en" }
StatusWhen
200Minted
400No type, or the body is not valid JSON
403The caller may not preview this type
404No such type, or an ambiguous plural
501The app has no preview signing secret configured

Present the token as ?preview=<token> or X-Preview-Token. See Preview.

Full guide: Assets.

200 with the content stores available to this tenant.

multipart/form-data, with the file in the file part.

ParameterNotes
pathFolder path to file the asset under
parentfolderidFolder by id, instead of path
createfoldersCreate missing folders along path
filenameOverride the uploaded name
overwriteReplace, or add a version when versioning is on
localeRequired when the store has locales enabled
descriptionStored on the sidecar
cacheexpiryPer-asset cache policy
transformApply a transform on the way in

200 with the asset record.

GET /store/:contentstore/asset, /asset/id/:id, /asset/path/*path

Section titled “GET /store/:contentstore/asset, /asset/id/:id, /asset/path/*path”
ParameterNotes
id / pathAddressing, when not in the path
versionPin a version
localeRequired when the store has locales enabled
transformA native transform expression
w, h, fit, fm, f, formatImage parameters
metadata=trueReturn the metadata as JSON instead of the bytes
downloadAsk for a download disposition

Responds 200 or 206, 304 on a matching validator, 416 for an unsatisfiable byte range, or 302 to a presigned URL for an object store.

multipart/form-data. Takes id or path, plus locale, version and transform.

Takes path, newpath and locale. Renames or moves an asset.

Takes id or path, plus locale.

Takes name, path, parentid and createfolders.

Takes folderid or path, plus type, depth and meta.

Takes parentfolderid, currentname, newname, currentpath, newpath and createfolders.

Takes id or path, plus forcedelete.