Content-Type application/problem+json. Vous obtenez ainsi un objet structuré, prévisible et identique sur toutes les routes — pas de message texte brut à parser.
Branchez toujours votre logique sur le code HTTP (
status) et éventuellement le title, jamais sur le texte de detail, qui peut évoluer sans préavis.Structure d’une réponse d’erreur
Toute erreur partage la même enveloppe. Trois champs sont toujours présents (type, title, status) ; les autres sont contextuels.
URI identifiant le type de problème. Vaut
about:blank par défaut (le code HTTP suffit alors à qualifier l’erreur).Libellé court, lisible et stable du type de problème (ex.
Not Found, Unprocessable Entity).Code de statut HTTP, dupliqué dans le corps pour faciliter le logging.
Message lisible spécifique à cette occurrence (ex.
Transport not found.). À afficher ou logger, mais à ne jamais utiliser comme clé de branchement.URI identifiant l’occurrence précise du problème, lorsqu’il est pertinent.
Détail des erreurs de validation, champ par champ. Présent surtout sur les réponses
422.Codes HTTP
L’API utilise un ensemble restreint de codes, chacun avec une sémantique métier claire.Réponses de succès
| Code | Nom | Quand |
|---|---|---|
200 | OK | Lecture réussie, ou mutation appliquée (estimation, modification de dates, annulation, gestion d’options…). |
201 | Created | Ressource créée : mission (POST /transports) ou refacturation (POST /transports/{id}/price-adjustments). |
207 | Multi-Status | Ajout de documents (POST /transports/{id}/documents) : la réponse contient un résultat par document, certains pouvant réussir et d’autres échouer. |
Un
207 n’est pas une erreur globale : inspectez data[] pour connaître le sort de chaque document (success, error).Réponses d’erreur
| Code | Nom | Signification métier |
|---|---|---|
400 | Bad Request | Corps de requête malformé (JSON invalide). Corrigez la charge utile. |
401 | Unauthorized | Clé API manquante, invalide, révoquée ou expirée. Vérifiez l’en-tête X-Api-Key. |
403 | Forbidden | Le scope requis est absent de la clé (ex. transports:write pour un POST). |
404 | Not Found | Mission inexistante OU appartenant à un autre groupe que celui de votre clé. |
409 | Conflict | Conflit d’idempotence ou conflit métier (voir ci-dessous). |
422 | Unprocessable Entity | Échec de validation du corps : champ requis manquant, valeur invalide. Lisez errors[]. |
429 | Too Many Requests | Limite de débit atteinte. Respectez l’en-tête Retry-After. |
502 | Bad Gateway | Échec d’un service amont (relai de création / tarification). Réessayez. |
Cas particuliers à connaître
404 — ressource d'un autre groupe ou inexistante
404 — ressource d'un autre groupe ou inexistante
Votre clé API est liée à un groupe (flotte, concession, loueur). Toute mission dont le
group_id ne correspond pas à celui de votre clé est traitée comme introuvable. Vérifiez que vous utilisez le bon id (alias offer_id) et la clé du bon groupe.409 — conflit d'idempotence ou conflit métier
409 — conflit d'idempotence ou conflit métier
Un
409 couvre plusieurs situations. Le champ detail précise laquelle :- Idempotence divergente : la même
Idempotency-Keyrejouée avec un corps différent, ou une requête concurrente portant la même clé encore en cours. - Mission déjà facturée ou payée : une refacturation (
price-adjustments) sur une jambe déjà payée ou facturée est refusée. - Mission déjà terminée : une annulation (
cancel) d’une mission déjà clôturée est refusée.
422 — validation du corps de requête
422 — validation du corps de requête
Le corps est syntaxiquement correct mais ne passe pas la validation métier (champ requis absent, valeur invalide). Le tableau
errors[] détaille chaque champ fautif — utilisez-le pour afficher des messages précis à l’utilisateur.429 — limite de débit (rate-limit)
429 — limite de débit (rate-limit)
Le débit est limité par IP, par clé et globalement. Un dépassement renvoie un
429 accompagné de l’en-tête Retry-After (en secondes). Mettez en place un back-off et patientez la durée indiquée avant de réessayer.502 — échec d'un service amont
502 — échec d'un service amont
La création de mission et la tarification s’appuient sur un relai interne. Si celui-ci est temporairement indisponible, l’API renvoie un
502. Ces requêtes sont sûres à rejouer dès lors que vous utilisez une Idempotency-Key : une réponse 5xx n’est pas mise en cache, le verrou d’idempotence est libéré pour permettre un nouvel essai.Exemple complet
Une requêtePOST /transports à laquelle il manque l’objet billing :
Gestion côté client (Node.js)
L’exemple ci-dessous montre un wrapper minimal qui branche sa logique sur le code HTTP, respecteRetry-After sur les 429, et retente automatiquement les erreurs amont (502).
Points clés d’une intégration robuste : brancher sur
status, lire errors[] sur les 422, respecter Retry-After sur les 429, et poser une Idempotency-Key pour pouvoir rejouer les mutations en cas de 502.Étapes suivantes
Idempotence
Posez une
Idempotency-Key pour rejouer les mutations sans effet de bord double, notamment après un 429 ou un 502.Authentification
Comprenez les clés
X-Api-Key, les scopes et l’isolation par groupe — la source des 401, 403 et 404.Démarrage rapide
Créez votre première mission de bout en bout et observez les réponses de succès et d’erreur en conditions réelles.
