For apps and every screen

Write it once.
Show it anywhere.

Underneath, Capa is headless. The same entries feed your website, your iOS and Android apps and the screen in the shop window, and each one asks for exactly the fields it shows.

osterialumen.com/menu

Autumn menu, now serving

Wild mushroom risotto, brown butter squash and the last of the figs.

  • Mushroom risottoWild mushrooms, aged parmesan.$26
  • Squash agnolottiBrown butter, sage, amaretti.$24
  • Fig and ricotta tartThe last figs of the year.$12
GET /api/entries/menus?select=title,intro,items(name,price,description)&limit=1
REST or GraphQL

Plain HTTP,
or a typed schema.

Anything that can send an HTTPS request can read Capa: a Swift app, a Kotlin app, the small computer behind a menu board. Teams on GraphQL get a schema typed from what their key can read, with persisted queries cached at the edge.

Same entries, same cursor, same cache

Request
GET /api/entries/articles?select=title,author(name)&limit=2
Host: cdn.capacms.com
x-api-key: cap_live_…
Capa-Version: 2026-10-01
select = "title,author(name)"  # author, expanded
limit  = 2                     # 1 to 200 a page
From @capacms/sdk
await capa.entries.list("articles", {
  select: ["title", { author: ["name"] }],
  limit: 2,
});
Response200
{ "data": [
    { "id": "…2e", "model": "articles",
      "status": "published",
      "fields": {
        "title": "Winter Field Guide 2026",
        "author": { "id": "…12", "model": "authors",
          "status": "published",
          "fields": { "name": "Brin Cole" } } } },
    { "id": "…2c", "model": "articles",
      "status": "published",
      "fields": {
        "title": "Merino or Synthetic?",
        "author": { "id": "…13", "model": "authors",
          "status": "published",
          "fields": { "name": "Cody Marsh" } } } } ],
  "page": { "limit": 2, "hasNext": true,
    "next": "c1.eyJ2Ijoi…", "hasPrev": false, "prev": null },
  "meta": { "version": "2026-10-01", "contract": 1,
    "environment": "production", "requestId": "req_0f3c…" } }
Dated versions

The app in the store
keeps working.

Apps stay on phones for months after you ship them. Each request names a Capa-Version date, and a published date never changes shape, so last spring’s build reads today’s content the way it always has.

  • We do not retire a version while you are still calling it.
Capa-Version
Capa-Version: 2026-10-01
  1. 2026-10-01Your site runs on this version.
  2. Next versionMove when you are ready.

A new key is pinned to the newest date the day you mint it, and the pin never moves on its own.

Images

The right image
for every screen.

One upload serves every size and pixel density. Ask for a width, a fit, a dpr of 1 to 3 and WebP or AVIF in the URL. Phones get small files. The big screen in the lobby gets a sharp one.

cdn.capacms.com/files/…/autumn-menu.jpg
  1. 1x screen?width=320&dpr=1&format=webp320 px wide
  2. 2x screen?width=320&dpr=2&format=webp640 px wide
  3. 3x screen?width=320&dpr=3&format=webp960 px wide

The same upload for a phone at each pixel density. Each size is cached at the edge for a year.

Agents

Building the next screen?
Your agent reads along.

The Capa MCP server gives Claude Code, Cursor and Codex your schema and content, read with your key. Ask it to wire up the new watch screen and it writes the query against your real models, then runs it once to check.

Claude Code

Write the query for the blog index: the 10 newest featured articles with their author’s name. Give me the SDK code for a Next.js server component.

  1. capa_graphql_schema{ "model": "articles" }Running
  2. capa_explore_data{ "model": "articles", "field": "featured", "sample": 0 }Running
  3. capa_graphql_build{ "model": "articles", "fields": ["title", { "field": "author", "fields": ["name"] }], "filter": { "featured": { "eq": true } }, "sort": ["publishedAt_DESC"], "first": 10, "run": true, "code": "next" }Running

Here is the server component. It reads through graphql() from @capacms/sdk/nextjs, tagged with every model the query reads, so a publish refreshes the page.

One source.
Every screen.

Free to start. Point your first screen at Capa this afternoon.