L’appel fonctionne en développement. Il vous reste maintenant à écrire la partie qui tourne en production — le bloc catch. À elle seule, une erreur HTTP venant d’une API tierce ne dit pas grand-chose : un code d’état en rouge, et aucune réponse évidente à la seule question qui compte à 3 h du matin — est-ce ma requête, ma clé, mon forfait ou leurs serveurs ? Et parmi ces cas, lesquels faut-il retenter, et lesquels faut-il remonter à l’utilisateur ?
Lingo.dev répond à cette question avec une structure claire. Chaque erreur — sur tous les endpoints, synchrones comme asynchrones — revient sous la forme du même objet JSON, avec un code d’état issu d’une table unique et fixe. Le code d’état n’est pas un simple libellé, c’est une instruction : il vous dit s’il faut corriger la requête, remplacer la clé, recharger le compte, temporiser ou réessayer. Lisez le code, vous saurez quoi faire ensuite. Un seul gestionnaire d’erreurs, piloté par le code d’état, couvre toute l’API.
Sur cette page
- Le format de l’erreur
- Codes d’état
- Quelles erreurs retenter
- 402 vs 429 : deux limites différentes
- Où apparaissent les erreurs des tâches asynchrones
Le format de l’erreur#
Chaque réponse hors 2xx a le même corps : un objet JSON avec un seul champ message qui décrit ce qui s’est mal passé.
{
"message": "Invalid API key"
}C’est tout le contrat. Pas d’enveloppe à déballer, pas de format d’erreur spécifique à un endpoint à traiter à part. Un 400 de /process/localize et un 404 lors de la recherche d’une tâche renvoient le même format — seuls le code d’état et le texte de message changent.
Basez-vous sur le code d’état, pas sur le texte du message
Le code d’état HTTP est le signal stable — faites reposer votre gestion des erreurs sur lui. La chaîne message est rédigée pour un humain qui lit un log ; traitez-la comme une description, pas comme un code d’erreur exploitable par une machine, et n’essayez pas d’en déduire quelque chose à partir de sa formulation exacte.
Codes d’état#
Sept codes d’état couvrent toutes les réponses. Ils sont regroupés ici selon qui doit les résoudre — car ce regroupement définit aussi votre politique de retry.
Vous avez envoyé quelque chose que la requête ne peut pas accepter (corrigez la requête, ne retentez pas à l’aveugle) :
| Code | Signification |
|---|---|
400 Bad Request | La validation de la requête a échoué — champ manquant, langue invalide, callbackUrl en HTTP (et non en HTTPS), ou payload mal formé. |
401 Unauthorized | L’en-tête X-API-Key est absent ou invalide. Voir Authentification. |
403 Forbidden | La clé est valide, mais n’a pas accès à la ressource demandée. |
404 Not Found | La ressource — un moteur, une tâche ou un groupe de tâches — n’existe pas. |
Votre organisation a atteint une limite de compte (à résoudre côté facturation) :
| Code | Signification |
|---|---|
402 Payment Required | L’organisation a atteint sa limite de crédit. |
429 Too Many Requests | L’organisation a atteint son quota quotidien de tokens. Passez à un forfait supérieur pour relever la limite. |
Quelque chose a échoué de notre côté (transitoire — réessayez) :
| Code | Signification |
|---|---|
500 Internal Server Error | Une défaillance inattendue — erreur de base de données, ou échec de l’appel de traduction sur tous les modèles configurés dans le moteur. |
Un 401 et un 403 peuvent se ressembler, mais ils ne désignent pas le même problème : 401 signifie que nous n’avons pas pu identifier l’appelant, alors que 403 signifie que nous avons identifié la clé, mais qu’elle n’est pas autorisée à accéder à la ressource. La solution à un 401, c’est la clé elle-même (la remplacer ou la vérifier) ; la solution à un 403, c’est les droits d’accès de la clé.
Quelles erreurs retenter#
La première question qu’un intégrateur un peu sceptique pose face à n’importe quel tableau d’erreurs est souvent celle à laquelle il ne répond pas : lesquelles faut-il retenter ? Le regroupement ci-dessus vous donne la réponse.
- 4xx — ne retentez pas à l’aveugle. Un
400,401,403ou404décrit un problème dans votre requête. Relancer exactement la même requête reproduira exactement la même erreur. Corrigez l’entrée, la clé ou l’identifiant de ressource, puis renvoyez la requête. - 402 et 429 — temporisez, puis traitez la limite. Ce ne sont pas des erreurs transitoires au niveau de la requête ; la suivante se heurtera au même blocage tant que la limite sous-jacente n’aura pas changé. Évitez les retries en boucle serrée, remontez clairement la limite, puis résolvez-la (rechargement du compte ou montée en gamme du forfait).
- 500 — réessayez avec backoff. C’est la seule classe réellement transitoire. Un
500peut signifier que tous les modèles configurés ont expiré sur cet appel ; une nouvelle tentative peut tomber sur un modèle en bonne santé. Utilisez un backoff exponentiel et un nombre maximal de tentatives.
L’API asynchrone renvoie les résultats autrement
Cette politique de retry s’applique aux appels synchrones que vous effectuez vous-même. L’API de localisation asynchrone ne vous renvoie pas de code d’état pour le résultat du travail : une requête POST renvoie 202 une fois acceptée, et chaque langue cible s’exécute comme une tâche indépendante via des workflows d’arrière-plan durables. Vous interrogez la tâche ou recevez un webhook pour obtenir le résultat, au lieu de gérer un code d’état sur l’appel d’origine. Voir où apparaissent les erreurs des tâches asynchrones.
402 vs 429 : deux limites différentes#
Ces deux codes au niveau du compte se ressemblent — dans les deux cas, on a l’impression qu’« il n’y a plus de marge » — et les confondre envoie le développeur vers la mauvaise solution. Il s’agit pourtant de deux limites distinctes, avec deux résolutions distinctes :
402 Payment Required— l’organisation a atteint sa limite de crédit. C’est une limite de facturation. L’appel suivant continuera d’échouer tant que l’état de facturation de votre organisation n’aura pas changé.429 Too Many Requests— l’organisation a atteint son quota quotidien de tokens. C’est un plafond d’usage qui se réinitialise, et vous pouvez le relever en passant à un forfait supérieur.
Pourquoi les distinguer dans votre gestionnaire : un 402 appelle une action de facturation effectuée par une personne ; un 429 correspond à un quota qu’il faut soit laisser se réinitialiser, soit relever via une montée en gamme. Renvoyer les deux vers un message générique du type « problème de paiement » masque le vrai levier que l’opérateur doit actionner.
Un corps de réponse 402 ressemble à n’importe quelle autre erreur — c’est le code d’état qui vous indique qu’il s’agit d’une limite de crédit :
{
"message": "Organization has reached its credit limit"
}Où apparaissent les erreurs des tâches asynchrones#
Il y a une distinction importante à faire, car c’est précisément là qu’un gestionnaire basé sur les codes d’état cesse d’être le bon outil.
Les codes d’état de cette page sont au niveau du transport : ils indiquent si l’API a accepté votre requête HTTP et a pu y répondre. Un 202 de l’API asynchrone signifie que votre requête a été acceptée — pas que la traduction a réussi. Une tâche asynchrone peut être acceptée sans problème, puis échouer plus tard, par exemple si un modèle expire en cours d’exécution. Cet échec n’apparaît pas comme un code d’état HTTP sur votre appel d’origine ; il est enregistré sur la tâche elle-même.
Les échecs asynchrones apparaissent donc à trois endroits, et aucun ne figure dans ce tableau :
- Statut par tâche. Une langue en échec porte
status: "failed"et unerrorMessagesur la tâche. Voir statuts des tâches. - Statut du groupe. Quand certaines langues réussissent et que d’autres échouent, le groupe renvoie
partial— les langues réussies sont tout de même livrées. Voir suivre un groupe de tâches. - Livraison des webhooks. Un échec est livré sous forme d’événement
translation.failedavec un champerror. Voir livraison des webhooks.
Une autre distinction piège souvent les utilisateurs : l’échec d’une étape pipeline non critique ne fait pas échouer la tâche. La tâche se termine avec completed_with_warnings et des avertissements par étape, plutôt qu’une erreur. C’est un sujet d’observabilité du pipeline, pas un code d’erreur — voir observer les exécutions du pipeline.
Étapes suivantes#
Un gestionnaire d’erreurs propre commence par les deux types de cas que vous rencontrerez d’abord pendant l’intégration — l’authentification, et les endroits où le travail asynchrone expose son propre résultat.
