# Errors and recovery

This reference describes the selected contract. It does not imply that an API endpoint is open or tested. Preserve `requestId` when reporting a problem; never send a key or raw private input.

## Request errors

| HTTP | Code or condition | Recovery |
| --- | --- | --- |
| 400 | `invalid_input` | Correct the reported field or conflicting authentication headers before submitting. |
| 401 | `unauthorized` | Check that the credential is present and valid; do not keep retrying an invalid key. |
| 403 | `forbidden` | Use an identity with the required scope; a read-only key cannot start work. |
| 402 | `insufficient_credits` | Resolve insufficient USD balance. The legacy code name does not introduce a credit currency. |
| 402 | `budget_exceeded` | Reduce the authorized task scope or deliberately adjust the applicable spending limit. |
| 404 | `not_found` | Check the target and access boundary. Missing, non-public or withheld data is not a verified negative answer. |
| 409 | `capability_changed` or a key/input conflict | Review current capability information or recover the original submission. Do not silently accept changed input. |
| 410 | `result_expired` | The stored snapshot is no longer available; a new collection needs separate authorization and budget. |
| 410 | `idempotency_key_expired` | Reconcile the original task before deciding to authorize new work. |
| 410 | `product_retired` | Review `details.replacement` when supplied; do not assume the replacement has an identical contract. |
| 422 | `unsupported_source` or `unsupported_filter` | Select a supported scope; do not silently drop a requested filter. |
| 422 | `unbounded_cost` | Supply the required bound, such as `maxMediaMinutes`, before execution. |
| 422 | `media_too_long` | Reduce the requested media scope to the supported limit. |
| 429 | `rate_limited` | Read the scope and `Retry-After` hint. Back off rather than retrying in a tight loop. |
| 502 | `source_blocked` | Treat the source as unavailable for this attempt; repeated identical calls are not a recovery strategy. |
| 503 | `source_unavailable` | Check capability status and retry only under a bounded policy. |
| 504 | `timeout` | Establish the original task's state before creating new work. |
| 500 | `internal` | Keep the request identifier for support and reconcile acceptance before retrying. |

The listed error responses do not add a business charge. Source failures and timeouts can consume the internal unbilled-execution allowance; an internal service error does not consume the customer's allowance. An error while looking up an existing task does not undo that task's earlier settlement.

## A successful empty answer is different

A source that normally responds and confirms a negative answer can produce `200` and `status: succeeded`. Its data must identify what was checked, for example an explicit `found: false`. Request-based billing may charge for that answer only where the operation contract permits it. Result-based zero-record delivery is free.

`status: partial` is also distinct from a request error. It requires the caller's authorization for partial delivery and must identify gaps. See [billing](/docs/billing/) and [response outcomes](/docs/responses/).

## Recover without duplicate work

1. Determine whether submission failed before acceptance or whether only the response was lost.
2. If you have a task handle, inspect that task first.
3. Retry an unchanged submission with its original `Idempotency-Key`, subject to current permissions and key validity.
4. For changed input or an expired key, explicitly decide whether to authorize a new task and its budget.

For example, losing the response to a submission is not evidence that it never ran. Replacing the key and submitting again can create duplicate work. A successful task lookup must still inspect the task's status rather than treating HTTP 200 as collection success.
