# Errors

[RightNow AI](https://www.rightnowai.co/) / [Decision model](https://www.rightnowai.co/docs/decision-model) / [Errors](https://www.rightnowai.co/docs/decision-model/errors)

Updated 2026-11-12

Use `error.code` to identify a refusal and `error.retryable` to decide whether to retry.

[Status](https://status.rightnowai.co/)

## Error body

A request refusal returns an HTTP status and an error envelope. This example shows an unsupported input refusal.

**error.json**

```json
{
  "error": {
    "message": "The document format is not supported.",
    "type": "invalid_request_error",
    "param": "attachments[0].data",
    "code": "document_unsupported",
    "retryable": false
  },
  "request_id": "request-id-from-response"
}
```

- **`error.message`**: A readable description of the refusal.
- **`error.type`**: The error category.
- **`error.param`**: The affected field, or null.
- **`error.code`**: The code your application should handle.
- **`error.retryable`**: A boolean: true permits an automatic retry; false stops automatic retries.
- **`error.details`**: Optional machine-readable context, such as a cause or reset.
- **`request_id`**: The request identifier to include when contacting support.

An HTTP 200 can contain a refusal under an individual question in `answers`. Check the entries as well as the HTTP status.

**Retry or stop: read the flag, then the wait.**

1. **Read the flag**: `x-should-retry` matches `error.retryable`. True permits a retry. False stops it. False includes `504 system_zero_timeout`.
2. **Read the wait**: Wait `Retry-After-Ms`, or `Retry-After` when it is absent. The SDK and the Manual HTTP example stop on a wait over 60 seconds. Maintenance waits 240 to 360 seconds.
3. **Send it again**: Keep the same `Idempotency-Key` and JSON body. If the first try finished, its stored answer can return in place of new work.
4. **Stop at the bound**: The SDK makes at most 5 retries on a 60 second retry budget. The Manual HTTP example resends for 10 minutes.

## Error codes

`400 media_unsupported`: Audio must be WAV (PCM or float) at a 16,000 Hz sample rate. Other audio formats are unsupported.

For a PDF, follow the matching document refusal below. Read [Inputs](https://www.rightnowai.co/docs/decision-model/attachments) for document limits. A priced PDF can still fail its page range, decoded size, encryption, source, signature or structure checks. Malformed data URLs are refused before PDF validation.

**Document refusals**

| Document case | Status and code | Reason | Message and action |
| --- | --- | --- | --- |
| Non-PDF document | `415 document_unsupported` | `pdf_required` | PDF is supported. Export this document to PDF and send the PDF file. Send the exported PDF inline. |
| PDF page range | `403 media_unpriced` | No specific reason | This input type is not supported. Send a PDF within the published physical page range. |
| Decoded PDF size | `413 document_too_large` | No specific reason | The document exceeds the decoded byte limit. Keep the decoded files within the request byte budget. |
| Encrypted PDF | `403 media_unpriced` | `pdf_encrypted` | Encrypted PDFs are not supported. Export an unencrypted PDF and send it again. Send the unencrypted PDF inline. |
| Document upload reference | `400 media_unsupported` | No specific reason | Field: `attachments[i].upload`. The media kind or count is not supported. At most 4 images and 1 audio are allowed. Send PDF data inline; upload references are not available to outside callers today. |
| Invalid PDF signature | `415 document_unsupported` | No specific reason | Field: `attachments[0].data`. The document format is not supported. The declared PDF bytes fail the signature check. Send a valid PDF. |
| Malformed data URL | `400 invalid_request` | No specific reason | The request is invalid. Correct the data URL before sending the inline PDF. |
| Malformed PDF structure | `403 media_unpriced` | No specific reason | This input type is not supported. The signature passed, but the PDF structure is invalid. Export a valid PDF. |

**Error codes**

| Status | Code | Meaning | Retryable |
| --- | --- | --- | --- |
| 400 | `idempotency_key_reuse` | Type: `invalid_request_error`. This idempotency key already settled another request. Use the original body with this key, or use a new key for changed work. | No automatic retry. |
| 400 | `invalid_idempotency_key` | Type: `invalid_request_error`. Use a nonblank `Idempotency-Key` with valid ASCII characters within the accepted length. | No automatic retry. |
| 400 | `invalid_request` | Type: `invalid_request_error`. The request is invalid. Correct the JSON, field names, types or encoding before resending. | No automatic retry. |
| 400 | `invalid_trace_header` | Type: `invalid_request_error`. Correct or remove `X-Client-Request-Id`; its value must be nonblank ASCII within the accepted length. | No automatic retry. |
| 400 | `media_unsupported` | Type: `invalid_request_error`. The media kind or count is not supported. At most 4 images and 1 audio are allowed. An attachment type, format or count is not supported. Held upload references return 400 media\_unsupported at attachments\[i\].upload. Send files inline. | No automatic retry. |
| 400 | `long_state_unsupported` | Held feature. Type: `invalid_request_error`. This input combination is not supported. This input combination is not supported. | No automatic retry. |
| 400 | `webhook_invalid` | Type: `invalid_request_error`. The webhook request is invalid. The URL, events, limit or body is invalid, or `Idempotency-Key` was sent. | No automatic retry. |
| 401 | `invalid_api_key` | Type: `authentication_error`. Authorization is missing, malformed or unknown; a Playground credential is not accepted as a public bearer key. Use a valid API key. | No automatic retry. |
| 402 | `insufficient_credits` | Type: `permission_error`. The workspace's balance does not cover this call. Add funds before starting a new request. Read balance\_cents, required\_cents and add\_funds\_url in error.details. | No automatic retry. |
| 402 | `spend_limit_reached` | Type: `permission_error`. This API key has reached its monthly spending limit. A workspace owner or admin can raise or remove it under Settings, API keys, or wait until resets\_at. This request was not charged. Raise or remove the key's limit, or wait for resets\_at. Read limit\_cents, spent\_cents and resets\_at in error. | No automatic retry. |
| 403 | `account_suspended` | Type: `permission_error`. The account is suspended, blocked or waiting for access. Contact support. | No automatic retry. |
| 403 | `auth_error` | Type: `authentication_error`. The API key is revoked or blocked. Replace the key; this response uses authentication\_error as its type. | No automatic retry. |
| 403 | `https_required` | Type: `invalid_request_error`. This API answers only over HTTPS. Send the request to the https address. Use the HTTPS base URL. | No automatic retry. |
| 403 | `media_unpriced` | Type: `permission_error`. This input type is not supported. The input format has no published price. Use a priced format listed in Inputs. | No automatic retry. |
| 403 | `starter_credit_held` | Type: `permission_error`. Your starting credit is under review. Contact us to request a review. Starting credit is under review. Contact us to request a review. | No automatic retry. |
| 404 | `audio_not_available` | Type: `not_found_error`. Audio is unavailable. Send the request without the audio attachment. This release can refuse an unavailable route or input. Audio combined with images, PDFs or video is unavailable. Run the audio on its own. | No automatic retry. |
| 404 | `committee_not_available` | Held feature. Type: `not_found_error`. This route is not available. Use standard route. | No automatic retry. |
| 404 | `deliberate_not_available` | Held feature. Type: `not_found_error`. This mode is not available. Use standard mode. | No automatic retry. |
| 404 | `document_controls_not_available` | Held feature. Type: `not_found_error`. Documents with control characters are unavailable. Remove the control characters and send it again. Remove control characters from the document and send it again. | No automatic retry. |
| 404 | `document_not_available` | Type: `not_found_error`. Documents are unavailable. Send the request without the document attachment. Send document contents as state text without an attachment. | No automatic retry. |
| 404 | `document_pictures_not_available` | Held feature. Type: `not_found_error`. Pictures inside documents are unavailable. Send the document without pictures, or as text. Send the document without pictures, or send its contents as state text. | No automatic retry. |
| 404 | `image_not_available` | Type: `not_found_error`. Images are unavailable. Send the request without the image attachment. This release can refuse an unavailable route or input. | No automatic retry. |
| 404 | `long_context_not_available` | Type: `not_found_error`. This route is not available. Check the access steps in [Danger zone](https://www.rightnowai.co/docs/decision-model/danger-zone), or send a shorter request. | No automatic retry. |
| 404 | `long_recording_not_available` | Held feature. Type: `not_found_error`. This input type is not supported. Remove the long recording. | No automatic retry. |
| 404 | `model_not_found` | Type: `not_found_error`. The requested model is not offered. Choose the alias or an available pinned version. | No automatic retry. |
| 404 | `unknown_endpoint` | Type: `not_found_error`. The route is unavailable. Check the base URL and path; this response does not mean the API key is invalid. | No automatic retry. |
| 404 | `video_not_available` | Type: `not_found_error`. This input type is not supported. An unavailable video route was refused. Production serves inline H.264 MP4 video as a preview. | No automatic retry. |
| 404 | `decision_not_found` | Type: `not_found_error`. The requested decision is not available. The id is invalid, or no stored decision matches it for this API key. | No automatic retry. |
| 404 | `upload_not_found` | Held feature. Type: `not_found_error`. The requested item is not available to this account. The requested item is not available to this account. | No automatic retry. |
| 404 | `session_not_found` | Held feature. Type: `not_found_error`. The requested resource is not available to this account. The requested resource is not available to this account. | No automatic retry. |
| 404 | `unknown_state` | Held feature. Type: `not_found_error`. The requested state is not available. The requested state is not available. | No automatic retry. |
| 404 | `webhook_not_found` | Type: `not_found_error`. The requested webhook is not available to this workspace. The endpoint is absent or belongs to another workspace. | No automatic retry. |
| 405 | `method_not_allowed` | Type: `invalid_request_error`. Use a method from the Allow response header. | No automatic retry. |
| 409 | `idempotency_conflict` | Type: `invalid_request_error`. The same key and body is still running. Wait and retry with that key. | Yes. Follow the response wait. |
| 409 | `idempotency_replay_unavailable` | Type: `invalid_request_error`. The request completed, but the stored answer is unavailable. details.original\_status records the original status. A new key starts new work; this is not a replay of the old answer. | No automatic retry. |
| 409 | `upload_not_ready` | Held feature. Type: `invalid_request_error`. The requested item is not ready. The requested item is not ready. | No automatic retry. |
| 409 | `upload_in_use` | Held feature. Type: `invalid_request_error`. The requested item is in use by another request. The requested item is in use by another request. | Yes. Follow the response wait. |
| 409 | `stale_parent` | Held feature. Type: `invalid_request_error`. The parent is not the latest state. The parent is not the latest state. | No automatic retry. |
| 409 | `session_busy` | Held feature. Type: `invalid_request_error`. Another request is still using this resource. Another request is still using this resource. | Yes. Follow the response wait. |
| 409 | `session_limit` | Held feature. Type: `invalid_request_error`. This account has reached its concurrency limit. This account has reached its concurrency limit. | No automatic retry. |
| 409 | `op_conflict` | Held feature. Type: `invalid_request_error`. This op\_id was already used with a different append or rewind. Send a new op\_id. This op\_id was already used with a different append or rewind. Send a new op\_id. | No automatic retry. |
| 410 | `session_lost` | Held feature. Type: `invalid_request_error`. The requested resource is no longer available. The requested resource is no longer available. | No automatic retry. |
| 413 | `payload_too_large` | Type: `invalid_request_error`. The request exceeds the body limit. Send fewer or smaller attachments. Reduce the whole request body. | No automatic retry. |
| 413 | `questions_too_large` | Type: `invalid_request_error`. The questions exceed the reply or token limit. Send fewer or shorter questions. Send fewer or shorter questions. | No automatic retry. |
| 413 | `state_too_large` | Type: `invalid_request_error`. The state exceeds the size or nesting limit. Shorten the state or reduce nesting. | No automatic retry. |
| 413 | `media_too_large` | Type: `invalid_request_error`. The media exceeds the decoded byte limit. Media takes the attachments over the decoded size limit. | No automatic retry. |
| 413 | `document_too_large` | Type: `invalid_request_error`. The document exceeds the decoded byte limit. A document takes the attachments over the decoded size limit. | No automatic retry. |
| 413 | `attachment_too_large` | Held feature. Type: `invalid_request_error`. This input exceeds the supported limits. This input exceeds the supported limits. | No automatic retry. |
| 413 | `long_duration_unsupported` | Held feature. Type: `invalid_request_error`. This input exceeds the supported limits. This input exceeds the supported limits. | No automatic retry. |
| 413 | `long_too_many_phrases` | Held feature. Type: `invalid_request_error`. This request exceeds the supported limits. This request exceeds the supported limits. | No automatic retry. |
| 415 | `document_unsupported` | Type: `invalid_request_error`. The document format is not supported. A document's format is not supported, or its bytes do not match it. | No automatic retry. |
| 421 | `wrong_host` | Held feature. Type: `invalid_request_error`. This route is not available for this request. This route is not available for this request. | No automatic retry. |
| 422 | `injection_suspected` | Type: `invalid_request_error`. The request was refused because its content reads as instructions to the model. Remove the embedded instructions and send it again. Remove embedded instructions from the input and send changed input. | No automatic retry. |
| 422 | `input_quarantined` | Type: `invalid_request_error`. This exact input caused repeated serving failures, so it is refused for up to 24 hours. Change the input or contact support. Do not resend the same input in a loop. | No automatic retry. |
| 422 | `invalid_criteria` | Type: `invalid_request_error`. The question criteria are invalid. Use the supported criteria shape and the option and level counts in the model list's limits. | No automatic retry. |
| 422 | `question_too_large` | Type: `invalid_request_error`. The question exceeds the size limit. Shorten the affected question. | No automatic retry. |
| 422 | `request_refused` | Type: `invalid_request_error`. RightNow refused this request. Change it before sending it again. Review the state and question instructions before starting new work. | No automatic retry. |
| 422 | `workspace_quarantined` | Type: `invalid_request_error`. This account's requests are paused for up to an hour after repeated serving failures. Contact support. Stop dispatching work from this workspace while the pause is in effect. | No automatic retry. |
| 422 | `media_decode_failed` | Type: `invalid_request_error`. The media bytes do not match the declared format. Media bytes do not match the declared format. | No automatic retry. |
| 422 | `document_decode_failed` | Type: `invalid_request_error`. The document could not be decoded. A document could not be decoded. | No automatic retry. |
| 422 | `question_not_grounded` | Type: `invalid_request_error`. The question cannot be answered from this state. The question cannot be answered from this state. | No automatic retry. |
| 422 | `upload_invalid` | Held feature. Type: `invalid_request_error`. This input does not match its declared size, type or hash. This input does not match its declared size, type or hash. | No automatic retry. |
| 422 | `long_question_unsupported` | Held feature. Type: `invalid_request_error`. This question cannot be answered for this input. This question cannot be answered for this input. | No automatic retry. |
| 422 | `long_options_unsupported` | Held feature. Type: `invalid_request_error`. These options cannot be evaluated for this input. These options cannot be evaluated for this input. | No automatic retry. |
| 422 | `long_phrase_invalid` | Held feature. Type: `invalid_request_error`. This phrase cannot be evaluated for this input. This phrase cannot be evaluated for this input. | No automatic retry. |
| 422 | `long_question_type_unsupported` | Held feature. Type: `invalid_request_error`. This question type cannot be answered for this input. This question type cannot be answered for this input. | No automatic retry. |
| 422 | `long_media_guard_refused` | Held feature. Type: `invalid_request_error`. This input was refused. This input was refused. | No automatic retry. |
| 422 | `long_no_readable_window` | Held feature. Type: `invalid_request_error`. This input could not be read. This input could not be read. | No automatic retry. |
| 422 | `long_evidence_incomplete` | Held feature. Type: `invalid_request_error`. This input could not be read completely. This input could not be read completely. | No automatic retry. |
| 429 | `capacity_exhausted` | Type: `overloaded_error`. RightNow is at capacity. Retry after the `Retry-After` delay. Wait for `Retry-After`; retry only with bounded client backoff. | Yes. Follow the response wait. |
| 429 | `concurrency_limit_exceeded` | Type: `rate_limit_error`. This account has reached its concurrent call limit. Retry after the `Retry-After` delay. The account already has its allowed work in flight. Follow `Retry-After` and reduce concurrency; details include max\_concurrent. | Yes. Follow the response wait. |
| 429 | `daily_dispatch_limit` | Type: `rate_limit_error`. This account reached today's request limit. It resets at 00:00 UTC. Wait until the UTC reset named by the response. | Yes. Follow the response wait. |
| 429 | `daily_unbilled_limit` | Type: `rate_limit_error`. This workspace reached today's unanswered processing limit. It resets at 00:00 UTC. Wait until the UTC reset named by the response. | Yes. Follow the response wait. |
| 429 | `monthly_cap_reached` | Type: `rate_limit_error`. The workspace reached its monthly decision cap. Follow resets\_at and `Retry-After`; details include monthly\_request\_cap and used. | Yes. Follow the response wait. |
| 429 | `playground_daily_limit` | Type: `rate_limit_error`. The Playground reached its daily limit. Wait for resets\_at; details include daily\_limit. | Yes. Follow the response wait. |
| 429 | `rate_limit_exceeded` | Type: `rate_limit_error`. Too many requests from this key or address. Retry after the `Retry-After` delay. Wait for `Retry-After` and pace requests to the returned limits. | Yes. Follow the response wait. |
| 429 | `workspace_limit_exceeded` | Type: `rate_limit_error`. This workspace is over one of its own allowances, such as calls in flight or bytes being read. Retry after the `Retry-After` delay. Wait for `Retry-After` and reduce the workspace's concurrent work or input load. | Yes. Follow the response wait. |
| 429 | `upload_quota_exhausted` | Held feature. Type: `rate_limit_error`. This account has reached a supported limit. This account has reached a supported limit. | Yes. Follow the response wait. |
| 429 | `sessions_at_capacity` | Held feature. Type: `overloaded_error`. No capacity is available right now. No capacity is available right now. | Yes. Follow the response wait. |
| 429 | `session_hours_exhausted` | Held feature. Type: `rate_limit_error`. This account has exhausted its daily allowance. The account reached its daily session limit. Wait until the next UTC day. | Yes. Follow the response wait. |
| 429 | `starter_spend_limit` | Type: `rate_limit_error`. This request exceeds the starting credit spend allowance. Retry after the `Retry-After` delay or request a review. Follow `Retry-After` or request a review of the starting credit spend limit. | Yes. Follow the response wait. |
| 429 | `starter_rate_limit` | Type: `rate_limit_error`. Starting credit requests reached their rate allowance. Retry after the `Retry-After` delay. Follow `Retry-After` before sending more starting credit requests. | Yes. Follow the response wait. |
| 429 | `starter_concurrency_limit` | Type: `rate_limit_error`. Two starting credit requests are already in progress. Retry after the `Retry-After` delay. Starting credit requests already occupy the available concurrency. Follow `Retry-After`. | Yes. Follow the response wait. |
| 429 | `starter_attempt_limit` | Type: `rate_limit_error`. Starting credit processing reached its temporary allowance. Retry after the `Retry-After` delay. Follow `Retry-After` before processing more starting credit requests. | Yes. Follow the response wait. |
| 429 | `webhook_limit_exceeded` | Type: `rate_limit_error`. This workspace has reached its webhook endpoint limit. The workspace already has 5 endpoints. Delete an endpoint before creating another. | No automatic retry. |
| 500 | `internal_error` | Type: `api_error`. An unexpected failure was caught. Retry after the stated delay; contact support with the request ID if it persists. | Yes. Follow the response wait. |
| 503 | `idempotency_unavailable` | Type: `api_error`. Replay protection cannot answer. Retry with the same `Idempotency-Key` after the wait. | Yes. Follow the response wait. |
| 503 | `limiter_unavailable` | Type: `api_error`. The limiting service cannot answer. Retry after the stated delay. | Yes. Follow the response wait. |
| 503 | `maintenance` | Type: `api_error`. The API is in maintenance. Wait for `Retry-After`. | Yes. Follow the response wait. |
| 503 | `service_unavailable` | Type: `api_error`. RightNow cannot serve this request right now. Retry after the `Retry-After` delay. Wait for `Retry-After`; keep the request ID if the failure persists. An admission store timeout returns 503 service\_unavailable. Wait for `Retry-After` and `Retry-After-Ms` before retrying. | Yes. Follow the response wait. |
| 503 | `system_zero_unavailable` | Type: `api_error`. RightNow is temporarily unavailable. Wait for `Retry-After` and retry when retryable is true. | Yes. Follow the response wait. |
| 503 | `starter_unavailable` | Type: `api_error`. Starting credit enforcement is temporarily unavailable. Retry after the `Retry-After` delay. Starting credit enforcement is temporarily unavailable. Follow `Retry-After`. | Yes. Follow the response wait. |
| 503 | `webhook_unavailable` | Type: `overloaded_error`. Webhook management is temporarily unavailable. Webhook management storage or encryption is unavailable. | Yes. Follow the response wait. |
| 504 | `system_zero_timeout` | Type: `api_error`. RightNow exceeded the response deadline. Shorten the work or inspect the outcome; do not automatically replay unchanged. | No automatic retry. |

Stream refusals, such as `429 stream_limit_exceeded`, are listed under [Streaming errors](https://www.rightnowai.co/docs/decision-model/streaming#errors).

A call without an API key returns `401 invalid_api_key`. Check the key, workspace access, API host and route.

A request over its [cost cap](https://www.rightnowai.co/docs/decision-model/request-policy#cost-cap) returns `400 policy_max_cost_exceeded`. It is not counted or charged, and `error.retryable` is `false`.

## Retries

`x-should-retry` matches `error.retryable`. Stop automatic retries when it is `false`, including `504 system_zero_timeout`.

When a response permits a retry, wait for `Retry-After-Ms` in milliseconds or `Retry-After` in seconds. Prefer `Retry-After-Ms` when both are present.

A `rate_limit_exceeded` refusal with `error.details.cause` set to `replay_bytes` means: Your account has used today's allowance for replayed answers. A request that repeats an `Idempotency-Key` gets its stored answer back, and those replays are limited by total bytes per account per UTC day. Replays resume at the next UTC day; the `Retry-After` headers give the wait.

Gateway 429 and 503 refusals carry `Retry-After` in whole seconds, rounded up, and `Retry-After-Ms` with the exact wait in milliseconds, except webhook\_limit\_exceeded.

Maintenance returns 503 with `Retry-After` and `Retry-After-Ms`. Each answer draws a wait of about 5 minutes (4 to 6), uniformly from 240 to 360 whole seconds.

A key-store outage returns 503 service\_unavailable, which is retryable. Wait for `Retry-After` and `Retry-After-Ms` before retrying.

Keep the decision's `Idempotency-Key` and JSON body. An `idempotency_conflict` means the same work is still running; wait before retrying with that key.

A cold start is a model pool replacing its warm container after a crash, a recycle, a preemption or a deploy, or adding one under a burst. A cold start can outlast a client's retry window; follow the response flags and wait.

See the [first request](https://www.rightnowai.co/docs/decision-model/quickstart).

## Get help

For a refusal that persists, use [Contact](https://www.rightnowai.co/contact) and include the response's `X-Request-Id`.

## Next

[Rate limits](https://www.rightnowai.co/docs/decision-model/rate-limits)
