Base URLs
The kurnl API has two separate surfaces:
All partner integration work uses the
/partner base. Examples in this reference use that base unless the page is explicitly marked as internal (/api/v1). (The split is organisational rather than physical: the partner routers are also mounted under /api/v1, so /api/v1/external-checkout/* etc. are live duplicates with identical auth — prefer /partner anyway.)
All endpoints are HTTPS only. The partner API operates on your live account; there is no separate sandbox API key. For safe exploration, use the in-dashboard sandbox.
Authentication
See Authentication for the full guide. Quick reference:Rate limits
Limits are fixed per endpoint:
Requests are bucketed per API key (key prefix) when an
X-API-Key header is
present, otherwise per client IP — callers behind a shared NAT share one IP
bucket. When the limit is exceeded, kurnl returns 429 Too Many Requests.
No X-RateLimit-* headers are emitted — back off and retry with your own timer.
Response format
All responses are JSON. Successful responses vary by endpoint. Error responses always follow this structure:410 Gone responses for expired/cancelled checkout sessions nest
an object inside detail:
expired_at: {"detail": {"detail": "Session cancelled"}}.
Common HTTP status codes
Idempotency
All provisioning endpoints are idempotent by design:POST /external-checkout/complete— the samesession_idreturns the existing subscriptionPOST /external-checkout/anonymous-complete— the sameexternal_subscription_id(or an already-completedsession_id) returns the existing subscription, flaggedidempotent_replay: truePOST /provisioning/provider-initiated,POST /provisioning/bulk, and the explicit-fields (no-session)POST /external-checkout/complete— idempotent per (subscriber email, plan version, location): a retry returns the existing subscription with the message"Subscription already exists (idempotent replay)"or"Provisioning already in progress"(job_idmay be empty on replay)
5xx is therefore safe on all of these paths — kurnl also rolls back partial state automatically on server failures.