> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitsearch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Handle v3 API errors

> Handle validation, authentication, idempotency, rate-limit, and asynchronous result failures safely.

HTTP errors use a stable envelope:

```json theme={"dark"}
{
  "status": "failed",
  "error": {
    "code": "developer_v3_search_input_required",
    "message": "Search requires query, intent, or at least one identity signal"
  }
}
```

## HTTP policy

| Status         | Meaning                                                      | Client action                                                                          |
| -------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| `400`          | Invalid field, value, ID, or request shape                   | Fix the request. Do not retry it unchanged.                                            |
| `401`          | Missing API key                                              | Add a bearer token.                                                                    |
| `403`          | Invalid key, missing scope, or invalid key context           | Fix the key or scopes. Do not retry in a loop.                                         |
| `404`          | Search, Enrich request, or authorized profile read not found | Verify the ID, API key, and environment.                                               |
| `409`          | An `Idempotency-Key` was reused for different work           | Reuse the original body, or use a new key for genuinely new work.                      |
| `429`          | API-key rate limit exceeded                                  | Honor `Retry-After`, then retry with backoff and jitter.                               |
| `500` or `503` | Temporary server or dependency failure                       | Retry with backoff. If you supplied an `Idempotency-Key`, reuse it with the same body. |

Common authentication codes are `missing_api_key`, `invalid_api_key`, and `missing_api_key_scope`. Validation codes begin with `developer_v3_search_` or `developer_v3_enrich_` and identify the affected contract.

## Async failures

An accepted request can later finish with a failed result. These failures appear inside the resource rather than as an HTTP error:

```json theme={"dark"}
{
  "profile_id": "profile_456",
  "status": "failed",
  "generation_level": 1,
  "failure": {
    "code": "profile_enrichment_failed",
    "message": "The profile could not be enriched",
    "retryable": true
  }
}
```

For Search, `completed_with_errors` is a terminal aggregate with usable results. Keep every `ready` result and handle failed items individually. Treat `failed` as a terminal search with no ready results.

For Enrich, stop polling on `completed` or `failed`. The server-generated `request_id` is the status handle for accepted work.

## Safe retry pattern

1. Let Orbit generate request IDs. Persist the returned `search_id` or Enrich `request_id` after the POST succeeds.
2. Retry transport, `429`, and temporary server failures with backoff. Use an optional `Idempotency-Key` header when duplicate POSTs must be prevented.
3. Honor `Retry-After` when present.
4. Use exponential backoff with jitter for both POST retries and polling.
5. Stop polling on every terminal status.

<Warning>
  Reuse an `Idempotency-Key` only with the exact same request. Using one key for different work returns `409`.
</Warning>
