Errors
ERROR CATALOGUE.
Every failure carries a stable code, a request_id, a retryable flag, a suggested_action naming the one thing to change, and a doc_url that lands on the section below. Nothing returns bare prose.
Shape
What a failure looks like
{
"type": "https://qubitnotion.com/developers/errors/insufficient_scope",
"title": "Scope missing for this endpoint",
"status": 403,
"code": "insufficient_scope",
"detail": "This endpoint needs the \"plans:read\" scope.",
"request_id": "req_01J...",
"doc_url": "https://qubitnotion.com/developers/errors/insufficient_scope",
"retryable": false,
"suggested_action": "Issue a key that includes "plans:read", or add the scope to this key under API keys.",
"required_scope": "plans:read",
"granted_scopes": ["account:read"]
}Validation failures add errors[], one entry per field with the field name, the rule it broke and what was received.
Codes
Every code we return
401 · not retryable
unauthorized
Authentication required
Why it happens. The request carried no Authorization header, or the header was not a bearer token.
How to fix it. Send `Authorization: Bearer qn_live_…` (or `qn_sandbox_…`) on every call.
401 · not retryable
invalid_key
API key not recognised
Why it happens. The key in the Authorization header does not match any key on record.
How to fix it. Check for a truncated or whitespace-padded value, then issue a fresh key in the workspace under API keys.
401 · not retryable
key_revoked
API key revoked
Why it happens. An administrator revoked this key. Revocation takes effect immediately.
How to fix it. Issue a new key and deploy it. If the revocation was unexpected, check the workspace audit log.
401 · not retryable
key_expired
API key expired
Why it happens. The key passed the expiry date it was created with. The response carries the expiry timestamp.
How to fix it. Rotate the key. Rotation gives you an overlap window so the old secret keeps working until its cutover date.
403 · not retryable
insufficient_scope
Scope missing for this endpoint
Why it happens. The key is valid but was not granted the scope this endpoint requires. The response lists the required and the granted scopes.
How to fix it. Grant the missing scope to the key, or use a key that already has it. Scopes are listed per operation in the reference.
403 · not retryable
ip_not_allowed
Address not on the key's allow-list
Why it happens. This key is restricted to a list of addresses and the call arrived from one that is not on it. The response carries the address we saw.
How to fix it. Add the calling address or its range to the key under API keys, or call from an approved address.
404 · not retryable
not_found
Resource not found
Why it happens. The object does not exist, or it belongs to another workspace, or a sandbox key asked for a live object.
How to fix it. Confirm the id and the environment of the key. Sandbox keys only ever see showroom data.
405 · not retryable
method_not_allowed
Method not allowed
Why it happens. The endpoint exists but does not serve this HTTP method.
How to fix it. Check the method in the reference for this path.
422 · not retryable
invalid_request
Request could not be processed
Why it happens. The payload or the query parameters failed validation. Field-level problems are listed in `errors[]`.
How to fix it. Read `errors[]`: each entry names the field, the rule it broke and the value that was received.
409 · not retryable
idempotency_key_reuse
Idempotency key reused with a different payload
Why it happens. This Idempotency-Key was already used on this key with a different request body or path.
How to fix it. Use a new key for a new payload. Reuse a key only to retry the exact same request.
429 · retryable
rate_limited
Rate limit exceeded
Why it happens. The per-minute burst limit for this key was exhausted. Rejected requests do not consume quota.
How to fix it. Wait the number of seconds in `Retry-After`, then retry. `RateLimit-Policy` declares every window that applies.
429 · retryable
quota_exceeded
Daily quota exhausted
Why it happens. The key spent its daily request allowance. This is a longer window than the per-minute rate limit.
How to fix it. Wait for the window in `Retry-After` to roll, spread the job across the day, or raise the quota on the key.
400 · not retryable
unsupported_version
API version not recognised
Why it happens. The `version` parameter, the `QN-Version` header or the version pinned on the key names a version we do not serve.
How to fix it. Send a dated version we publish, or the aliases `stable` or `next`. GET /v1/versions lists them.
500 · retryable
internal_error
Something went wrong on our side
Why it happens. An unhandled failure inside the API. The response carries a request id.
How to fix it. Retry with backoff. If it persists, send us the `request_id` and we can trace the exact call.