Du hast einen String oder ein kleines Objekt mit Strings, das sofort in einer anderen Sprache vorliegen muss – ein Formularlabel, eine Benachrichtigung oder einen kurzen UI-Text, auf den ein Nutzer gerade wartet. Für einen einzelnen Roundtrip willst du weder einen Webhook-Endpunkt aufsetzen noch einen Job pollen. Du willst den Text senden und die Übersetzung direkt zurückbekommen.
Genau dafür gibt es den synchronen Localize-Endpunkt: eine Anfrage rein, übersetzte Daten in derselben Struktur zurück. Du sendest Schlüssel-Wert-Inhalte per POST mit Quell- und Zielsprache, der Aufruf blockiert, während deine Engine übersetzt, und die Antwort gibt dir dasselbe Objekt mit übersetzten Werten bei unveränderter Struktur zurück. Es gibt keinen Job, den du verfolgen musst, und keinen zweiten Aufruf.
Die Übersetzung ist kein generischer Modellaufruf. Sie läuft durch die Lokalisierungs-Engine, die du konfiguriert hast – mit ihrem glossary, ihrer Markenstimme, ihren Anweisungen und ihrer sprachspezifischen Modellauswahl – dieselbe Engine, die auch die async API nutzt. Der Unterschied liegt nur in der Form: Async verteilt eine Anfrage auf viele Sprachen und liefert Ergebnisse, sobald sie eintreffen; dieser Aufruf verarbeitet genau ein Sprachpaar und gibt das Ergebnis inline zurück.
Ein Sprachpaar und ein blockierender Aufruf sind für dich okay? Dann bist du hier richtig.
Greif zu diesem Endpunkt, wenn du ein einzelnes Sprachpaar brauchst und auf einen Roundtrip warten kannst. Wenn du viele Zielsprachen, längere Inhalte hast oder Fehler pro Sprache isolieren möchtest, nimmt die async Localization API eine Anfrage entgegen, gibt sofort ein 202 zurück und führt jede Sprache als unabhängigen, robusten Hintergrund-Workflow aus. Noch ein Unterschied neben der Latenz: Die Lokalisierungs-Pipeline – Pre-Edit, menschliche Prüfung, Rückübersetzung und die anderen optionalen Stufen – läuft nur bei Async-Jobs. Dieser synchrone Aufruf ignoriert die Pipeline-Konfiguration.
Auf dieser Seite
Anfrage#
POST /process/localizeAuthentifiziere dich mit dem Header X-API-Key. Schlüssel gelten organisationsweit und geben Zugriff auf jede Engine in deiner Organisation – unter Authentifizierung erfährst du, wo du einen Schlüssel erzeugst, und unter Fehler und Statuscodes findest du das vollständige Fehlermodell.
| Parameter | Typ | Beschreibung |
|---|---|---|
engineId | string (optional) | Die ID der Lokalisierungs-Engine (eng_...). Wenn nicht angegeben, wird die Standard-Engine deiner Organisation verwendet. |
sourceLocale | string | BCP-47-Quellsprache (z. B. en). |
targetLocale | string | BCP-47-Zielsprache (z. B. de). |
data | object | Zu übersetzende Schlüssel-Wert-Inhalte. Verschachtelte Objekte und Arrays werden unterstützt; die Antwort spiegelt genau die Struktur wider, die du sendest. |
context | string (optional) | Allgemeiner Kontext für diese Übersetzungsnutzlast, etwa Produktoberfläche, Zielgruppe oder Zweck. Gilt für die gesamte Anfrage. |
hints | object (optional) | Kontextuelle Hinweise pro Schlüssel. Die Schlüssel entsprechen den data-Schlüsseln; die Werte sind Arrays aus Breadcrumb-Strings (z. B. { "nav.home": ["Navbar", "Home link"] }), die der Engine sagen, wo ein String verwendet wird, damit kurze oder mehrdeutige Texte korrekt eingeordnet werden. |
{
"engineId": "eng_abc123",
"sourceLocale": "en",
"targetLocale": "de",
"data": {
"greeting": "Hello, world!",
"cta": "Get started"
},
"hints": {
"cta": ["Landing page", "Primary button"]
}
}Antwort#
Die Antwort enthält den übersetzten Inhalt in derselben Struktur, die du gesendet hast, plus das Modell, das ihn erzeugt hat, und die Kosten pro Anfrage. Dieselben Schlüssel kommen zurück, in derselben Verschachtelung – dein Code kann die Übersetzung also direkt aus der bereits bekannten Struktur auslesen.
| Feld | Typ | Beschreibung |
|---|---|---|
sourceLocale | string | BCP-47-Quellsprache, aus der Anfrage übernommen. |
targetLocale | string | BCP-47-Zielsprache, aus der Anfrage übernommen. |
data | object | Übersetzte Schlüssel-Wert-Inhalte entsprechend der Eingabestruktur. |
model | string (optional) | Das LLM model, das diese Übersetzung erzeugt hat, formatiert als provider/model (z. B. anthropic/claude-sonnet-4.5). Daran erkennst du, welches Modell in deiner Fallback-Kette tatsächlich gelaufen ist. Das Feld fehlt, wenn kein LLM-Aufruf stattgefunden hat – siehe Hinweis unten. |
usage | object (optional) | Token-Anzahlen und Kosten pro Anfrage in USD. Fehlt, wenn kein LLM-Aufruf stattgefunden hat. |
Das Objekt usage schlüsselt die Kosten des Aufrufs auf, damit du Ausgaben ohne separate Abrechnungsabfrage zuordnen kannst:
| Feld | Typ | Beschreibung |
|---|---|---|
inputTokens | number | Gesamtzahl der verbrauchten Input-Token über alle Chunks hinweg. |
outputTokens | number | Gesamtzahl der erzeugten Output-Token über alle Chunks hinweg. |
cacheReadTokens | number | Input-Token, die aus dem Prompt-Cache des Anbieters bedient wurden, sofern das Modell sie meldet. |
cacheWriteTokens | number | Input-Token, die in den Prompt-Cache des Anbieters geschrieben wurden, sofern das Modell sie meldet. |
llmCost | number | Kosten des vorgelagerten LLM-Anbieters in USD. 0, wenn keine Kosten gemeldet wurden. |
localizationCost | number | Lingo.dev's Kosten pro Token in USD, berechnet aus outputTokens. |
cost | number | Gesamtkosten der Anfrage in 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
}
}Wenn `model` und `usage` fehlen
Wenn data leer ist – also keine Schlüssel zum Übersetzen vorhanden sind –, beendet der Endpunkt den Vorgang sofort, ohne ein LLM aufzurufen, und die Antwort enthält weder model noch usage. Das ist der einzige Fall, in dem die Kostenfelder fehlen, und der Grund ist einfach: Es sind keine Kosten entstanden. Nichts wurde übersetzt, also wurde auch nichts berechnet. Jede Anfrage, die eine Übersetzung auslöst, enthält beide Felder. Behandle sie in deinem Parser als optional, dann überrascht dich der Fall leerer Eingaben nicht.
Beispiele#
Derselbe Aufruf in fünf Sprachen. Der Übersicht halber sendet jedes Beispiel ein flaches Objekt; data akzeptiert aber auch verschachtelte Objekte und Arrays, und die Antwort kommt in genau der Struktur zurück, die du sendest.
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" }Was bei der Lokalisierung passiert#
Hinter einem einzelnen POST steckt eine ganze Abfolge von Schritten – und es lohnt sich, sie zu kennen. Denn genau sie sorgen dafür, dass das Ergebnis zum Rest deiner lokalisierten Inhalte passt und nicht wie ein einmaliger Modelltreffer wirkt. Wenn eine Anfrage den Endpunkt erreicht, wendet die Engine ihre vollständige Konfiguration der Reihe nach an:
Modellauswahl – Wählt das LLM model mit der höchsten Priorität aus, das zum Sprachpaar passt. Sprachspezifische Modelle haben Vorrang vor Wildcard-Modellen (
*). Falls das primäre Modell fehlschlägt, wechselt die Engine automatisch zum nächsthöher eingestuften Modell.Markenstimme – Lädt die Markenstimme für die Zielsprache und greift auf die Wildcard-Markenstimme zurück, falls keine sprachspezifische vorhanden ist.
Anweisungen – Lädt jede Anweisung, die zur Zielsprache passt, einschließlich Wildcard-Anweisungen.
Glossarsuche – Teilt Eingabewerte in durchsuchbare Chunks auf, erzeugt Embeddings und führt eine Vektorähnlichkeitssuche gegen das glossary der Engine aus. Treffer erzwingen exakte Übersetzungen oder markieren Begriffe als nicht übersetzbar, damit sie unverändert durchgereicht werden.
Generierung – Sendet den zusammengesetzten Prompt an das ausgewählte Modell und parst und validiert anschließend die JSON-Antwort.
Das ist dieselbe Pipeline aus Engine-Schritten, die die async API pro Job ausführt. Ob du Sync statt Async aufrufst, ändert nur die Art der Auslieferung, nicht die Erzeugung der Übersetzung – ein hier übersetzter String und derselbe String aus einem Async-Job landen also bei denselben Glossarbegriffen und derselben Stimme.
Der Modell-Fallback läuft automatisch, und die Antwort zeigt dir, welches Modell verwendet wurde
Falls das primäre Modell fehlschlägt, versucht die Engine das nächste Modell in der Rangfolge. Das geschieht transparent – die Struktur der Antwort bleibt identisch, unabhängig davon, welches Modell die Übersetzung erzeugt hat. Das einzige Signal für einen Fallback ist das Feld model in der Antwort: Lies es aus, wenn du genau wissen musst, welches Modell in deiner Kette eine bestimmte Anfrage verarbeitet hat.
