Idempotency
Creating a resource is the one kind of request you never want to run twice by
accident. A dropped connection or a timed-out retry could otherwise leave you
with two identical audiences, or a second activation delivering to a partner.
The optional Idempotency-Key header makes a create safe to retry: the
platform recognises the repeat and replays the original outcome instead of
doing the work again.
Which endpoints honor it
Eight endpoints - the resource creates and Estimate Audience Size - read the
Idempotency-Key header:
| Endpoint | Route |
|---|---|
| Create Audience | POST /api/v2/analyses/audiences/create |
| Estimate Audience Size | POST /api/v2/analyses/audiences/estimate |
| Create Lookalike Audience | POST /api/v2/analyses/audiences/create-lookalike |
| Create Cohort | POST /api/v2/analyses/cohorts/create |
| Create Activation | POST /api/v2/analyses/activations/create |
| Create Project | POST /api/v2/analyses/projects/create |
| Create Schedule | POST /api/v2/analyses/schedules/create |
| Create Submission by Upload | POST /api/v2/my-data/pois/submissions/create-by-upload |
The header is ignored everywhere else. Cancel Lookalike, the schedule activate/deactivate writes, and the delete endpoints do not participate - sending the header does not make a cancel, a status toggle or a delete idempotent.
How a key behaves
The key is optional and caller-generated: you supply any unique string
(a UUID v4 is typical) in the Idempotency-Key header. Omit it and the create
runs normally, with no replay protection.
When you do send a key:
- First request - runs normally. If it succeeds (a
2xxresponse), that response is stored against the key. - Same key, same body, within the TTL - the stored response is replayed
verbatim, carrying an extra
Idempotency-Replayed: trueheader. No second resource is created. - Same key, different body - rejected with
409 Conflict. A key is a promise that the request is the same one; changing the body breaks that promise. - Same key while the first request is still in flight - a concurrent
duplicate also returns
409 Conflictrather than starting a second run.
The stored response lives for 24 hours. After that TTL expires, the same key is free to start a fresh create.
Only successful responses are cached
Only 2xx responses are stored. If the first attempt fails with a 429 (rate
limited) or a 5xx, nothing is cached, so a retry with the same key genuinely
re-executes the create - which is exactly what you want, because the
resource was never made. Retry those safely.
Replay is scoped to you
A stored response is scoped to the token, the company, and the exact route that produced it. Keys never collide across different tokens, different companies, or different endpoints: the same string used by two callers, or on two different create routes, is two independent keys. You will only ever replay a response your own token created on that same route.
Using it well
- Generate a fresh key per logical operation - one UUID for “create this audience”, a different one for the next audience.
- Reuse that same key on every retry of that one operation - on a timeout, a
dropped connection, or a
429/5xx, resend with the key you already generated. You either get the original result back (if the first attempt actually succeeded) or a clean re-execution (if it did not). - Do not reuse a key for a genuinely new create - a new operation carrying an
old key either replays the old result or, if the body differs, returns
409.
Calling from an AI agent over MCP? The create tools take an
idempotency_key argument that maps to this exact header, with identical
semantics - pass a fresh value per logical create and reuse it on retries. See
Automate with an AI Agent.
One tool differs: estimate_audience_size waits up to about 12 seconds for
the estimate’s answer after its create. Its replay is the stored response with
data[0] as the estimate is now, not the stored body verbatim, and it waits
for the answer again. A retry sent while the first call is still waiting
replays at once, without a 409 (the create itself is done), and takes the
wait over: the first call then answers at once. Estimate Audience Size over
the API behaves as described above.
Related
- The Async Model - create returns fast, then you poll.
- Errors - the error envelope, including
409and429. - Polling and Rate Limits - retrying on a
429withRetry-After, and idempotent retries in practice.