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

# Idempotency

> Safely retry POST requests without performing the operation twice

Network failures happen. Idempotency keys let you safely retry a `POST` request — for example after a timeout — without risk of creating a duplicate contact or firing an event twice.

## How it works

Send an `Idempotency-Key` header with any `POST` request. The value can be any unique string, such as a UUID you generate per logical operation.

<CodeGroup>
  ```bash cURL theme={null}
  curl --location --request POST 'https://api.audienceful.com/v2/people' \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: <your-api-key>' \
  --header 'Idempotency-Key: 8f9a1b2c-3d4e-5f60-7182-93a4b5c6d7e8' \
  --data-raw '{ "email": "person@example.com" }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.audienceful.com/v2/people"
  headers = {
      "Content-Type": "application/json",
      "X-Api-Key": "<your-api-key>",
      "Idempotency-Key": "8f9a1b2c-3d4e-5f60-7182-93a4b5c6d7e8",
  }
  payload = {"email": "person@example.com"}

  response = requests.post(url, headers=headers, json=payload)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.audienceful.com/v2/people", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Api-Key": "<your-api-key>",
      "Idempotency-Key": "8f9a1b2c-3d4e-5f60-7182-93a4b5c6d7e8",
    },
    body: JSON.stringify({ email: "person@example.com" }),
  });
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

* The **first** request with a given key executes normally, and its response is stored for **24 hours**.
* A **retry** with the same key **replays the stored response** and adds an `Idempotent-Replay: true` header — the operation does **not** run a second time.
* A retry sent **while the original is still in flight** returns a `409` with code `idempotency_in_progress`.
* **Server errors (`5xx`) are never cached**, so a request that failed on our side can be safely retried with the same key.

Keys are scoped per workspace and per endpoint, so the same key value used against two different endpoints is treated as two independent operations.

<Tip>Generate a fresh idempotency key for each distinct operation, and reuse that same key only when retrying that specific operation.</Tip>
