Docs

What changed in October 2026

Every Capa site moved to a new platform on 2026-10-01. Legacy reads answer as before. Send them to cdn.capacms.com.

View as Markdown

On 2026-10-01 every Capa site moved to the platform these docs describe. /v2/api and /v3/api kept their routes, parameters and response shapes, so a site built on them keeps working without a code change.

Send reads through the CDN

Send every /v2/api and /v3/api request to https://cdn.capacms.com. Once the origin lock is enforced, the legacy read routes and /files answer only through Capa's CDN, and a request that reaches Capa's servers directly is refused:

{ "error": "Direct origin access is not allowed. Request this through the CDN hostname." }

That answer is a 403. If your site, a build script or a server job calls another host for these routes, point it at cdn.capacms.com.

curl 'https://cdn.capacms.com/v2/api/articles?slug=a-preview-you-can-trust' \
  -H "x-api-key: $CAPA_KEY"

Your keys did not change. The legacy reference is the full contract for these routes.

Fixed on this platform

This platform answers only with your own project's data, and a production key reads only published content. A few answers differ from the old platform's because of that:

WhereBefore 2026-10-01Now
GET /v2/api/{id} with another project's entry or model id200 with that project's content404 {"error":"Model not found"}, the same as an id that does not exist
?id= with another project's entry id404 {"error":"Model instance not found"}404 {"error":"Model instance version not found"}, the same as an id that does not exist
a sorted list read with a pk_ keyan entry with a newer draft was served and sorted by the draft, and sort=<relation>.<field> read the related entry's draft. Empty tags were nullpublished data only, sorted by published values. Empty tags are [], as in an unsorted list
sort=<relation>.<field> on a relation that points into another projectsorted by the other project's valuesorts like an empty relation, last in both directions
extended searchlastUpdatedByUser carried the last editor's id, email, name and avatarlastUpdatedByUser is always null
extended searcha model whose category pointed into another project showed that project's categoryonly your project's categories and entries

If a page depended on one of the old answers, read the row's "Now" column for what it gets today.

When you want more

The legacy API is frozen: its answers do not change. New features land on /api/, a dated API you can adopt one page at a time while the rest of your site stays on /v2/api.