Getting started
From sign-up to first published entry in roughly ten minutes. The path covers four steps: sign up, install the CLI, push a schema, fetch through the SDK.
1. Sign up
Pick a preset on the pricing page. Stripe takes you to checkout; on success you land in the Studio with an empty workspace. Magic-link sign-in works out of the box; passkeys can be registered from /settings.
The default workspace ships with one space called default. The control plane provisions everything in EU (Frankfurt) unless you bought a country-specific residency module — Belgian, Luxembourgish, Swiss, etc.
2. Install the CLI
In the customer repo where your schemas will live:
pnpm add -D @estokad/cli @estokad/schema
pnpm estokad init
estokad init scaffolds:
estokad.config.ts # workspace, region, apiUrl, paths
schemas/index.ts # re-export entry point
schemas/site-settings.ts # tiny singleton, smoke test the loop
.estokad/.gitignore
The config file:
export default {
workspace: 'your-workspace-slug',
apiUrl: 'https://api.estokad.com',
region: 'eu-fra-1',
}
3. Push a schema
Issue a management API key from /settings/api-keys in the Studio. Keys are prefixed by scope — ek_m_… for management, ek_w_… write, ek_d_… read-draft, ek_r_… read. Set the management key in your shell:
export ESTOKAD_API_KEY='ek_m_…'
Then push:
pnpm estokad push
Expected output:
✓ loaded 1 definitions from ./schemas
✓ compiled to JSON IR (1 types)
✓ pushed to your-workspace@eu-fra-1 (1 types)
✓ state saved to ./.estokad/schema-state.json
The state file maps type/field names to UUIDs across runs — commit it so renames stay stable for your team.
Open the Studio: the siteSettings type now appears in the Library. Create a draft, fill in siteName, publish.
4. Fetch the entry
Install the framework-agnostic SDK or the Next.js adapter:
pnpm add @estokad/sdk
# or, for Next.js (re-exports the SDK + adds draft mode, EstokadProvider,
# auto-tagging Estokad.* components — self-contained, no extra deps):
pnpm add @estokad/next
Issue a read API key (/settings/api-keys, scope read — it looks like ek_r_…) and use it as a public client token. createClient returns a proxy where each content type is a property, so cms.<type> exposes .get(), .list(), and the write methods. Field values sit at the top level of each entry alongside id, status, and publishedAt.
import { createClient } from '@estokad/sdk'
const cms = createClient({
workspace: 'your-workspace-slug',
apiUrl: 'https://api.estokad.com',
apiKey: process.env.ESTOKAD_PUBLIC_KEY, // an ek_r_… read key
})
// Singleton: one entry — read the first (and only) row.
const [settings] = await cms.siteSettings.list({ first: 1 })
console.log(settings.data.siteName) // schema fields live under `data`
In a Next.js App Router page, fetching a collection and a single entry:
import { createClient } from '@estokad/next'
const cms = createClient({
workspace: 'your-workspace-slug',
apiUrl: 'https://api.estokad.com',
apiKey: process.env.ESTOKAD_PUBLIC_KEY,
})
export default async function Home() {
const articles = await cms.article.list({ first: 20, offset: 0 })
return (
<ul>
{articles.map((a) => (
<li key={a.id}>{a.title}</li>
))}
</ul>
)
}
// A single entry by slug — returns null on 404, ready for generateStaticParams.
// const article = await cms.article.get({ slug })
@estokad/next re-exports createClient so you don't install @estokad/sdk separately. The full read reference — collections, singletons, drafts, and cache revalidation — is in Fetching content. For fully-generated types you can also point openapi-typescript at /v1/<workspace>/openapi.json.
Version support. @estokad/next targets Next ^14.2 || ^15 and React ^18.2 || ^19. The data, draft-mode, overlay-route, rich-text, and token surfaces are fully typed and run on all of those. The async visual-edit components (EstokadProvider, <Estokad.*>) run on Next 14 but only typecheck under React 19's types — on a React-18 project, deliver visual edit via the overlay route + injected script instead (the components are only a convenience wrapper around that). See the package README's Compatibility section for the details and the one-line call-site workaround.
That is the full loop. Schema in code → push → publish → fetch.
Where to go next
For deeper schema work, see defineType(). For the editor experience and live preview, see Visual edit. For locking down access, see Auth & RBAC.