# Idempotency

Networks fail at the worst moment. When a call times out on your side, you can't tell whether it ran.
An `Idempotency-Key` makes retrying safe.

```bash
curl https://api.happyfetch.net/v1/company \
  -H "Authorization: Bearer $HAPPYFETCH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f0c9e2a-6b1d-4c8e-9a51-7d2f0b6c1e44" \
  -d '{"url": "stripe"}'
```

## How it works

- Use one unique key, such as a UUID, per logical request, and reuse it for every retry of that request.
- A retry within **24 hours** replays the stored response, with its original status and body, and adds
  the header `Idempotent-Replayed: true`. It isn't charged again.
- A retry while the first request is still running gets `409`
  [`idempotency_key_in_use`](/docs/errors#idempotency_key_in_use). Wait a moment and retry.
- Reusing a key with a different endpoint or body gets `422`
  [`idempotency_key_reused`](/docs/errors#idempotency_key_reused).
- An answer that says retrying helps (a refunded failure, a rate limit) isn't stored, so a retry with the
  same key runs again for real.

## What a replay looks like

A replay is the stored answer, sent again:

- Its body and headers are the original call's, so `X-Credits-Charged`, `Age` and `meta.request_id` describe
  that call. The replay itself costs nothing: check for `Idempotent-Replayed: true`.
- Its `X-Request-Id` header is new: it identifies the replay, while `meta.request_id` in the body still
  points at the original call and its charge.

Keys are scoped to your workspace, so different workspaces can't collide.
