Skip to main content

Standard error object

Permissio uses a single flat error envelope on every error response.

{
"error": "Human readable message",
"code": "technical_error_code",
"request_id": "uuid-v4",
"details": { "optional": "context" }
}

Code enum

Branch on code for control flow. The full set of values you may receive on a /v1/* partner endpoint is:

codeTypical statusMeaning
validation_error400Request body or query parameters failed validation.
not_found404The referenced resource does not exist or is not visible to your account.
unauthorized401Generic authentication failure that does not match a more specific code.
missing_api_key401The Authorization header was absent.
invalid_api_key401The key was malformed, expired, revoked, or of the wrong type.
api_key_env_mismatch401The key's sk_test_/sk_live_ prefix does not match the environment the key was issued for. Rotate to a key for the correct environment.
ip_not_allowed403The caller IP is not on this account's IP allowlist.
missing_scope403The key does not carry the scope required for this operation.
forbidden403Generic authorization failure that does not match a more specific code.
rate_limited429The account or key has exceeded its rate budget.
internal_error5xxUnexpected server error. Safe to retry with backoff.
idempotency_conflict409The same Idempotency-Key was reused with a different request body.
idempotency_in_progress425The same Idempotency-Key is currently being processed. Retry after a short delay.
allowlist_check_failed403A configured allowlist (recipient domain, callback URL, etc.) rejected the request.

The details object, when present, carries structured context such as the failing field name on a validation_error. Treat its shape as best-effort and fall back to error for display.