
# Error Codes

DocuShell returns structured JSON errors with stable codes and request IDs so integrations can distinguish validation problems, auth failures, rate limits, and transient capacity issues.

Source: https://docs.docushell.com/error-codes
Category: Errors

## Related

- [Getting started](/getting-started.md#error-envelope): See the common error envelope in the queued job flow.
- [Rate limits](/rate-limits.md): Understand `429 rate_limit_exceeded` and retry behavior.
- [Troubleshooting](/troubleshooting.md): Match a failure code to the fix that clears it.

## Error Envelope

Every error on every route uses this shape. `request_id` is also returned in the `x-request-id` header.

```json
{
  "error": {
    "code": "invalid_request",
    "message": "Invalid request body.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

## Common Status Codes

| HTTP | Code | Meaning |
| --- | --- | --- |
| 400 | invalid_request | Malformed JSON, missing required fields, unsupported file type, invalid URL, or rejected PDF. |
| 401 | invalid_api_key | Missing, revoked, expired, or malformed bearer credential. |
| 403 | api_access_disabled / webhook_access_disabled | Credential is valid, but the current plan state does not allow the API lane or requested webhook fields. |
| 402 | insufficient_credits | The account cannot start the requested job because credits or plan access are insufficient. The error includes hard-limit and upgrade details. |
| 404 | not_found | The requested job, batch, file, artifact, or output does not exist for this authenticated caller. |
| 409 | idempotency_key_reused | The same idempotency key was reused with a different payload. |
| 413 | payload_too_large | The request body or uploaded file exceeds the plan or endpoint limit. |
| 429 | rate_limit_exceeded | The caller exceeded the configured request rate. |
| 500 | internal_error | Unexpected gateway or service failure. |
| 503 | backend_unavailable | A downstream processor or queue was temporarily unavailable. |

## Shared Error Responses

These four are returned by every endpoint. Endpoint pages document only their own additional failures.

### 401 invalid_api_key

```json
{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid API key.",
    "type": "auth_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

Returned when the bearer token is missing, revoked, expired, or not allowed to use the API lane.

### 409 idempotency_key_reused

```json
{
  "error": {
    "code": "idempotency_key_reused",
    "message": "This Idempotency-Key was already used with a different request.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

Returned when the same Idempotency-Key is reused with a different payload than the original request.

### 403 webhook_access_disabled

```json
{
  "error": {
    "code": "webhook_access_disabled",
    "message": "Webhooks are available on Pro, Growth, and Scale. Starter includes API access without webhooks.",
    "type": "billing_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

Returned when a Starter API key submits webhook fields. Pro, Growth, and Scale include webhooks.

### 429 rate_limit_exceeded

```json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded.",
    "type": "rate_limit_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}
```

Returned when the API key or caller fingerprint exceeds the configured request rate.

## Recovery Guidance

- Retry `429`, `500`, and `503` failures with backoff; keep the same `Idempotency-Key` only for the exact same submit request.
- Fix `400` failures before retrying. The same invalid file or request shape will be rejected again.
- Resolve `401`, `403`, and `402` in the dashboard before sending more work. DocuShell does not auto-charge overages.
- Log `request_id` from the error body or `x-request-id` header for support and debugging.
