Errors
HTTP status codes and structured error payloads.
DocAI uses two related conventions. Always inspect both top-level fields and nested detail.
DocAIException envelope
{
"success": false,
"error_code": "INVALID_FILE",
"message": "..."
}Common codes: INVALID_FILE, CORRUPTED_PDF, PASSWORD_PROTECTED_PDF, PAGE_LIMIT_EXCEEDED, OCR_FAILED, EXTRACTION_FAILED, SCHEMA_VALIDATION_FAILED, STORAGE_FAILED, IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_IN_PROGRESS.
Structured detail objects
402: insufficient credits
{
"detail": {
"code": "INSUFFICIENT_CREDITS",
"message": "...",
"required": 3,
"balance": 0.5,
"mode": "Pro",
"pages": 1,
"free_extractions_remaining": 0
}
}Free/trial orgs calling Pro or Ultra get 402 TRIAL_MODE_RESTRICTED (allowed_modes: lite, plus).
429: rate limit
{
"detail": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "...",
"limit": 60,
"retry_after_seconds": 30
}
}422: batch page cap
{
"detail": {
"error_code": "BATCH_PAGE_LIMIT_EXCEEDED",
"message": "...",
"total_pages": 120,
"max_pages": 100
}
}A single PDF over 100 pages is 400 PAGE_LIMIT_EXCEEDED. A password-protected PDF is 400 PASSWORD_PROTECTED_PDF.
401: expired API key
Expired keys are not treated as revoked. The row stays active so you can Rotate it in Settings.
{
"detail": {
"code": "API_KEY_EXPIRED",
"message": "This API key has expired. Rotate it in Settings, then update DOCAI_API_KEY.",
"expires_at": "2026-12-01T00:00:00+00:00",
"settings_url": "https://docai.subgradientlabs.com/settings?section=api-keys"
}
}Do not retry 401. Rotate the key (signed-in JWT only: POST /org/api-keys/{key_id}/rotate), copy the new secret once, and update DOCAI_API_KEY. An API key Bearer cannot rotate (403). See Authentication.
Other statuses
| Status | Typical meaning |
|---|---|
| 401 | Missing/invalid Bearer token, or expired API key (API_KEY_EXPIRED) |
| 403 / 404 | Forbidden or not found (jobs may 404 across orgs; API-key rotate is 403) |
| 409 | Trial already redeemed, or idempotency conflict (IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_IN_PROGRESS) |
| 503 | Upstream extract unavailable (e.g. LlamaExtract not configured) |
Client guidance
- Treat 402 as “buy credits or lower mode”, not a transient network failure.
- Treat 401
API_KEY_EXPIREDas “rotate in Settings”; never retry with the same key. - Treat 429 as retryable with backoff using
retry_after_seconds. - Prompts and custom fields are optional for all modes; cloud modes use a server default prompt when omitted.