kurnl uses two authentication mechanisms. Which one you use depends on the direction of the API call.

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 the X-API-Key header:
API keys are scoped to your provider account. You cannot access another provider’s subscribers or plans with your key.
Never expose your API key in client-side code (browser JavaScript, mobile apps). All calls using X-API-Key must be made from your server.
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 returns 403 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 form krnl_<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).
The legacy single-key endpoints (POST/DELETE /provider/api-key, dashboard-authenticated) are deprecated and keep their old destructive semantics: the legacy generate revokes every existing key and mints one new full-scope key. Migrate scripts to the per-key endpoints (/provider/api-keys); the legacy endpoints are scheduled for removal in the next release.

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.
This secret is also used to sign outbound webhook events kurnl sends to your 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 the session_id and checks your X-Webhook-Secret against 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

Which credential for which endpoint