Base URL
| Environment | Base URL |
|---|---|
| Production | https://api.kurnl.ca/api/v1 |
| Sandbox | https://api.kurnl.ca/api/v1 (same host, different credentials) |
Authentication
See Authentication for the full guide. Quick reference:| Header | Used for |
|---|---|
X-API-Key: krnl_live_... | Subscriber management, plan queries, bulk provisioning, reports |
X-Webhook-Secret: ... | CKO-03 external checkout callbacks |
Rate limits
| Limit | Value |
|---|---|
| External checkout endpoints | 120 requests / minute per IP |
| All other authenticated endpoints | 300 requests / minute per API key |
429 Too Many Requests. Retry after the X-RateLimit-Reset timestamp.
Response format
All responses are JSON. Successful responses vary by endpoint. Error responses always follow this structure:Common HTTP status codes
| Status | Meaning |
|---|---|
200 | Success |
201 | Created |
202 | Accepted (async operation queued) |
204 | No content (e.g. successful delete) |
400 | Bad request — invalid input |
401 | Unauthorized — missing or invalid credentials |
403 | Forbidden — valid credentials but insufficient permissions |
404 | Not found |
409 | Conflict — e.g. duplicate subscription for a unit |
422 | Unprocessable entity — validation failure |
429 | Rate limit exceeded |
500 | Server error — safe to retry |
Idempotency
Several endpoints are idempotent by design:POST /external-checkout/complete— sameemail + plan_version_idreturns the existing subscriptionPOST /provisioning/bulk— resubmitting the same subscriber email returns the existing subscriptionPOST /provisioning/provider-initiated— same as above
Pagination
List endpoints support cursor-based pagination:total, page, page_size, and has_more fields alongside the results array.