Lisez la sortie traduite d'une langue, ainsi que le détail par étape de sa production.
Vous utiliserez ce point de terminaison une fois que vous avez un jobId — renvoyé dans le 202 de création, transmis via un webhook ou listé dans un groupe de jobs. Le point de terminaison du groupe vous dit combien de langues sont terminées. Celui-ci vous dit ce que une langue donnée a produit, et ce qui s'est passé au fil du traitement.
GET /jobs/localization/:jobIdVous découvrez la localisation asynchrone ? Commencez par la Vue d'ensemble.
Toute la raison d'être de cette page est là. La réponse d'un groupe, c'est un tableau de bord : des totaux et un statut par job, présentés sur la page du groupe de jobs. Un job individuel, c'est l'historique complet d'une langue : l'outputData traduit, le status final, les éventuels warnings, et une trace steps[] de chaque étape exécutée par le pipeline. Quand vous êtes prêt à enregistrer le texte allemand dans votre base de données, c'est cet appel qui vous le fournit.
Authentification#
Passez votre clé API dans l'en-tête X-API-Key. Les clés sont limitées à l'organisation et donnent accès à chaque moteur de l'organisation. Voir Authentication pour plus de détails.
Réponse#
Le champ outputData reprend la structure du data d'entrée, avec chaque valeur de type chaîne traduite et chaque valeur non textuelle (nombres, booléens, null) conservée à sa place. Même clés, même imbrication, même ordre des tableaux : seules les chaînes changent.
{
"id": "ljb_A1b2C3d4E5f6G7h8",
"groupId": "ljg_A1b2C3d4E5f6G7h8",
"targetLocale": "de",
"status": "completed",
"outputData": {
"id": "course_101",
"title": "Einführung in maschinelles Lernen",
"steps": [
{ "heading": "Was ist ML?", "body": "Maschinelles Lernen ist ein Teilbereich der künstlichen Intelligenz." },
{ "heading": "Überwachtes Lernen", "body": "Trainieren eines Modells mit gelabelten Daten." }
],
"metadata": { "author": "Dr. Smith", "difficulty": "beginner" }
},
"errorMessage": null,
"warnings": [],
"callbackStatus": "delivered",
"createdAt": "2026-03-16T10:30:00.000Z",
"startedAt": "2026-03-16T10:30:01.000Z",
"completedAt": "2026-03-16T10:30:04.000Z",
"steps": [
{
"stepId": "localize",
"type": "action",
"status": "completed",
"errorMessage": null,
"externalRefType": null,
"externalRefId": null,
"externalRefUrl": null,
"createdAt": "2026-03-16T10:30:01.000Z",
"startedAt": "2026-03-16T10:30:01.000Z",
"completedAt": "2026-03-16T10:30:04.000Z"
}
]
}Le bloc metadata ci-dessus est resté intact : Dr. Smith et beginner sont des valeurs non textuelles que le moteur a laissées telles quelles. L'outputData que vous récupérez a la même forme que celui que vous avez envoyé, donc le même code qui a construit la charge utile peut aussi consommer la traduction.
| Champ | Description |
|---|---|
id | L'identifiant propre à ce job (ljb_…). C'est la valeur passée dans le chemin. |
groupId | Le groupe de jobs parent (ljg_…) auquel ce job appartient. Passez-le à le point de terminaison du groupe de jobs pour voir d'un coup toutes les langues sœurs. |
targetLocale | La langue BCP-47 vers laquelle ce job a traduit — il y a un job par langue cible. C'est ce champ sur lequel vous vous basez pour envoyer outputData vers la bonne colonne ou le bon fichier. |
status | queued, processing, completed, completed_with_warnings ou failed. |
outputData | Contenu traduit qui reprend la structure d'entrée. Présent lorsque status vaut completed ou completed_with_warnings. |
errorMessage | Description de l'erreur. Présente lorsque status vaut failed ; sinon null. |
warnings | Échecs d'étapes non critiques du pipeline. Chaque entrée est { step, message }. Vide sauf si status vaut completed_with_warnings. |
callbackStatus | État de livraison du webhook : pending, delivered ou failed. null si aucune URL de rappel n'est configurée. |
createdAt | Moment où le job a été accepté (l'horodatage du 202 qui l'a créé). |
startedAt | Moment où le moteur a commencé à traduire cette langue. Renseigné une fois que le job quitte queued. |
completedAt | Moment où le job a atteint un état terminal. Renseigné une fois que status vaut completed, completed_with_warnings ou failed. |
steps | Historique d'exécution par étape. Contient toujours l'étape localize, plus une entrée par étape optionnelle activée dans le pipeline. Structure complète de l'historique dans Observe pipeline runs. |
outputData vaut null tant que le job n'est pas terminé
Tant que status vaut queued ou processing, outputData est vide et errorMessage vaut null — il n'y a encore rien à lire. Ne lisez outputData qu'une fois que status a atteint completed ou completed_with_warnings ; en cas de failed, lisez plutôt errorMessage. Commencez par tester status, puis accédez à la charge utile.
Valeurs de statut des jobs#
Un job passe de queued à processing, puis à un unique état terminal. Testez d'abord status avant de lire quoi que ce soit d'autre : c'est ce champ qui vous dit quelles propriétés sont renseignées.
| Statut | Signification | Que lire |
|---|---|---|
queued | Accepté, pas encore démarré. | Rien pour l'instant — interrogez à nouveau, ou attendez le webhook. |
processing | Le moteur traduit cette langue. | Rien pour l'instant. |
completed | Traduction terminée, toutes les étapes activées ont réussi. | outputData. |
completed_with_warnings | La traduction est terminée et outputData est complet, mais une étape non critique du pipeline a échoué. | outputData, puis warnings. |
failed | Le job n'a produit aucune traduction. | errorMessage. |
completed_with_warnings livre quand même une traduction
completed_with_warnings n'est pas un échec mineur. Vous recevez un outputData complet — l'étape centrale de traduction a réussi. Ce qui change, c'est qu'une étape non critique (par exemple pre-edit ou back-translation) n'est pas allée au bout, et chaque échec est consigné dans warnings sous forme de { step, message }. Considérez la sortie comme exploitable ; considérez warnings comme un signal de qualité à faire remonter à la personne qui effectue la relecture des traductions. Seul failed signifie qu'il n'y a aucune traduction à lire.
Gérer les valeurs de statut inconnues
Les cinq valeurs de statut ci-dessus constituent le contrat actuel. Les étapes du pipeline évoluent, donc traitez status comme un ensemble ouvert : gérez les valeurs que vous connaissez et envoyez toute valeur inattendue vers un cas par défaut qui lit outputData s'il est présent et journalise sinon. Un switch sans solution de repli, c'est le genre de ligne qui casse le jour où un nouvel état est mis en production.
Le tableau steps#
steps[] est l'historique par étape d'un job donné — un enregistrement pour chaque étape exécutée par le moteur, dans l'ordre. Chaque job contient au minimum l'étape localize, car la traduction principale s'exécute toujours. Chaque étape optionnelle du pipeline que vous avez activée ajoute un enregistrement de plus. Ainsi, un job sans étape supplémentaire n'affiche qu'une seule étape localize ; un job avec pre-edit et back-translation activés en affiche trois.
C'est ce qui rend un job auditable plutôt qu'une boîte noire. Vous n'avez pas à supposer qu'une étape a été exécutée — vous lisez son enregistrement : quelle étape (stepId), si elle a completed, failed ou a été skipped, ce qu'elle a coûté (costUsd) et quand elle a commencé et s'est terminée. Pour les étapes de relecture humaine, externalRef* pointe vers l'enregistrement externe.
"steps": [
{
"stepId": "preEdit",
"type": "action",
"status": "completed",
"errorMessage": null,
"costUsd": 0.0012,
"createdAt": "2026-03-16T10:30:01.000Z",
"completedAt": "2026-03-16T10:30:02.000Z"
},
{
"stepId": "localize",
"type": "action",
"status": "completed",
"errorMessage": null,
"costUsd": 0.0184,
"createdAt": "2026-03-16T10:30:02.000Z",
"completedAt": "2026-03-16T10:30:05.000Z"
}
]Une entrée failed ici ne fait pas forcément échouer le job. Lorsqu'une étape non critique échoue, son enregistrement steps[] indique failed, le même échec apparaît dans le warnings de premier niveau du job, et le job atteint quand même completed_with_warnings avec un outputData complet. La structure complète de l'historique — chaque champ, chaque stepId, la sémantique de completed/failed/skipped — se trouve sur une page canonique unique : Observe pipeline runs. Cette page vous montre où la trouver dans un job ; cette autre page en donne la spécification.
Lire un job terminé#
Un client typique commence par tester status, écrit outputData en cas de succès et journalise errorMessage en cas d'échec. L'appel prêt à copier-coller ci-dessous renvoie la charge utile présentée plus haut.
const jobId = "ljb_A1b2C3d4E5f6G7h8";
const response = await fetch(`https://api.lingo.dev/jobs/localization/${jobId}`, {
headers: { "X-API-Key": process.env.LINGO_API_KEY },
});
const job = await response.json();
switch (job.status) {
case "completed":
case "completed_with_warnings":
// outputData is populated; warnings may carry non-critical stage failures
await db.content.update({
where: { id: job.outputData.id },
data: { [`content_${job.targetLocale}`]: job.outputData },
});
if (job.warnings.length) console.warn(job.targetLocale, job.warnings);
break;
case "failed":
console.error(`${job.targetLocale} failed: ${job.errorMessage}`);
break;
default:
// queued or processing - nothing to read yet; also catches future states
break;
}Polling ou push
Ce point de terminaison fournit une lecture à un instant T. Pour la plupart des jobs, le moteur met 2 à 8 secondes par langue ; si vous interrogez régulièrement, un intervalle de 2 secondes est un bon point de départ. Pour éviter complètement le polling, enregistrez un webhook et ne récupérez le job que lorsqu'il vous indique que la langue est terminée, ou surveillez l'ensemble du groupe via le WebSocket. Dans tous les cas, un GET final ici constitue la lecture canonique de outputData.
Lorsque ce point de terminaison renvoie une erreur — jobId inconnu, clé manquante — il suit le modèle d'erreur JSON standard. Voir Errors and status codes.
