Idempotency-Key header
The Bird API supports opt-in request deduplication via the Idempotency-Key header. This page is the wire contract; for the concepts (why, when, and retry strategy) see Idempotency.
Request header
| Header | Constraints |
|---|---|
| Idempotency-Key | Optional. Any string up to 255 characters; a UUID v4 is recommended. Honored on supported POST, PATCH, PUT, and DELETE operations; ignored on GET, HEAD, and OPTIONS. |
Workspace- and organization-scoped mutations support this response replay. User-only and unauthenticated operations, streams, and operations with a separate replay contract bypass it. Sending a key to an operation that bypasses replay does not add deduplication protection.
Omitting the header skips idempotency entirely: the request is processed normally with no deduplication. An empty header value also skips deduplication. On endpoints that declare this header, a key longer than 255 characters returns 422 with code E01001 ValidationError.
Keys are scoped to your workspace and retained for roughly 3 hours. After the retention window, a reused key is processed as a fresh request.
Code example
curl -X POST https://us1.platform.bird.com/v1/email/messages \
-H "Authorization: Bearer bk_us1_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{ "from": "hello@yourdomain.com", "to": ["delivered@messagebird.dev"], "subject": "Welcome!", "html": "<p>Hi.</p>" }'Response semantics
| Scenario | Response |
|---|---|
| First request with a key | Processed normally; a completed response can be retained for replay; 5xx responses are not retained. |
| Same key, identical request | Original status and body replayed, with the Idempotency-Replay: true response header. |
| Same key, different request | 409 with E01005 IdempotencyKeyReuse. Generate a new key for the new request. |
| Same key, original request still in flight | 409 with E01004 RequestInProgress. The lock expires within ~30 seconds; wait and retry. |
| Original request returned 5xx | Not cached: the key unlocks and the retry is processed fresh. |
| Idempotency protection unavailable before execution | 503 with E01033 IdempotencyUnavailable. This attempt is not executed; retry with the same key and request. |
A replayed response is byte-for-byte the original (same status code, same body), distinguished only by the extra header:
Code example
HTTP/1.1 202 Accepted
Idempotency-Replay: true"Identical request" covers the method, endpoint, path and query parameters, and the raw request body; a difference in these values, including JSON whitespace, triggers E01005. Multipart uploads compare part names, filenames, and contents; boundaries and part ordering do not affect replay. Both 409 errors come wrapped in the standard error envelope.
Retained responses can include 4xx rejections. Use a new key when correcting a request: if its rejection was retained, an unchanged retry replays it, and a changed request returns 409 E01005 IdempotencyKeyReuse.
5xx responses are never cached. Retry with backoff using the same key and request. E01033 IdempotencyUnavailable means this attempt did not execute; it does not describe the outcome of an earlier attempt. Keep the key on every retry.
An operation can take effect before its response is retained. If that response is lost, or the in-flight lock expires, a retry can execute the operation again. A timeout or another 5xx response therefore does not prove that the operation had no effect.
SDK behavior
The official SDKs attach an auto-generated UUID Idempotency-Key to every mutating request, generated once per logical call and reused across all retry attempts of that call. You can supply your own key per call (idempotencyKey in TypeScript, option.WithIdempotencyKey in Go, idempotency_key in Python) when one logical operation spans multiple SDK calls. To detect a replay, read the Idempotency-Replay response header through each SDK's transport-metadata accessor: .withResponse() in TypeScript, option.WithResponseInto in Go, and with_raw_response in Python.
Related
- Idempotency concepts: retry strategy, key design, and replay limits
- Error responses: the envelope wrapping E01004 and E01005
- Email messages: the send endpoint, the most common place to use a key
- SDK concepts: automatic key generation and retries
Related resources
Continue with the documentation, guides and examples for this topic. Resources are in English.
Understand the conceptShould I use a Bird SDK or call the API directly?Follow the learning pathBuild your first integrationImplementation guideSend your first email
Get an implementation brief