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.