Errors
The status code says which class, the body says what exactly; errors expose five common headers plus a scope header for rate limits, so retry logic never has to read the body.
When something fails, the HTTP status code tells you the class of the failure; the body gives the specific cause in the format of that prefix; and every error response also carries four x-praxis-problem-* headers plus one x-praxis-recovery-action, so retry logic only needs the headers, whatever the body looks like.
Status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Invalid request fields or format | Correct the parameters; do not retry unchanged |
401 | Missing or invalid credentials | Check your API key |
402 | Insufficient balance or paid allowance | Add funds or contact your account administrator |
403 | Access denied | Check key permissions and resource ownership; contact support if needed |
404 | Resource, model or route not found | Check the ID, model name and path |
408 | Request timed out | Check connectivity before retrying; verify whether writes completed first |
409 | Resource state or concurrent update conflict | Read the current state and adjust the request |
413 | Payload or file too large | Reduce the payload or use a URL input supported by the endpoint |
422 | Request content cannot be processed | Correct parameters or input using the error details |
429 | Rate, concurrency or model quota exceeded | Honor retry-after; let in-flight requests finish when concurrency is full |
500 | Internal platform error | Retry later; contact support with X-Request-Id if it persists |
501 | Capability not implemented | Use a supported endpoint; do not retry |
502 | Upstream call failed or returned an invalid response | Back off and retry; switch models or contact support if it persists |
503 | Service or eligible route temporarily unavailable | Back off and retry, or select another model |
504 | Upstream response timed out | Back off and retry; check write results first to avoid duplicate creation |
Error codes
These are common machine-readable codes, not an exhaustive enum for every endpoint. Compatible error bodies may use protocol-specific code/type values. For cross-protocol handling, read x-praxis-problem-code, which can differ from the body code. Codes are case-sensitive.
| code | When it occurs and what to do |
|---|---|
AUTHENTICATION_ERROR | The key is missing or invalid; check or replace your credentials. |
VALIDATION_ERROR | A parameter violates a format, type or range requirement; correct it using the details. |
INPUT_NOT_REPRESENTABLE | The selected model or protocol cannot represent an input option; remove the option or switch models. |
NOT_FOUND | The resource is absent or not visible to this account; check the ID and account. |
MODEL_NOT_FOUND | The model is absent or not visible; select an available name from the model list. |
MODEL_PROTOCOL_NOT_OFFERED | The model does not offer this protocol; use a supported endpoint or another model. |
MODEL_PROTOCOL_LINE_UNAVAILABLE | Qualified routes for the protocol are unavailable; back off and retry or switch models. |
GENERATION_NOT_FOUND | The generation is absent or belongs to another account; check the generation ID from the response headers and the key. |
RATE_LIMITED | A rate or concurrency limit was exceeded; honor retry-after and reduce rate or concurrency. |
UPSTREAM_ERROR | The upstream call failed or returned an invalid response; retry with backoff when retryable, then switch models or contact support if it persists. |
PROVIDER_SELECTION_NOT_ALLOWED | Provider order/only was supplied without BYOK; remove provider selection or provide your own upstream key. |
not_implemented | The endpoint or capability is not implemented; use a supported capability instead of retrying. |
model_protocol_not_offered | HTTP 404: the model does not declare the requested protocol. Check supported_apis in GET /model/v1/models and use the corresponding endpoint. For Google models, use /google/v1beta/models/{model}:generateContent with a Google request body; changing only the prefix is insufficient. |
provider_unavailable | HTTP 502: all available routes for this request failed. Retry with backoff; if failures persist, switch models and contact support with X-Request-Id. |
thinking_disable_unsupported | HTTP 400: thinking cannot be disabled, for example reasoning_effort="none" on glm-5.3. Omit the disabling setting or choose a supported effort level; switch models if you need thinking disabled. |
insufficient_quota / INSUFFICIENT_BALANCE | HTTP 402: insufficient balance; body or header codes vary by endpoint. Add funds or contact your account administrator before retrying; avoid immediate retry loops. |
validation_error (response_format) | HTTP 400, for example: Model "deepseek-flash" does not support json_schema on this API. Switch to a model supporting json_schema on this endpoint. If valid JSON alone is sufficient, use json_object; it does not enforce a schema. |
validation_error (named parameter) | HTTP 400: with provider.require_parameters=true, the model may reject a requested parameter. For example, param: "logprobs" accompanies does not support the requested logprobs value. Adjust the named parameter or switch models. Disabling the check does not prove the parameter takes effect. |
Error body
The body format follows the first segment of the address, same as success responses — your SDK needs no special handling for errors.
Vendor prefixes (/openai /anthropic /google /e2b /tavily): identical to that vendor's official API error body.
// /openai
{ "error": { "code": 401, "message": "Invalid API key." } }// /anthropic
{ "type": "error", "error": { "type": "authentication_error", "message": "Invalid API key." } }Praxis prefixes (/agent /model /sandbox /search /meta): standard Problem Details (RFC 9457), Content-Type: application/problem+json.
{
"type": "https://deepraxis.ai/problems/authentication_error",
"title": "authentication_error",
"status": 401,
"detail": "Invalid API key.",
"instance": "problem_eqfnxu",
"code": "AUTHENTICATION_ERROR",
"retryable": false
}| Field | Meaning |
|---|---|
type | URL of the error type, stable, safe to branch on |
title / detail | Human-readable summary and specific cause |
status | Same as the HTTP status code |
instance | ID of this error, attach it when contacting support |
code | Machine-readable error code |
retryable | Whether retrying verbatim might succeed |
Error headers (five common + one rate-limit header)
The five common headers are independent of body format; the sixth, scope, applies to rate-limit errors:
| Header | Meaning | Example |
|---|---|---|
x-praxis-problem-code | Cross-protocol classification; may differ from the body's code | AUTHENTICATION_ERROR |
x-praxis-problem-kind | Broad class — what broke | authentication_failure |
x-praxis-problem-origin | Who owns it — who can fix it: user (your request or credential), platform (us), upstream_provider (the vendor), etc. | unknown |
x-praxis-problem-retryable | Whether retrying verbatim might succeed | false |
x-praxis-problem-scope | Rate-limit layer, when applicable: platform or model | platform |
x-praxis-recovery-action | Suggested action | relogin |
Retrying
retryableistrue(or status429502503): retry with exponential backoff; for429honorretry-afterfirst.- Everything else: never retry verbatim — fix the request or the Key first.
Authentication
One header, shared by every endpoint.
Rate limits
Rate limiting has two layers: the platform layer caps per-second requests and concurrency per Key, and the model layer caps per-minute requests and tokens per model. Every response carries three headers telling you exactly what you have left.