Every 4xx / 5xx response from the Prism IO™ API returns the same envelope. SDKs can model error handling once instead of per-endpoint.
{
"error": {
"code": "string", // stable machine identifier
"message": "string", // human-readable, safe to display
"param": "string|null", // request input that caused the error
"type": "string" // category (closed set, see below)
}
}
| Type | HTTP status range | Typical cause |
|---|---|---|
invalid_request_error | 400, 422 | Request payload failed validation; param field
points at the input |
authentication_error | 401 | JWT missing, expired, revoked, or invalid |
permission_error | 403 | Authenticated but lacks permission for the action |
not_found_error | 404 | Resource does not exist (or is hidden from this user) |
rate_limit_error | 429 | Per-IP or per-user rate limit exceeded; check
Retry-After header |
governance_error | 400, 422 | Action would violate Prism IO™ governance constraints (e.g., brand-voice drift threshold exceeded) |
server_error | 500, 502, 503, 504 | Unexpected condition; logged with full context server-side; retry-safe |
| Code | Type | Meaning |
|---|---|---|
validation_error | invalid_request_error | One or more request fields failed pydantic validation;
param points at the first failing field |
invalid_credentials | authentication_error | Email + password did not match any active account |
subscription_inactive | authentication_error | Account found but subscription is not active; uniform with
invalid_credentials to avoid leaking which emails
exist |
token_expired | authentication_error | JWT exp claim is in the past; refresh via the refresh-cookie flow |
token_revoked | authentication_error | JWT predates a token-version rotation (password reset, explicit revoke); user must sign in again |
missing_refresh_token | authentication_error | POST /api/auth/refresh-token called without
the httpOnly prismio_refresh cookie |
invalid_handoff_token | authentication_error | HMAC-signed handoff token failed signature verification |
rate_limit_exceeded | rate_limit_error | IP or user-keyed limit hit; respect Retry-After |
not_found | not_found_error | Endpoint or resource does not exist at this path |
tier_limit_exceeded | invalid_request_error | Calling user's tier does not allow this action;
/api/v1/capabilities describes per-tier limits |
server_error | server_error | Unexpected condition; retry once with backoff before reporting |
The canonical code list lives in the Prism IO™ codebase at
app/core/errors.py. Codes are stable across releases
(once shipped they do not change shape); new codes are additive.