Idempotency
Every POST needs an Idempotency-Key. Retry with the same key and the work happens once.
Networks fail in the worst place: after Gauge sent the message, before you got the answer. An idempotency key makes the retry safe. Send the same key again and Gauge returns the first answer instead of doing the work twice.
Every POST on /v2 requires an Idempotency-Key header. A POST without one answers
400 validation_failed, naming the header.
curl https://app.gauge.chat/backend/v2/messages \
-H "Authorization: Bearer $GAUGE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5d1f8c2a-7e3b-4a9d-b6c0-2f8e1a4d7c93" \
-d '{"connectionId":"…","to":"+447700900123","text":"Hello"}'Choosing a key
- 1 to 255 visible ASCII characters (no spaces).
- One key per distinct operation. A UUID generated when you decide to do the thing works, as
does an id from your own system that names the operation:
order-1042-confirmation. - Generate it before the first attempt and reuse it for every retry of that operation. A new key on each retry defeats the point.
What happens
Keys are scoped to the API key, the method and the path, and are kept for 24 hours.
| You send | Gauge answers |
|---|---|
| A key it has not seen | Runs the request and stores the answer |
| The same key and the same body, after the first finished | The stored status and body, with Idempotent-Replayed: true |
| The same key and the same body, while the first is still running | 409 conflict, reason: idempotency_in_flight. Retry shortly. |
| The same key with a different body | 409 idempotency_mismatch. A new request needs a new key. |
| The same key after the first attempt failed | Runs again: a failed attempt releases its key, so an honest retry is not stuck behind an error |
A replay is visible in Developers → Logs, where it is marked as a replay.
Sending messages
For POST /v2/messages, the idempotency key is also how a message is identified as "the same send".
Gauge derives the message's own de-duplication reference from your API key and the
Idempotency-Key, and stores it on the message. So:
- Within 24 hours, a retry replays the first answer exactly: the same status (
201or202) and body, withIdempotent-Replayed: true. - After 24 hours, the replay record is gone, but the message still carries the reference: a
retry with the same key answers that same message (with its current status, so
201once it has been sent) and never sends a second one.
The reference is per API key: the same Idempotency-Key on two different keys is two sends.