Skip to main content
When a request times out, you do not know whether it reached the API. If you repeat it carelessly, the resource may be created twice. On POST /messages, the end customer receives the same message twice. With the Idempotency-Key header, the first call runs and the repetitions get the same response as the first time.
string
Unique key for the operation, up to 200 characters. Accepted on POST and PUT. It is optional: without it, each call runs normally.

How to use it

Generate a unique identifier for each business operation and use that same identifier on every attempt of that operation. With the same key, the API understands that the attempts are a single operation.
The best keys come from something that is already unique in your system, such as order-88213-confirmation, invoice-2026-09-reminder or crm-card-771-note. A random UUID works too, as long as you save it before the first attempt. If a new UUID is generated on each attempt, the key does not protect against duplicates.

What happens in each case

The API returns the response from the first run, with the same status, and adds this header:
Nothing runs again. This is what happens on a retry after a timeout.
The API refuses the request with 409. Using the same key for another operation almost always points to a mistake in how your integration generates keys.
The response is also 409. It happens when two attempts run at the same time. Wait and check the result instead of sending a third attempt.
With more than 200 characters, the request is refused with 400 ERR_API_IDEMPOTENCY_KEY_INVALID before anything runs.

Key rules

Errors are not stored. Only successful responses are recorded. If the call failed because of invalid data, fix the body and repeat with the same key, since the operation has not happened yet. The key applies per token, method and route. The same key used on POST /messages and on POST /contacts counts as two different operations, with no conflict. Different tokens do not share a key either, even within the same company. Responses without a body are replayed too. Operations that answer 204, such as applying a tag to a ticket, record the result like any other, and the repeat returns 204 with Idempotent-Replay: true. Uploads do not use the key. With multipart/form-data the file has not been read yet when the check happens, so there is no body to compare and the key is ignored. This covers media sending, campaigns with a file and scheduled message attachments: handle duplicates on your side there. The key expires. Keys are kept for 24 hours (this period can be configured on the installation). After that, the same key makes the operation run again. The protection is meant for retries made right after a failure. A resend made weeks later is treated as a new operation.
If there is an internal instability, the API processes the request normally, without the idempotency protection, instead of refusing it. For this reason, critical operations should also be able to detect duplicates on your side.

Where to use it

POST /messages

This is where a duplicate is visible to the end customer. Always use it.

POST /campaigns

A campaign created twice sends to your entire base twice.

POST /contacts

Avoids a duplicate record when the retry comes from an automated routine. See also POST /contacts/upsert.

POST /crm/cards

Repeated cards clutter the CRM board and distort the metrics.