ProductsFor your stack
Content APIREST or GraphQL. Same content, your call.
One read API for every site, app and screen you ship. Choose fields and expand relations in a single request, and filter with real boolean logic. Our releases never change a live integration.
curl 'https://cdn.capacms.com/api/entries/articles?select=title,author(name)&limit=2' \
-H "x-api-key: $CAPA_KEY" \
-H 'Capa-Version: 2026-10-01'{
"data": [
{ "id": "…002e", "model": "articles", "status": "published",
"fields": {
"title": "Winter Field Guide 2026",
"author": { "id": "…0012", "model": "authors", "status": "published",
"fields": { "name": "Brin Cole" } } } },
{ "id": "…002c", "model": "articles", "status": "published",
"fields": {
"title": "Merino or Synthetic?",
"author": { "id": "…0013", "model": "authors", "status": "published",
"fields": { "name": "Cody Marsh" } } } }
],
"page": { "limit": 2, "hasNext": true, "next": "c1.eyJ2…" },
"meta": { "version": "2026-10-01", "environment": "production" }
}Ask for exactly what the page needs.
One URL carries the fields, the relations, the filters, the order and the page. Hover any part to see what it does.
GET
Name the fields. author(...) expands the relation in the same request: up to 12 expansions, 4 hops deep.
Generous, and stated up front.
Every request is measured before it runs. A request over a limit is refused with the number it reached and the change that would fit.
- 12Relation expansions per request
- 4 hopsFrom the entry you asked for
- 5,000Entries per request, checked first
- 1 to 200Entries per page, with cursors
A typed schema, built for each key.
The same reads as REST, as a GraphQL schema of every model your key can read. Same limits, same errors, same cache.
Typed from your models
Every model becomes a type, every field keeps the label your editors gave it, and a key restricted to one model sees a schema with one model in it.
Persisted queries
Register documents at build time with capa persist, then send only a hash by GET. The URL stays short and the CDN can answer it.
A cost you can see
Each answer reports what the document cost against the 5,000-entry budget, so a slow query shows up in development, not in production.
Nothing hidden
Every root field runs as a REST read. Ask for extensions.capa and the answer prints the exact REST request it made.
query BlogIndex($first: Int) {
articles(first: $first, sort: [publishedAt_DESC],
filter: { featured: { eq: true } }) {
nodes {
id
title
author { name }
coauthors(first: 3) { nodes { name } }
}
pageInfo { hasNextPage endCursor }
}
}An API that tells you what it is doing.
- Upgrades
Upgrades on your schedule
Each integration stays on the API version it was built on. New behaviour ships as a new version, and you move when you are ready.
- Errors
Errors that say what to do
Every error carries a stable code, a hint in plain words and a link to its page. Over a limit, the hint names the number that fits.
- Drafts
Drafts by key, not by flag
A production key reads published entries only. A development key also reads drafts. Same URL, same code.
- Keys
Keys that do less
Scoped cap_ keys can read one model, expire on a date, rotate with a grace window and only answer your origins.
- Shape
Each related entry once
Add shape=flat and every expanded entry arrives once, in included. Twenty articles by one author carry that author once.
- Safety
Read-only, on purpose
A write to /api/ answers 405 on every host, so a key in a public bundle can never change your site.
Moving to the new API.
Do my /v2 and /v3 integrations keep working?
Yes. /v2/api and /v3/api keep serving the bytes they serve today, with the key you use today. /api/ is a second surface you move to when you want to, route by route.
Which keys work on /api/?
Both families. The pk_ or sk_ key your site already holds reads here unchanged, and scoped cap_live_ and cap_test_ keys work here only. GET /api/me tells you what the key in your hand can do.
Will an API update break my site?
No. Your integration stays on the API version it was built on until you choose to move. Each new version lists exactly what it changes.
How fast are reads?
Reads come from the edge cache, and a publish refreshes only what changed. See Edge Cache for how purging and refilling work.
Your first query, in five minutes.
Mint a key under Developers > Keys, paste one curl, and you are reading your own content.