---
title: "Errors and debugging"
description: "Handle QuiverAI API errors, correlate request IDs, inspect Logs, and escalate persistent failures."
icon: "circle-alert"
---

QuiverAI API failures use standard HTTP statuses and a machine-readable JSON envelope:

```json
{
  "status": 429,
  "code": "rate_limit_exceeded",
  "message": "Rate limit exceeded",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

Branch on `status` and `code`, not on the human-readable `message`.

## Status and code guide

| Status         | Common codes                                                                                                                              | What to do                                                                                                                               |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `400`          | `invalid_request`                                                                                                                         | Correct missing, malformed, or incompatible parameters. Do not retry the same body unchanged.                                            |
| `401`          | `invalid_api_key`, `unauthorized`                                                                                                         | Check the Bearer header, secret, key status, environment, project, and key authority.                                                    |
| `402`          | `insufficient_credits`, `funding_pending`, `funding_payment_method_required`, `funding_payment_action_required`, `funding_payment_failed` | Resolve funding in [API Platform Billing](https://platform.quiver.ai/billing), then retry when the balance or payment action is settled. |
| `403`          | `unauthorized`, `account_frozen`, `content_policy_violation`, `invalid_request`                                                           | Check the key's allowed operations and models, then resolve any account, content-policy, or endpoint-specific restriction.               |
| `404`          | `model_not_found` or `invalid_request`                                                                                                    | Refresh `GET /v1/models` for model availability and verify the endpoint path.                                                            |
| `408` or `504` | `request_timeout`                                                                                                                         | Treat the outcome as potentially uncertain. Before retrying, assess duplicate-work risk; Responses has no documented idempotency key.    |
| `413`          | `payload_too_large`                                                                                                                       | Reduce the upload or request payload before retrying.                                                                                    |
| `429`          | `rate_limit_exceeded`, `operation_rate_limit_exceeded`, `weekly_limit_exceeded`                                                           | Respect `Retry-After` when present, add backoff and jitter, and review [Limits](https://platform.quiver.ai/limits).                      |
| `500`          | `server_error`                                                                                                                            | Before retrying, assess duplicate-work risk; Responses has no documented idempotency key. Escalate persistent failures.                  |
| `502`          | `model_error`                                                                                                                             | Before retrying, assess duplicate-work risk; Responses has no documented idempotency key. Escalate persistent failures.                  |
| `503`          | `model_unavailable`                                                                                                                       | Before retrying, assess duplicate-work risk; Responses has no documented idempotency key. Escalate persistent failures.                  |

## Correlate a request

Every response includes `X-Request-ID`. On an error response, it matches the envelope's
`request_id`. Record this value with the endpoint, model, status, code, and UTC timestamp.

You can also send an optional `x-trace-id` from your application. The API echoes it in
`X-Trace-ID`, letting you join QuiverAI request records with caller telemetry.

When request metadata is available under your data policy, use
[Logs](https://platform.quiver.ai/logs) to inspect the request outcome. Logs can help correlate a
request with its project, API key, endpoint, model, status, charge state, and public error code;
they do not capture prompts, request or response bodies, uploads, or generated artifacts.

## Interpret a rate-limit response

A `429` means an independently enforced capacity rejected the request. Use the canonical
[response-header definitions](/api-reference/introduction#response-headers) to interpret the
reported scope, subject, dimension, remaining capacity, reset time, and optional `Retry-After`.

A key that does not authorize the requested operation or model can reject with `403 unauthorized`.
Check its allowed operations and models in [API Keys](https://platform.quiver.ai/api-keys);
changing capacity settings does not grant a key additional authority.

Honor `Retry-After` when it is present. When no retry timing is supplied and the reported capacity
is zero, the relevant limit must change before the request can succeed.

## Unsupported Responses options

The Responses endpoint is stateless. `store: true` and a non-null `previous_response_id` return
`400 invalid_request` before model execution, regardless of organization policy. Omit `store` or
send `false`; omit `previous_response_id` or send `null`. Continue by replaying the full input
history, not by retrieving a stored response. Changing data policy will not enable these features.

Remove unsupported fields such as `background`, `include`, and `websocket` before retrying. See
[Current limitations](/developers/guides/migrate-to-responses#current-limitations). Caller-tool
storage is your application's responsibility and is distinct from QuiverAI's metadata and
inference-retention policies in [Data controls](/developers/platform/data-controls).

## Streaming failures

Handle each failure boundary separately:

- **HTTP setup failure:** A non-`200` response before SSE begins uses the JSON error envelope.
- **Terminal SSE failure:** For `/v1/responses`, handle `response.failed`, `response.incomplete`,
  and `event: error`. Collect complete `function_call` or `custom_tool_call` items before handling
  them; partial arguments are not executable calls. A completed call can be followed by more
  refinement turns, so do not publish staged content until the tool loop finishes successfully.
- **Early EOF:** If the connection closes before a recognized terminal event, treat the outcome as
  uncertain and retain the request id for investigation.
- **Client cancellation or timeout:** Stopping the client does not prove server-side work stopped.
  Assess duplicate-work risk before submitting another Responses request because the endpoint has
  no documented idempotency key.
- Native SVG streams emit preview events before the final `content` event. Do not persist a preview.
- `data: [DONE]` ends the transport. Evaluate the terminal event that preceded it to determine the
  request outcome.

## Test error handling

Test keys use the production base URL and published response shapes without model calls or charges.
Use the sandbox's deterministic outcomes and supported failure markers to exercise client handling.
The sandbox does not implement `/v1/responses`; see
[Sandbox and test keys](/developers/guides/sandbox-and-test-keys).

## Escalate a persistent failure

Provide support with:

- the `X-Request-ID` or error `request_id`;
- UTC timestamp, endpoint, model, HTTP status, and machine-readable code;
- a minimal reproduction and sanitized request shape;
- whether the request was streaming and which terminal event arrived.

Never send an API key or other secret. Include prompts, source assets, or generated output only when
they are necessary to reproduce the issue and your data-sharing policy permits it.
