Aller au contenu principal

Idempotence — API publique Pesia

L'API Pesia implémente une idempotence replay-safe sur toutes les opérations mutantes (POST, PATCH, DELETE). Une clé d'idempotence garantit que renvoyer la même requête après une réponse de succès conservée ne réexécute pas cette opération. Les réponses avec un secret à usage unique suivent une exception décrite ci-dessous.

Quand utiliser Idempotency-Key​

Le header Idempotency-Key est obligatoire sur toutes les requêtes mutantes :

MéthodeExempleObligatoire
POSTPOST /partner/v1/webhooks/subscriptionsOui
PATCHPATCH /partner/v1/...Oui
DELETEDELETE /partner/v1/webhooks/subscriptions/:idOui
DELETEDELETE /partner/v1/webhooks/subscriptions/:id/deliveriesOui
GETGET /partner/v1/smicNon (lecture seule)

Une requête mutante sans Idempotency-Key est rejetée avec 400 Bad Request.

Format de la clé​

La clé doit être un UUIDv4 ou un ULID :

# UUIDv4
Idempotency-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479

# ULID
Idempotency-Key: 01ARZ3NDEKTSV4RRFFQ69G5FAV

Le serveur valide le format par regex. Une clé invalide retourne 400 Bad Request avec code: "idempotency_key_invalid_format".

Règles :

  • Unique par opération intentionnelle (générez une nouvelle clé à chaque action)
  • Sensible à la casse
  • TTL : 24 heures (la clé expire après 24h — vous pouvez alors réutiliser le même UUIDv4)

Comportements​

Première requête​

La première requête avec une clé inconnue est traitée normalement. La réponse est conservée pendant 24 heures, sauf les données à usage unique comme le secret de création d'un abonnement webhook. Ce secret n'est pas restitué lors d'un rejeu.

Relecture (replay)​

Si vous renvoyez exactement la même requête (même clé + même corps), le serveur renvoie la réponse persistée sans ré-exécuter l'opération :

HTTP/1.1 201 Created
X-Idempotency-Replayed: true
Content-Type: application/json

{ "success": true, "data": { ... }, "timestamp": "2026-08-10T12:00:00.000Z" }

Le header X-Idempotency-Replayed: true indique que la réponse provient du cache idempotent.

Conflit de corps (body mismatch)​

Si vous renvoyez la même clé avec un corps différent, le serveur refuse la requête :

HTTP/1.1 409 Conflict
Content-Type: application/problem+json

{
"type": "https://docs.pesia.fr/partner/errors/idempotency_key_conflict",
"title": "Idempotency key conflict",
"status": 409,
"code": "idempotency_key_conflict",
"detail": "The provided Idempotency-Key was already used with a different request body.",
"originalRequestAt": "2026-06-01T10:00:00.000Z",
"instance": "/partner/v1/dpae/submissions",
"timestamp": "2026-08-10T12:00:00.000Z"
}

Exemple : renvoyer un dépôt DPAE​

Enregistrez le corps décrit dans DPAE dans dpae.json. Après une coupure réseau, renvoyez le même fichier avec la même clé, le même accès et le même environnement :

curl -X POST https://api.pesia.fr/partner/v1/dpae/submissions \
-H "Authorization: Bearer <token>" \
-H "X-Pesia-Env: sandbox" \
-H "Idempotency-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Content-Type: application/json" \
--data-binary @dpae.json

Si une réponse de succès a été conservée, le rejeu la restitue sans créer un autre dépôt. Pour un lot corrigé, utilisez une nouvelle clé. La DPAE dispose aussi d'une déduplication métier par référence contrat, organisation et environnement.

Exception : secret webhook​

La création d'un abonnement webhook renvoie hmacSecret une seule fois. Le rejeu avec la même clé ne restitue pas le secret ni la réponse initiale complète. Si la première réponse est perdue, listez vos abonnements pour retrouver l'URL. Supprimez l'abonnement concerné en trois étapes (voir Supprimer un abonnement), puis créez-en un nouveau avec une nouvelle clé.

Codes d'erreur​

CodeStatutDescription
idempotency_key_required400Header absent sur une opération mutante
idempotency_key_invalid_format400Format UUIDv4/ULID non respecté
idempotency_key_conflict409Même clé, corps différent

Tous les codes respectent le format RFC 7807.

Durée de vie des clés​

Une clé d'idempotence est conservée 24 heures, puis expirée automatiquement. Réutiliser une clé au-delà de cette fenêtre la traite comme une nouvelle requête. Côté intégration, générez une clé fraîche par opération métier distincte.

Voir aussi​