Sign inGet started

En-tête Idempotency-Key

L'Bird API prend en charge la déduplication optionnelle des requêtes via l'en-tête Idempotency-Key. Cette page décrit le contrat filaire ; pour les concepts (pourquoi, quand et stratégie de réessai), consultez Idempotence.

En-tête de requête

En-têteContraintes
Idempotency-KeyFacultatif. Toute chaîne non vide de 255 caractères maximum ; un UUID v4 est recommandé. Pris en charge sur les opérations POST, PATCH, PUT et DELETE prises en charge ; ignoré sur GET, HEAD et OPTIONS.
Les mutations à portée d'espace de travail et d'organisation prennent en charge ce rejeu de réponse. Les opérations réservées aux utilisateurs et non authentifiées, les flux, ainsi que les opérations disposant d'un contrat de rejeu distinct le contournent. Envoyer une clé à une opération qui contourne le rejeu n'ajoute aucune protection de déduplication.
Omettre l'en-tête désactive entièrement l'idempotence : la requête est traitée normalement sans déduplication. Une clé vide ou dépassant 255 caractères renvoie 400 avec le code E01002 InvalidRequest.
Les clés sont limitées à votre espace de travail et conservées pendant environ 3 heures. Après la fenêtre de rétention, une clé réutilisée est traitée comme une nouvelle requête.
Exemple de code
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>" }'

Sémantique de la réponse

ScénarioRéponse
Première requête avec une cléTraitée normalement ; la réponse (2xx ou 4xx) est mise en cache avec la clé.
Même clé, requête identiqueLe statut et le corps d'origine sont rejoués, avec l'en-tête de réponse Idempotency-Replay: true.
Même clé, requête différente409 avec E01005 IdempotencyKeyReuse. Générez une nouvelle clé pour la nouvelle requête.
Même clé, requête d'origine encore en cours409 avec E01004 RequestInProgress. Le verrou expire en ~30 secondes ; attendez puis réessayez.
La requête d'origine a renvoyé 5xxNon mise en cache : la clé est déverrouillée et le réessai est traité comme une nouvelle requête.
Protection d'idempotence indisponible avant l'exécution503 avec E01033 IdempotencyUnavailable. Cette tentative n'est pas exécutée ; réessayez avec la même clé et la même requête.
Une réponse rejouée est identique octet pour octet à l'originale (même code de statut, même corps), distinguée uniquement par l'en-tête supplémentaire :
Exemple de code
HTTP/1.1 202 Accepted
Idempotency-Replay: true
"Identical request" couvre la méthode, le point de terminaison, les paramètres de chemin et de requête, et le corps brut de la requête ; toute différence, y compris un espace, en fait une requête différente et déclenche E01005. Les deux erreurs 409 sont encapsulées dans la réponse d'erreur standard.
Les réponses 5xx ne sont jamais mises en cache. Réessayez avec un délai exponentiel en utilisant la même clé et la même requête. E01033 IdempotencyUnavailable signifie que cette tentative ne s'est pas exécutée ; cela ne décrit pas le résultat d'une tentative précédente. Conservez la clé à chaque réessai.
Une opération peut prendre effet avant que sa réponse ne soit conservée. Si cette réponse est perdue, ou si le verrou en cours expire, un réessai peut exécuter l'opération à nouveau. Un délai d'attente dépassé ou une autre réponse 5xx ne prouve donc pas que l'opération n'a eu aucun effet.

Comportement des SDK

Les SDK officiels attachent un UUID Idempotency-Key généré automatiquement à chaque requête de mutation, créé une seule fois par appel logique et réutilisé pour toutes les tentatives de réessai de cet appel. Vous pouvez fournir votre propre clé par appel (idempotencyKey en TypeScript, option.WithIdempotencyKey en Go, idempotency_key en Python) lorsqu'une opération logique couvre plusieurs appels SDK. Pour détecter un rejeu, lisez l'en-tête de réponse Idempotency-Replay via l'accesseur de métadonnées de transport de chaque SDK : .withResponse() en TypeScript, option.WithResponseInto en Go et with_raw_response en Python.

Ressources associées