# Handle errors and retries

Make failures understandable to your backend and recover without duplicating customer actions.

An API error returns an HTTP status and an `error` object. Use the status and code for your handling logic; use the message to explain or diagnose the particular request.

```json
{
  "error": {
    "code": "invalid_request",
    "message": "The request could not be validated.",
    "doc_url": "https://developer.thesauros.io/api/v1/openapi.json#errors"
  }
}
```

## Choose the next action

| Status | Typical code | Next action |
| --- | --- | --- |
| 400 | `invalid_request` | Correct the fields, parameters or asset. Do not repeat the unchanged request. |
| 401 | `unauthorized` | Check that the correct credential is present and active. |
| 403 | `forbidden` | Check scope, partner binding and account status. |
| 404 | `not_found` | Verify the resource ID, asset and environment. |
| 409 | `conflict` | Resolve the conflicting operation or state. |
| 429 | `rate_limited` | Wait according to the response's retry guidance before trying again. |
| 5xx | `internal` or another service error | Inspect the response and retry eligible reads with backoff. |

## Treat uncertain writes carefully

A timeout or server error does not prove that a write had no effect. Before repeating an action such as user creation, check whether the intended record already exists.

The sandbox supports an idempotency-key mechanism for its documented create flows. Do not assume the Partner API implements the same guarantee merely because it accepts an HTTP header. The current Partner API contract does not provide a general idempotency guarantee for its writes.

## Preserve the diagnostic context

Capture the environment, method, path, status and request ID when available. The backend attaches `X-Request-Id` to successful responses; failures rejected before the response interceptor may not carry it.

Keep secrets and customer-sensitive payloads out of general logs. Use a redacted example when contacting [integration support](/resources/support/).

## Keep the interface useful

Distinguish a valid empty account from unavailable data. Preserve a clearly identified last-known value during a refresh failure, and show pending customer actions until their final state is known.
