API Key — your calls to kurnl
Use your API key when you are calling kurnl’s API directly (plan queries, address serviceability checks, provider-initiated and bulk provisioning, billing reports). Send it in theX-API-Key header:
The
api_access feature gate: a valid key still gets
403 "API access is not enabled for this account" when the provider’s
api_access feature flag is off. This is the first thing to check on an
unexplained 403.Scopes
Every API key carries a set of scopes chosen when the key is created on the dashboard API Keys page. A call outside the key’s scopes returns403 with "API key is missing the required scope '<scope>'".
Write implies read: a key holding
provisioning:write also passes
provisioning:read checks. Grant each integration only what it needs — a
webshop key doesn’t need provisioning:write; a finance export needs only
billing:read.
The external-checkout endpoints are not API-key-authenticated (they use
the webhook secret, below) and therefore have no scope.
Keys created before scopes existed were migrated with all scopes — their
behavior is unchanged.
Key format
Your API key is a production credential of the formkrnl_<hex>. There is no separate sandbox key — the partner API operates on your live account. For safe, no-impact exploration use the in-dashboard sandbox instead.
Multiple keys & rotation
Each provider can hold up to 10 active keys at once, each with its own label, scopes, creator, and last-used timestamp (visible on the dashboard API Keys page — “last used” is accurate to about 5 minutes). Rotate gracefully: create a new key, switch your integration to it at your own pace, then revoke the old key. Revocation takes effect immediately on the worker that serves the request, and within about 5 minutes on all other workers (per-process credential cache).Rate limits
Exceeding a limit returns
429. No X-RateLimit-* headers are sent — pace
your requests client-side.
Webhook Secret — kurnl’s calls to you (CKO-03)
The webhook secret is used for CKO-03 external checkout callbacks. When your checkout system calls kurnl’s/external-checkout/complete endpoint, kurnl looks up the secret for your service_provider_document_id and verifies the X-Webhook-Secret header before processing anything.
webhook_url. See Webhooks for signature verification.
Two behaviours worth knowing:
- No secret configured → 401, not open access. Every webhook-secret endpoint rejects all calls until a secret is set on the Checkout page.
- On session-based calls the provider comes from the session. For
/complete, session read/PATCH, and session-based/subscription-status, kurnl resolves the provider from thesession_idand checks yourX-Webhook-Secretagainst that provider’s secret.
The webhook secret is a symmetric pre-shared value — it is never hashed or encrypted at rest on kurnl’s side. Treat it like a password: at least 32 random characters, rotated if compromised.
Keeping credentials safe
- Store both the API key and webhook secret as environment variables, never in source code
- Treat the API key as a production credential — the partner API has no sandbox mode
- Restrict server access to the IP ranges of your checkout and back-office servers where possible
- If a credential is compromised, rotate it immediately from the dashboard and audit recent API activity in your logs