# Idempotency

> Retry a write without ever doing it twice, thanks to the Idempotency-Key header.

A network loses responses. Without care, retrying a write may launch two crawls, or generate recommendations twice, and consume your quota twice.

## The principle

Send a unique `Idempotency-Key` header per logical operation (a UUID is enough). For 24 hours:

- the same key with the same request replays the **first response**, without running anything, with the `Idempotent-Replayed: true` header;
- the same key with **another** request answers `422 idempotency.key_reused`;
- the same key while the first request is still running answers `409 idempotency.in_progress`.

## Required or accepted

**Billed** writes (launching a crawl, generating recommendations, tracking keywords, checking a keyword) **require** the key: without it, `400 idempotency.key_required`. Other creations accept it. The reference says so for each operation.

```bash expect=202
curl -X POST "https://api.nessflow.com/v1/campaigns/$CAMPAIGN_ID/crawls" \
  -H "Authorization: Bearer $NESSFLOW_TOKEN" \
  -H "Idempotency-Key: 6f1c2b0e-monday-crawl"
```

Replayed with the same key, the request returns the same response, and no second crawl:

```bash expect=202
curl -X POST "https://api.nessflow.com/v1/campaigns/$CAMPAIGN_ID/crawls" \
  -H "Authorization: Bearer $NESSFLOW_TOKEN" \
  -H "Idempotency-Key: 6f1c2b0e-monday-crawl"
```

A `5xx` response is not stored: the key stays free, and the retry really runs.
