Idempotence

Renvoyer une écriture après une coupure réseau sans risquer de doublon, avec l'en-tête Idempotency-Key.

Documentation de l'APIGuides · Idempotence

Le problème

Une requête d'écriture part, la connexion coupe, aucune réponse n'arrive. L'écriture a-t-elle eu lieu ? Sans précaution, la renvoyer peut créer un deuxième contact, valider deux fois un code promo ou publier deux réponses.

L'en-tête Idempotency-Key règle ce cas : une requête renvoyée avec la même clé d'idempotence ne s'exécute qu'une fois, et toutes les tentatives reçoivent la même réponse.

Utiliser une clé d'idempotence

Choisissez une valeur unique par opération métier, par exemple un UUID ou l'identifiant de l'opération dans votre outil, et gardez-la pour chaque nouvel essai de cette même opération :

curl https://api.mabellenote.com/v1/promo-codes/redeem \
  -H "Authorization: Bearer $MBN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: caisse-1-ticket-2026-10-25-0042" \
  -d '{ "code": "BIS-7KQ4", "establishmentId": "kh2n8p5r3t6v9b1c4d7f0g2j5k8m1n3p", "amountCents": 4850 }'
  • La clé compte de 1 à 255 caractères. Hors de ces bornes, l'API répond 400 invalid_request.
  • Elle est propre à la clé API : deux clés API peuvent utiliser la même valeur sans interférer.
  • Elle est conservée 24 heures après sa première utilisation. Au-delà, la même valeur repart de zéro.

Ce que l'API répond

SituationRéponse
Première requête avec cette cléExécutée normalement.
Même clé, même requête, déjà terminéeLa réponse initiale, rejouée, avec Idempotent-Replayed: true.
Même clé, même requête, encore en cours409 idempotency_in_progress : réessayez un peu plus tard.
Même clé, requête différente (autre méthode, chemin ou corps)422 idempotency_key_reused.

Une requête refusée par une erreur, par exemple 400, 404 ou 409 promo_code_already_redeemed, ne garde pas sa clé : après correction, la renvoyer avec la même clé l'exécute de nouveau. Seules les réponses réussies sont rejouées.

Opérations concernées

OpérationIdempotency-Key
POST /v1/contactsFacultatif
PATCH /v1/contacts/{contactId}Facultatif
POST /v1/visitsFacultatif
POST /v1/promo-codes/redeemFacultatif
POST /v1/reviews/{reviewId}/reply-draftsFacultatif
PUT /v1/reviews/{reviewId}/reply-draftFacultatif
POST /v1/reviews/{reviewId}/replyObligatoire

Les lectures n'en ont pas besoin : elles ne modifient rien. POST /v1/webhook-endpoints ne l'accepte pas, car sa réponse contient le secret de signature, qui ne doit pas être conservé.

Cas particuliers

  • Passages : en plus de l'en-tête, un passage est unique par externalId dans un établissement. Transmettre deux fois le même numéro de ticket ne crée qu'un passage, même sans Idempotency-Key : la première réponse est 201, les suivantes 200.
  • Brouillons rédigés par l'IA : la génération ne se fait pas dans la même transaction que l'enregistrement de la clé. La garantie est donc « au plus une génération par clé d'idempotence terminée » : une requête interrompue en plein calcul peut, rarement, consommer une génération sans réponse.
  • Publication sur Google : la clé est obligatoire, pour qu'un appel rejoué ne publie jamais deux fois. Utilisez l'identifiant de l'avis, ou celui de la réponse dans votre outil.

Bonnes pratiques

  • Générez la clé avant le premier envoi, et conservez-la avec l'opération tant que vous n'avez pas de réponse.
  • Réessayez avec la même clé sur une erreur réseau, un délai dépassé, 409 idempotency_in_progress, 429 rate_limited ou 503 service_unavailable, en respectant Retry-After.
  • Ne réutilisez jamais une clé pour une autre opération : vous recevriez 422 idempotency_key_reused, ou pire, la réponse d'une autre opération si les corps sont identiques.

Mis à jour le 25 octobre 2026