Error codes
Every API failure returns an RFC 9457
application/problem+json body with two stable extensions: a numeric code and
a dotted codeName.
{ "status": 403, "title": "Forbidden by policy", "detail": "Activation is blocked by the entitlement's activation policy.", "code": 2011, "codeName": "license.forbidden_by_policy"}Branch on code or codeName, never on detail or title — those are
human-facing prose and may change; the codes are contract. New codes may be added
over time (an additive, backward-compatible change), so treat unknown codes as a
generic failure of the given HTTP status.
Codes are globally unique and grouped in ranges: general platform errors are 1000–1999, licensing 2000–2999, account/directory 3000–3999, webhooks 4000–4999.
General (1000–1999)
Section titled “General (1000–1999)”Cross-cutting errors any endpoint can return.
| Code | Code name | HTTP | Meaning |
|---|---|---|---|
| 1001 | validation.empty |
400 | A required value was missing or empty. |
| 1002 | validation.duplicate |
409 | The value collides with an existing record. |
| 1003 | validation.failed |
400 | The request failed validation. |
| 1010 | resource.not_found |
404 | The resource doesn’t exist. |
| 1011 | resource.expired |
410 | The resource existed but has expired. |
| 1012 | resource.limit-exceeded |
429 | A plan or capacity limit was reached. |
| 1020 | operation.invalid |
400 | The operation isn’t valid in the current state. |
| 1021 | operation.pending |
409 | A conflicting operation is already in flight. |
| 1030 | auth.forbidden |
403 | The caller lacks the required scope or role. |
| 1040 | service.unavailable |
503 | Temporarily unavailable — retry with backoff. |
| 1041 | service.failure |
500 | Unexpected failure. |
| 1042 | service.too-many-requests |
429 | Rate limit exceeded — honor Retry-After. |
Licensing (2000–2999)
Section titled “Licensing (2000–2999)”Returned by activation, session and usage endpoints.
| Code | Code name | HTTP | Meaning |
|---|---|---|---|
| 2001 | license.no_active_license |
403 | No active license backs this request. |
| 2002 | license.no_such_entitlement |
404 | The entitlement doesn’t exist. |
| 2003 | license.no_active_session |
409 | No active session for this operation. |
| 2004 | license.not_found |
404 | The activation code doesn’t map to anything, or has expired. |
| 2005 | license.invalid_operation |
400 | The operation isn’t valid for this license’s state. |
| 2006 | license.no_permission |
403 | The caller doesn’t own this session or entitlement. |
| 2007 | license.no_such_product |
404 | The product doesn’t exist. |
| 2008 | license.no_such_provider |
404 | The provider doesn’t exist. |
| 2009 | license.validation_error |
400 | The request body or activation code is invalid. |
| 2010 | license.no_credit |
400 | The credit balance can’t cover the requested consumption. |
| 2011 | license.forbidden_by_policy |
403 | Blocked by the entitlement’s activation policy (e.g. identity verification required). |
| 2012 | license.operation_pending |
409 | A pending step (e.g. email verification) must complete first. |
| 2013 | license.expired |
409 | The license or credit balance has expired. |
| 2014 | license.spending_disabled |
403 | The balance holds credits, but its owner has switched extra-credit spending off. Distinct from license.no_credit: nothing needs buying. |
Account & directory (3000–3999)
Section titled “Account & directory (3000–3999)”Returned by user and organization endpoints.
| Code | Code name | HTTP | Meaning |
|---|---|---|---|
| 3001 | organization.not_found |
404 | The user or organization doesn’t exist. |
| 3002 | organization.duplicate |
409 | Already exists (e.g. email in use). |
| 3003 | organization.invalid_operation |
400 | Not valid in the current state. |
| 3004 | organization.no_permission |
403 | The caller lacks directory permission. |
| 3005 | organization.validation_error |
400 | The request failed validation. |
| 3006 | organization.no_credit |
400 | A seat or capacity limit was reached. |
Webhooks (4000–4999)
Section titled “Webhooks (4000–4999)”Returned by the webhook subscription and delivery-management endpoints.
| Code | Code name | HTTP | Meaning |
|---|---|---|---|
| 4001 | subscription.tenant_required |
400 | The request lacks an active environment context. |
| 4002 | subscription.client_id_required |
400 | An OAuth client identity is required. |
| 4003 | subscription.tenant_mismatch |
403 | The subscription belongs to a different environment. |
| 4010 | subscription.not_found |
404 | The subscription doesn’t exist. |
| 4020 | subscription.invalid_state |
409 | Not allowed in the subscription’s current state (e.g. test-fire on an inactive subscription). |
| 4021 | subscription.invalid_transition |
409 | The requested state change isn’t allowed. |
| 4030 | subscription.invalid_secret |
400 | The signing secret doesn’t meet requirements (min. 32 bytes). |
| 4031 | subscription.invalid_overlap |
400 | The rotation overlap window is invalid. |
| 4032 | subscription.invalid_callback_scope |
400 | A requested callback scope isn’t allowed. |
| 4033 | subscription.invalid_url |
400 | The receiver URL is not allowed. |
| 4040 | subscription.challenge_failed |
422 | The endpoint failed the registration challenge. |
| 4050 | subscription.not_licensed |
403 | Webhooks aren’t included in your plan. |
Validation errors
Section titled “Validation errors”Model-binding failures (malformed JSON, wrong types, missing required fields)
return the standard ASP.NET validation problem — a 400 with an errors
dictionary keyed by field name:
{ "status": 400, "title": "One or more validation errors occurred.", "errors": { "activationCode": ["The activationCode field is required."] }}