POST /v1/projects/:id/keys. They are environment-specific:
a key created on localhost only authenticates against http://localhost:3000; a production key only
authenticates against https://api.craftkit.dev.
Credential types
Craftkit has three distinct bearer/secret credential types. They are not interchangeable — each is validated against its own table (or, for the admin key, a direct env-var comparison), and a credential of one type is always rejected wherever another type is expected.
For the account key specifically — creating and managing projects, and minting project keys for
them programmatically — see Account-key auth.
One key, full project access
A project key is full-access within its project. There is no per-key scope, role, or permission column today — every validck_live_ key for a project can do all of the following
for that project, with no per-org provisioning:
Render
POST /v1/templates/:slug/renderRead templates
GET /v1/templates and GET /v1/templates/:slugPoll renders
GET /v1/renders/:idCreate shares
POST /v1/renders/:id/sharesGET /v1/embed/builder/templates (list) and
GET /v1/embed/renders/:id/download (private stream).
For a headless render integration you need exactly one
ck_live_ key, and the template
must live in the project that key belongs to. No admin key, no embed session, no provisioning.401 vs 404
These two are easy to confuse when a render “fails”:- 401
unauthorized— the key is missing, malformed, revoked, or from the wrong environment. - 404
template_not_found— the key authenticated fine, but no template with that slug exists in that key’s project. Usually means the key resolves to a different project than you expect, or the template was never created/published there.
The admin key is separate
CRAFTKIT_ADMIN_KEY is a single global environment secret that gates only the multi-tenant
provisioning endpoints (POST/PATCH /v1/admin/provision). It is compared directly against the
env value and never consults the API-key table — so a ck_live_ key sent to /v1/admin/provision
returns 401. You do not need the admin key for headless rendering.
Key scope
Today a project key is all-or-nothing within its project, which means the key you embed in a backend service can also create and publish templates. There is no render-only or read-only scoped key yet (roadmap). Until then:- Mint a dedicated key per integration (rendering, embed, inbound webhooks each separate) so you can revoke one without disrupting the others.
- Store keys in environment variables, never in client code or logs.
Key management
Project keys can be minted from the dashboard (Project → API keys) or programmatically withPOST /v1/projects/:id/keys, using the project’s account key.
There is no rotation endpoint — rotate by minting a new key, deploying, verifying traffic, then
revoking the old one.
Account keys (ck_acct_…) are dashboard-only (Account → API keys) — there is no endpoint
that issues one, by design, so provisioning your account’s own top-level credential always requires
a human in the dashboard once.
Revocation is immediate with no grace period for both credential types — a revoked key stops
authenticating on its very next use.