Vous avez une chaîne, ou un petit objet de chaînes, qui doit être disponible immédiatement dans une autre langue — un libellé de formulaire, une notification, un court texte d’interface qu’un utilisateur attend. Vous n’avez pas envie de mettre en place un endpoint webhook ni d’interroger un job pour un simple aller-retour. Vous voulez envoyer le texte et récupérer la traduction dans la foulée.
C’est exactement à cela que sert l’endpoint Localize synchrone : une requête, des données traduites renvoyées dans la même structure. Vous envoyez un contenu clé-valeur en POST avec une langue source et une langue cible, l’appel reste bloquant pendant que votre moteur traduit, puis la réponse renvoie le même objet avec ses valeurs traduites et sa structure intacte. Aucun job à suivre, aucun second appel à faire.
La traduction ne repose pas sur un simple appel générique à un modèle. Elle passe par le moteur de localisation que vous avez configuré — son glossaire, sa voix de marque, ses instructions et sa sélection de modèle par langue — le même moteur que l’API asynchrone utilise. La seule différence, c’est le format : l’asynchrone déploie une requête sur plusieurs langues et livre les résultats à mesure qu’ils arrivent ; cet appel ne traite qu’une seule paire de langues et renvoie le résultat directement dans la réponse.
Une seule langue et un appel bloquant vous conviennent ? Vous êtes au bon endroit.
Choisissez cet endpoint lorsque vous avez besoin d’une seule paire de langues et que vous pouvez attendre un aller-retour. Si vous avez de nombreuses langues cibles, un contenu long, ou si vous voulez isoler les échecs par langue, l’API de localisation asynchrone accepte une requête, renvoie un 202 immédiatement, puis exécute chaque langue comme un workflow d’arrière-plan durable et indépendant. Autre différence, au-delà de la latence : le pipeline de localisation — pré-édition, relecture humaine, rétrotraduction et autres étapes optionnelles — ne s’exécute que sur les jobs asynchrones. Cet appel synchrone ignore la configuration du pipeline.
Sur cette page
Requête#
POST /process/localizeAuthentifiez-vous avec l’en-tête X-API-Key. Les clés sont limitées au niveau de l’organisation et donnent accès à tous les moteurs de votre organisation — voir Authentication pour savoir où en générer une, et Errors and status codes pour le modèle d’erreur complet.
| Paramètre | Type | Description |
|---|---|---|
engineId | string (facultatif) | ID du moteur de localisation (eng_...). Utilise le moteur par défaut de votre organisation si ce champ est omis. |
sourceLocale | string | langue source BCP-47 (par ex. en). |
targetLocale | string | langue cible BCP-47 (par ex. de). |
data | object | Contenu clé-valeur à traduire. Les objets imbriqués et les tableaux sont pris en charge ; la réponse reprend exactement la structure que vous envoyez. |
context | string (facultatif) | Contexte général de cette charge de traduction, comme la surface produit, l’audience ou l’objectif. S’applique à l’ensemble de la requête. |
hints | object (facultatif) | Indications contextuelles par clé. Les clés correspondent à celles de data ; les valeurs sont des tableaux de chaînes de type fil d’Ariane (par ex. { "nav.home": ["Navbar", "Home link"] }) qui indiquent au moteur où se trouve une chaîne, afin de lever l’ambiguïté sur des textes courts ou polysémiques. |
{
"engineId": "eng_abc123",
"sourceLocale": "en",
"targetLocale": "de",
"data": {
"greeting": "Hello, world!",
"cta": "Get started"
},
"hints": {
"cta": ["Landing page", "Primary button"]
}
}Réponse#
La réponse contient le contenu traduit dans la même structure que celle que vous avez envoyée, ainsi que le modèle qui l’a produit et le coût de la requête. Les mêmes clés reviennent, avec la même imbrication — votre code peut récupérer la traduction dans une structure qu’il connaît déjà.
| Champ | Type | Description |
|---|---|---|
sourceLocale | string | langue source BCP-47, reprise depuis la requête. |
targetLocale | string | langue cible BCP-47, reprise depuis la requête. |
data | object | Contenu clé-valeur traduit, conforme à la structure d’entrée. |
model | string (facultatif) | Modèle LLM ayant produit cette traduction, au format provider/model (par ex. anthropic/claude-sonnet-4.5). Consultez-le pour savoir quel modèle de votre chaîne de repli a réellement été utilisé. Absent lorsqu’aucun appel LLM n’a été effectué — voir l’encadré ci-dessous. |
usage | object (facultatif) | Nombre de tokens et coût de la requête en USD. Absent lorsqu’aucun appel LLM n’a été effectué. |
L’objet usage détaille le coût de l’appel, afin que vous puissiez attribuer la dépense sans devoir consulter la facturation séparément :
| Champ | Type | Description |
|---|---|---|
inputTokens | number | Nombre total de tokens d’entrée consommés sur l’ensemble des segments. |
outputTokens | number | Nombre total de tokens de sortie générés sur l’ensemble des segments. |
cacheReadTokens | number | Tokens d’entrée servis depuis le cache de prompt du fournisseur, lorsque le modèle les remonte. |
cacheWriteTokens | number | Tokens d’entrée écrits dans le cache de prompt du fournisseur, lorsque le modèle les remonte. |
llmCost | number | Coût du fournisseur LLM en amont, en USD. 0 lorsqu’aucun coût n’a été signalé. |
localizationCost | number | Coût par token de Lingo.dev en USD, calculé à partir de outputTokens. |
cost | number | Coût total de la requête en USD (llmCost + localizationCost). |
{
"sourceLocale": "en",
"targetLocale": "de",
"data": {
"greeting": "Hallo, Welt!",
"cta": "Jetzt starten"
},
"model": "anthropic/claude-sonnet-4.5",
"usage": {
"inputTokens": 2789,
"outputTokens": 861,
"cacheReadTokens": 0,
"cacheWriteTokens": 0,
"llmCost": 0.02129,
"localizationCost": 0.001722,
"cost": 0.023012
}
}Quand `model` et `usage` sont absents
Si data est vide — aucune clé à traduire — l’endpoint s’arrête immédiatement sans appeler de LLM, et la réponse omet model et usage. C’est le seul cas où les champs de coût sont absents, et la raison est simple : il n’y a eu aucun coût. Rien n’a été traduit, donc rien n’a été dépensé. Toute requête qui déclenche une traduction inclut ces deux champs. Traitez-les comme facultatifs dans votre parseur, et le cas d’entrée vide ne vous prendra pas au dépourvu.
Exemples#
Le même appel en cinq langues. Chacun envoie un objet plat pour plus de clarté ; data accepte aussi les objets imbriqués et les tableaux, et la réponse revient dans la structure exacte que vous envoyez.
const response = await fetch(
"https://api.lingo.dev/process/localize",
{
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
engineId: "eng_abc123",
sourceLocale: "en",
targetLocale: "de",
data: {
greeting: "Hello, world!",
cta: "Get started",
},
}),
}
);
const { data } = await response.json();
// { greeting: "Hallo, Welt!", cta: "Jetzt starten" }Ce qui se passe pendant la localisation#
Un seul POST masque une suite d’étapes, et il vaut la peine de les connaître — car c’est elles qui garantissent une sortie cohérente avec le reste de votre contenu localisé, plutôt qu’une proposition isolée d’un modèle. Lorsqu’une requête atteint l’endpoint, le moteur applique toute sa configuration dans l’ordre :
Sélection de modèle — Sélectionne le modèle LLM le plus prioritaire correspondant à la paire de langues. Les modèles spécifiques à une langue priment sur les modèles joker (
*). Si le modèle principal échoue, le moteur bascule automatiquement vers le modèle suivant dans le classement.Voix de marque — Charge la voix de marque pour la langue cible, avec repli sur la voix de marque joker si aucune version spécifique à cette langue n’existe.
Instructions — Charge chaque instruction correspondant à la langue cible, y compris les instructions joker.
Recherche dans le glossaire — Découpe les valeurs d’entrée en segments interrogeables, génère des embeddings et lance une recherche de similarité vectorielle dans le glossaire du moteur. Les termes trouvés imposent des traductions exactes, ou marquent certains termes comme non traduisibles afin qu’ils soient conservés tels quels.
Génération — Envoie le prompt composé au modèle sélectionné, puis analyse et valide la réponse JSON.
C’est le même pipeline d’étapes du moteur que l’API asynchrone exécute pour chaque job. Choisir le synchrone plutôt que l’asynchrone change le mode de livraison, pas la manière dont la traduction est produite — ainsi, une chaîne traduite ici et la même chaîne traduite dans un job asynchrone s’appuient sur les mêmes termes du glossaire et la même voix.
Le repli de modèle est automatique, et la réponse vous indique lequel a été utilisé
Si le modèle principal échoue, le moteur essaie le modèle suivant selon l’ordre de priorité. Cela se fait de manière transparente — la structure de la réponse reste identique, quel que soit le modèle ayant produit la traduction. Le seul signal d’un repli est le champ model dans la réponse : consultez-le lorsque vous avez besoin de savoir exactement quel modèle de votre chaîne a traité une requête donnée.
