API basics
Errors
Errors are JSON with a detail field; some also carry a machine-readable code.
Error shapes
| Shape | Returned for |
|---|---|
{"detail": "<message>"} | Most errors |
{"detail": {"code": "<CODE>", "message": "<message>", …}} | Named errors raised inside a feature, listed in Named codes; message can be absent |
{"detail": "<message>", "code": "<CODE>", …} | 429, 428, app errors, and 402 QUOTA_EXCEEDED / FEATURE_NOT_AVAILABLE, with extra fields at the top level. 402 PAYMENT_FAILED uses the nested shape |
{"detail": [{"type", "loc", "msg", "input", …}]} | 422 request validation |
Examples, recorded from the API:
{"detail": "User not found"}{"detail": {"code": "USER_IN_OTHER_ORGANIZATION"}}{
"detail": [
{
"type": "value_error",
"loc": ["body", "email"],
"msg": "value is not a valid email address: An email address must have an @-sign.",
"input": "not-an-email",
"ctx": {"reason": "An email address must have an @-sign."}
}
]
}Status codes
| Status | Meaning |
|---|---|
400 | The request is not valid in its current state, for example Missing X-Space-Slug header or This invite has expired |
401 | No valid credential: Valid API key or Bearer token required |
402 | A plan limit or a payment problem: QUOTA_EXCEEDED, FEATURE_NOT_AVAILABLE, PAYMENT_FAILED |
403 | The credential is valid but not allowed here: wrong workspace for the key, no membership, or a missing permission |
404 | The resource does not exist or is not visible to the caller |
409 | A conflict with the current state, such as an existing member or a named code below |
422 | The body or parameters failed validation, or a referenced item is unusable |
428 | A connection needs the caller to sign in to it first: PER_USER_AUTH_REQUIRED |
429 | Too many requests: REQUEST_RATE_LIMITED; see Rate limits |
502 | An upstream service failed; nothing was changed or charged |
Errors with top-level fields
| Status | code | Extra fields |
|---|---|---|
429 | REQUEST_RATE_LIMITED | limit_name, limit, window_secs, retry_after; headers Retry-After, RateLimit, RateLimit-Policy |
402 | QUOTA_EXCEEDED or FEATURE_NOT_AVAILABLE | quota_type, metric, limit and used (strings) |
428 | PER_USER_AUTH_REQUIRED | reason, connector_key, connection_id |
401 | APP_VIEWER_IDENTITY_REQUIRED | app_id |
403 | CONNECTION_NOT_DECLARED | app_id, connection_id, kind (the app did not declare that connection) |
403 | NO_ACCESS | connection_id, reason (the viewer cannot use that connection) |
Named codes
code | Status | Meaning |
|---|---|---|
MODEL_NOT_ALLOWED | 403 | The model is not available on your plan |
MODEL_NOT_AVAILABLE_IN_WORKSPACE | 403 | The model is not enabled in this workspace |
SANDBOX_BUSY | 409 | The chat or app is still working on an earlier message; carries run_id |
MODEL_PRICE_MISSING | 422 | A model cannot be enabled without a price (platform admins) |
TEMPLATE_NOT_AVAILABLE | 422 | The selected ontology template is unavailable |
USER_IN_OTHER_ORGANIZATION | 409 | An organization plan cannot be bought: your home organization is one you are not an admin of |
LAST_ORGANIZATION_ADMIN | 409 | An organization must keep at least one admin |
HOME_SWITCH_REQUIRED | 409 | Accepting a home invite would replace your home organization, named in organization_name; repeat with switch_home: true |
HOME_ORGANIZATION_CONTAINED | 409 | Your home organization, named in organization_name, does not let its members join other organizations |
EXTERNAL_MEMBER | 409 | An external member cannot get a seat or plan; only their home organization gives one |
OUTSIDE_ORGANIZATION | 409 | The person's home organization does not let its members join workspaces outside it |
ORGANIZATION_ROLE_EXISTS | 409 | An organization role with this name already exists, or the name is admin or member |
BUILT_IN_ORGANIZATION_ROLE | 409 | The admin and member organization roles cannot be deleted |
ORGANIZATION_ROLE_IN_USE | 409 | The organization role is the default for new members, or a member or pending invite holds it |
SEAT_REQUIRED_FOR_PERSONAL_PAYER | 409 | The user pays for a personal plan; add them with a seat |
PERSONAL_SUBSCRIPTION_ACTIVE | 409 | Cancel the personal plan before joining an organization |
PLAN_SWITCH_REQUIRED | 409 | Joining ends the personal plan; repeat with replace_personal_plan: true |
PLAN_SWITCH_FAILED | 502 | The personal plan could not be ended; nothing was charged |
STRIPE_MANAGED | 409 | The plan is billed through Stripe; change it there |
USER_DISABLED | 409 | A disabled user cannot be given a plan or a seat |
ORGANIZATION_ENDING | 409 | The organization's plan is ending; seats cannot be assigned |
IN_ORGANIZATION | 409 | The user's organization handles their plan |
ACTIVE_SUBSCRIPTION | 409 | The plan changed meanwhile; reload and try again |
ALREADY_ON_PLAN | 409 | The user is already on this plan |
PAYMENT_FAILED | 402 | The payment provider refused the payment |
COMPANY_DETAILS_REQUIRED | 422 | A business plan needs the company email, address and VAT ID |
INVALID_TAX_ID | 422 | The VAT ID was rejected |
INVALID_ADDRESS | 422 | The address cannot be used for billing |
CHECKOUT_FAILED | 502 | Checkout could not be opened; nothing was charged |
PLAN_UPDATE_FAILED | 502 | The plan could not be updated |
Treat any other code as its status code says; new codes can be added.