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

# Errors and idempotency

> Handle problem responses, correlation IDs, retries, and write conflicts safely.

Attesso fails closed. A timeout, infrastructure failure, or non-allow response never grants permission to execute.

## Problem responses

When Attesso supplies an error body, it uses `application/problem+json`. The values below illustrate the response shape; use the exact codes returned by the API.

```json theme={null}
{
  "type": "https://example.invalid/problem-type",
  "title": "Human-readable summary",
  "status": 422,
  "code": "MACHINE_READABLE_CODE",
  "detail": "Human-readable detail",
  "request_id": "req_01J2ABCDEF",
  "retryable": false,
  "errors": [
    {
      "pointer": "/example/path",
      "code": "FIELD_ERROR_CODE",
      "message": "Human-readable field detail"
    }
  ]
}
```

Branch on the returned `code`, `retryable`, and field pointers. Do not branch on human-readable `title`, `detail`, or `message` text.

## Status codes

| Status | Meaning                                          | Default handling                                    |
| ------ | ------------------------------------------------ | --------------------------------------------------- |
| `400`  | Malformed JSON or request syntax                 | Fix the request                                     |
| `401`  | Missing or invalid API key                       | Fix configuration; do not retry blindly             |
| `404`  | Resource not found in your organization          | Verify the identifier and environment               |
| `409`  | Idempotency conflict or invalid state transition | Read current state and reconcile                    |
| `422`  | Valid JSON that violates schema or domain limits | Fix the request                                     |
| `429`  | Rate limit exceeded                              | Back off; a response body is not guaranteed         |
| `503`  | Retryable infrastructure failure                 | Fail closed and retry with the same idempotency key |

Edge-generated `429` responses may omit the problem body, request ID, and `Retry-After` header.

## Idempotency keys

Every write requires `Idempotency-Key`.

```http theme={null}
Idempotency-Key: aut_01HZX8G2Q6V5
```

Keys must be 16–255 characters and contain only letters, digits, `.`, `_`, `:`, or `-`.

* Scope one key to one logical operation.
* Persist the key with your operation state before sending the request.
* Retry identical canonical input with the same key.
* Use a new key for a different operation.
* Reusing a key with different input returns `409`.

A successful replay returns the same resource identity in its current state and includes `Idempotency-Replayed: true`.

## Retry pattern

<Steps>
  <Step title="Classify the failure">
    Respect `retryable` when a problem body is present. Treat uncertain execution outcomes as non-permission.
  </Step>

  <Step title="Keep the original operation identity">
    Reuse the same idempotency key and byte-equivalent logical input.
  </Step>

  <Step title="Back off with jitter">
    Honor `Retry-After` when present. Otherwise use bounded exponential backoff.
  </Step>

  <Step title="Reconcile by reading">
    If a lifecycle transition remains uncertain, retrieve the mandate or authorization before taking another action.
  </Step>
</Steps>

<Info>
  Log `Attesso-Request-Id` for correlation. It is safe to share with Attesso support and does not contain credentials.
</Info>
