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

# Idempotency

> Safely retry requests without duplicating money movement.

Money-moving requests should be safe to retry. If a request times out or your
connection drops mid-flight, you often can't tell whether it went through. Send an
idempotency key and Spritz guarantees the operation runs at most once. A retry with the
same key returns the original result instead of doing the work again.

## Send an idempotency key

Add an `Idempotency-Key` header, a unique value such as a UUID, to any mutating request
(`POST`, `PUT`, `PATCH`, `DELETE`). Reuse the same key when you retry that request.

```bash theme={null}
curl -X POST https://platform.spritz.finance/v1/off-ramp-quotes/ \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f9a1c2e-8b47-4d6a-9c1f-2b7e5a0d4e11" \
  # plus your integrator signing headers and the user's Authorization (see Authentication)
  -d '{ "accountId": "...", "amount": "100.00", "rail": "ach_standard", "chain": "ethereum" }'
```

Idempotency applies to authenticated mutating requests that include the header. `GET`
requests are already safe to repeat, so they don't need a key.

## What happens on a retry

| Situation                                            | Result                                                                                                               |
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| First request with a new key                         | Processed normally, and the response is stored for 24 hours                                                          |
| Same key and same request, after it finished         | You get the original response back, with the header `X-Idempotency-Replayed: true`. The operation does not run again |
| Same key while the first request is still processing | `409` (`urn:problem-type:request-in-progress`). Wait and retry; a `Retry-After` header tells you how long            |
| Same key but a different request body                | `422` (`urn:problem-type:idempotency-conflict`). A key is bound to one exact request                                 |

## Scope and lifetime

A key is bound to your auth context and the exact request (method, path, and body). If
you send the same key with a different body, Spritz rejects it with a `422` rather than
risk returning the wrong result. Keys are remembered for **24 hours**; after that, the
same key is treated as new.

## Error responses

```json theme={null}
{
  "type": "urn:problem-type:request-in-progress",
  "title": "Request In Progress",
  "status": 409,
  "detail": "A request with this idempotency key is currently being processed"
}
```

```json theme={null}
{
  "type": "urn:problem-type:idempotency-conflict",
  "title": "Idempotency Key Conflict",
  "status": 422,
  "detail": "The provided idempotency key has been used with a different request"
}
```

Both are standard [problem responses](/guides/errors).

## Best practices

* **Generate a unique key per operation**, for example a UUID.
* **Reuse the same key when you retry** the same operation, so the retry is deduplicated.
* **Never reuse a key for a different operation.**
* **Persist the key** until you've confirmed the outcome, so a crash and retry uses the
  same key.
