API
REST API
Every route the CMS router serves, relative to where it is mounted.
Routes starting with _ are registered before /:collection, so they never collide with a collection slug. Errors use one envelope: { "error": { "code", "message", "details"? } }.
Documents
GET /:collection,POST /:collection(body{ data, locale? })GET|PATCH|PUT|DELETE /:collection/:id: PATCH merges{ data }, PUT replaces itPOST /:collection/:id/_patch: JSON Patch, body{ operations }POST /:collection/:id/_publish,_unpublish,_request-review,_withdraw-reviewGET|POST|DELETE /:collection/:id/_schedule-publishGET /:collection/:id/_revisions,POST /:collection/:id/_revisions/:revisionId/_restoreGET /:collection/:id/_translations,POST /:collection/:id/_translateGET /:collection/_tags?field=GET|PATCH /_globals/:slug
Lists
Lists accept filter.<field>=value or filter.<field>.<op>=value (equals, notEquals, gt, gte, lt, lte, contains, startsWith, in, exists), sort (a field or createdAt, updatedAt, publishedAt; - for descending), limit, cursor, locale, status, and include. They return { items, nextCursor, included? }.
curl "https://<host>/api/_public/posts?filter.title.contains=hello&sort=-publishedAt&limit=10"CMS
GET /_cms/collections: every definition with the caller's permissionsGET|POST /_cms/proposals,GET /_cms/proposals/:id,POST /_cms/proposals/:id/_approve,_rejectGET /_cms/search,POST /_cms/search/reindexPOST /_cms/pages/_preview,GET /_cms/activityGET|POST /_cms/api-keys,DELETE /_cms/api-keys/:idGET|POST /_media,GET /_media/:id/raw,DELETE /_media/:idPOST /mcp: the MCP server
Public
GET /_public/:collection,/_public/:collection/:id,/_public/:collection/_tagsGET /_public/_globals/:slug,/_public/_search,/_public/_pages?path=
Public routes return only live content of collections whose public rule allows the caller.