API

Two surfaces, one source of truth. GraphQL is the primary interface; REST is generated from the same schema for clients that prefer it. Both honour the same auth, residency, and field-level RBAC rules.

Picking a surface

GraphQL is the default. It returns exactly what the caller asks for, batches efficiently with a single round-trip per page, and the schema introspection drives type generation in @estokad/sdk. Use it from any TypeScript app.

REST exists for clients that don't want a GraphQL transport — webhooks subscribers, server-to-server integrations written in languages without strong GraphQL tooling, simple curl scripts. The endpoints are documented as OpenAPI 3.1; download the spec from /v1/<workspace>/openapi.json.

For framework-specific helpers (auto-tagging components, draft mode helpers, the getEstokad() accessor), use @estokad/next or its sibling adapters.

Auth

Every request needs an API key in Authorization: Bearer estk_…. Keys are issued per workspace from /settings/api-keys in the Studio with one of four scopes:

| Scope | Reads | Writes | Manages | |---|---|---|---| | read | published only | — | — | | read_draft | published + drafts | — | — | | write | yes | content entries | — | | management | yes | content + schema | yes |

management keys can push schema, change billing, mint preview tokens. Treat them like database credentials.

Draft mode

Draft entries are invisible to read-scope keys. A read_draft key sees both. The Next.js adapter wires Next's draft-mode cookie to a per-request override:

import { draftMode } from 'next/headers'
import { getEstokad } from '@estokad/next'

const { isEnabled } = await draftMode()
const cms = getEstokad({ draft: isEnabled })
const article = await cms.entry('article', slug).fetch()

Preview tokens — used by visual edit and editorial preview links — are short-lived JWTs signed by KMS. See Visual edit for the full flow.

Rate limits

Free-tier rate limits are 100 req/sec per workspace. Paid tiers raise that to 1000 req/sec. Hard ceilings are configurable on the Sovereign tier. The API returns standard X-RateLimit-* headers.

Residency

Every request lands in the workspace's chosen region. The hostname api.estokad.com resolves to a regional gateway via Cloudflare; if your workspace is provisioned in eu-bru-1 (Belgium), the request never leaves Belgium. Cross-region reads are not possible — by design.

Surfaces in detail

  • REST — endpoint reference, query parameters, response shape.
  • GraphQL — schema, query patterns, the @estokad/sdk typed client.