Dexa APIv0.5.0

Errors

Status codes, the error body, and what to do about each failure.

Error body#

Every failure, at every endpoint, returns the same shape:

json{
  "error": {
    "type": "invalid_request_error",
    "message": "tasks must contain at least one task",
    "param": "tasks",
    "code": "too_few_tasks"
  }
}
Field Always present Notes
type yes Broad category, invalid_request_error style
message yes Human-readable, safe to log
param no Which field was wrong
code no Stable machine-readable code, safe to branch on

Branch on code, log message, show neither to end users.

Status codes#

Status When it happens Retry?
400 Malformed JSON, unknown field, missing context or messages No, fix the request
401 Missing or invalid API key No
403 Key cannot use this model No
422 Well-formed JSON, invalid values No, fix the request
429 Rate limited Yes, after Retry-After
500 Server-side failure Yes, with backoff

Common errors#

400 no input#

json{ "error": { "type": "invalid_request_error", "message": "one of context or messages is required", "code": "missing_input" } }

Every endpoint needs text to work from. Send context for a single blob, or messages when you need roles or content parts.

400 unknown field#

json{ "error": { "type": "invalid_request_error", "message": "Unrecognized property: 'stream'", "param": "stream", "code": "unknown_field" } }

Requests are strict. Unknown fields are rejected rather than ignored, so a typo fails loudly instead of silently doing nothing. The API is also non-streaming, so stream is never valid.

422 bad task name#

json{ "error": { "type": "validation_error", "message": "name must match ^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,63}$", "param": "tasks[1].name", "code": "invalid_task_name" } }

param points at the exact index in tasks that failed.

422 out of range#

json{ "error": { "type": "validation_error", "message": "max_output_tokens must be between 1 and 4096", "param": "max_output_tokens", "code": "out_of_range" } }

temperature is 0 to 2, max_output_tokens is 1 to 4096.

429 rate limited#

json{ "error": { "type": "rate_limit_error", "message": "Rate limit reached", "code": "rate_limit_exceeded" } }

Honour the Retry-After header, fall back to exponential backoff with jitter, and batch more tasks per call rather than retrying in a tight loop.

500 server error#

json{ "error": { "type": "api_error", "message": "Internal server error", "code": "internal_error" } }

Retry with backoff. If it persists, the request id from the response is what support needs.

Handling in the clients#

The generated clients throw on any non-2xx response, with the status code and the parsed error body attached.

tsimport { DexaAiSdkError } from "@dsainvg/dexa-ai-sdk";

try {
  await client.tasks.decideExtract(request);
} catch (error) {
  if (error instanceof DexaAiSdkError) {
    console.error(error.statusCode, error.body?.error?.code);
  }
}
pythonfrom dexa_ai_sdk.core.api_error import ApiError

try:
    client.tasks.decide_extract(request)
except ApiError as error:
    print(error.status_code, error.body["error"]["code"])

Retry only on 429 and 5xx. Everything else needs a change to the request.