Écritures et idempotence
Écrire avec POST /operations, réessayer sans doublon avec Idempotency-Key et prévisualiser un effet avec dry_run.
Toute écriture passe par POST /operations/<nom>. Cette page explique comment choisir une opération, comment réessayer sans créer de doublon et comment prévisualiser un effet avant de le produire.
Trouver une opération
GET /operations liste les opérations. L'appel est public : sans clé, sans crédit. Il fait foi sur chaque opération : sa nature (kind), le périmètre demandé (scope), les périmètres sensibles (sensitive), la possibilité de prévisualiser (confirmable) et les arguments (input_schema).
curl https://api.fitdistance.io/api/partner/v1/operations \
| jq '.data[] | {name, kind, scope, confirmable}'Un nom absent de cette liste reçoit un 404 OPERATION_NOT_EXPOSED, sans crédit.
Appeler une opération
Le corps JSON est l'objet des arguments, plus dry_run en option. Cet exemple demande students:write :
curl -X POST https://api.fitdistance.io/api/partner/v1/operations/students.note_create \
-H "Authorization: Bearer $FITDISTANCE_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: note-42-2026-10-25" \
-d '{"studentId": 42, "content": "Bonne séance"}'La réponse a toujours trois champs : data (le résultat, de forme propre à l'opération), message et dry_run.
{ "data": { "uid": "…", "studentId": 42 }, "message": "", "dry_run": false }Réessayer sans doublon
Un appel qui expire laisse un doute : l'écriture a-t-elle eu lieu ? L'en-tête Idempotency-Key le lève. Il est facultatif, mais envoie-le sur chaque écriture.
- Donne une valeur unique par écriture voulue, de 1 à 128 caractères, comme un UUID. Une valeur vide ou plus longue donne un 400
VALIDATION. - Même clé et même requête, c'est-à-dire la même opération et le même corps : l'écriture ne tourne qu'une fois. Le rejeu rend la réponse stockée avec
Idempotency-Replayed: true, et son crédit est remboursé. - Même clé et requête différente : 409
IDEMPOTENCY_MISMATCH, gratuit. - Même requête encore en cours : le rejeu attend sa réponse, sinon 409
CONFLICT, gratuit. Si le conflit dure, un appel a été interrompu : vérifie si l'écriture a eu lieu, puis envoie une nouvelle clé.
Une Idempotency-Key est propre à la clé API qui l'envoie, et gardée de 24 à 48 heures. Les réponses 5xx et 429 ne sont jamais stockées : le nouvel essai s'exécute. Le refus d'une opération (un 4xx) est stocké comme une réponse réussie : après avoir corrigé la requête, prends une nouvelle Idempotency-Key. Sans crédit, même un rejeu reçoit un 402.
Prévisualiser avec dry_run
Ajoute "dry_run": true au corps : l'opération annonce son effet sans rien écrire.
- C'est un booléen strict : la chaîne
"true"est refusée en 400VALIDATION. - Seules les opérations
confirmable: trueprévisualisent. Pour les autres : 400DRY_RUN_UNSUPPORTED, gratuit, et rien n'a tourné. messaging.sendne prévisualise qu'avecthreadUid. AvecstudentId, il répondDRY_RUN_UNSUPPORTED, car trouver le fil de l'élève peut le créer.- Un aperçu n'écrit rien et n'est jamais débité, sauf pour neuf opérations qui débitent l'aperçu et le remboursent s'il n'écrit rien (à solde nul, leur
dry_runrépond 402). Il demande le même périmètre que l'appel réel.
{
"data": null,
"message": "<l'effet décrit par l'opération>",
"dry_run": true
}data vaut null et l'effet est dans message. Le dry_run fait partie du corps : pour la vraie écriture, prends une autre Idempotency-Key.
Le script de Écrire un script applique ces règles, et chaque opération est décrite dans la référence.