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

# Idempotency

> Safely retry write requests with an Idempotency-Key.

Every write request (`POST` and `PATCH`) to a `/v1` endpoint **requires** an `Idempotency-Key`
header. The key lets you retry a request safely — if a response is lost to a network error, replaying
the same request returns the original result instead of applying the change twice.

<Warning>
  The `Idempotency-Key` header is **mandatory** on all `/v1` writes. A write without it is rejected
  with `400 validation_failed`. (The token endpoint `POST /oauth/token` is exempt — do not send the
  header there.)
</Warning>

## Sending the key

Generate a unique value per logical operation — a UUID is a good choice — and send it as the
`Idempotency-Key` header. Keys may be up to **256 characters**; a longer key returns
`400 validation_failed`.

```bash theme={null}
curl -X PATCH "https://api.secfix.com/v1/inventory/assets/$ASSET_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: 5f3c9a2e-8b4d-4e7a-9c1f-2a5b6c7d8e9f" \
  -H "Content-Type: application/json" \
  -d '{ "classification": "CONFIDENTIAL" }'
```

## Behavior

| Situation                                         | Result                                                                          |
| ------------------------------------------------- | ------------------------------------------------------------------------------- |
| First request with a new key                      | Executes normally; the response is cached against the key.                      |
| Retry with the **same key and same request body** | The original cached response is replayed — the change is **not** applied again. |
| Retry with the **same key but a different body**  | Rejected with `409 idempotency_conflict`.                                       |
| Missing or empty header                           | Rejected with `400 validation_failed`.                                          |
| Key longer than 256 characters                    | Rejected with `400 validation_failed`.                                          |

Keys are scoped to your API key within your workspace, so different API keys can use the
same idempotency key value independently. Only successful (`2xx`) responses are cached — a failed write persists
nothing, so you can safely retry it with the same key.

## Guidance

* Use a **fresh** key for each distinct operation, and **reuse** that key when retrying that same
  operation.
* Do not reuse a key for a different change — that returns `409 idempotency_conflict`.
* Store the key alongside the operation you are performing so a retry after a crash uses the same
  value.
