---
title: "Provider"
description: "Alle KI- und Maschinenübersetzungs-Provider, die verbatra unterstützt, mit ihren Optionen und API-Key-Variablen, dazu das Verhalten, das sie alle teilen."
type: "reference"
---
# Provider

Alle KI- und Maschinenübersetzungs-Provider, die verbatra unterstützt, mit ihren Optionen und API-Key-Variablen, dazu das Verhalten, das sie alle teilen.

Wähle einen Provider über die `id` im `provider`-Block deiner [Konfiguration](https://verbatra.kreitz-webdev.de/de/docs/config-file.md). Anthropic, OpenAI, Gemini, OpenCode und openai-compatible sind Sprachmodelle; DeepL, Google Cloud Translation und LibreTranslate sind Maschinenübersetzungsdienste; `none` schaltet maschinelle Übersetzung ab. Die Sprachabdeckung steht unter [Sprachen und Locales](https://verbatra.kreitz-webdev.de/de/docs/language-support.md), und was jeder Provider bekommt, unter [Datenverarbeitung und Datenschutz](https://verbatra.kreitz-webdev.de/de/docs/data-handling.md).

## Welchen soll ich nehmen? [#welchen-soll-ich-nehmen]

Jeder Provider funktioniert mit jedem Format und jedem Befehl, und ein späterer Wechsel heißt, eine `id` zu ändern.

| Wenn du willst | Nimm |
| --- | --- |
| Kostenlos, für ein kleines Projekt mit nicht vertraulichen Strings | **Gemini**: ein kostenloses API-Kontingent, dessen Anfragen Google außerhalb von EWR, Schweiz und Vereinigtem Königreich von Menschen prüfen lassen darf ([Bedingungen](https://verbatra.kreitz-webdev.de/de/docs/data-handling.md#aufbewahrung-und-auftragsverarbeitung-beim-anbieter)). |
| Die beste Qualität für eine Produktions-App | **Anthropic** oder **OpenAI**, beide bezahlt. |
| Hohes Volumen, ein natives Glossar, kein LLM | **DeepL**, kostenloses oder bezahltes Kontingent. |
| Die breiteste Abdeckung mit einem API-Schlüssel auf Google Cloud | **Google Cloud Translation** (Basic, v2). |
| Offline, kostenfrei, nichts verlässt dein Netzwerk | **openai-compatible** mit LM Studio, Ollama oder vLLM. |
| Kein Sprachmodell, aber selbst gehostet | **LibreTranslate** auf deinem eigenen Server. |
| Gar keine maschinelle Übersetzung | **none**: nur Translation Memory und Menschen. |

## Keys kommen aus der Umgebung [#keys-kommen-aus-der-umgebung]

verbatra liest nie einen Key aus der Konfiguration. Jeder gehostete Provider liest eine Variable:

| Provider-Id | Umgebungsvariable |
| --- | --- |
| `anthropic` | `ANTHROPIC_API_KEY` |
| `openai` | `OPENAI_API_KEY` |
| `gemini` | `GEMINI_API_KEY` |
| `deepl` | `DEEPL_API_KEY` |
| `google-translate` | `GOOGLE_TRANSLATE_API_KEY` |
| `opencode` | `OPENCODE_API_KEY` |

Setze sie in `.env` (das `verbatra init` in `.gitignore` einträgt), in deiner Shell oder in deinem CI-Secret-Store, und committe sie nie. Eine ungesetzte oder leere Variable scheitert mit [`MISSING_API_KEY`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#missing_api_key), das die Variable nennt, aber nie einen Wert. `openai-compatible` und `libretranslate` brauchen meist keinen Key.

## Anthropic [#anthropic]

```ts title="verbatra.config.ts"
provider: {
  id: "anthropic",
  options: {
    model: "claude-sonnet-4-6", // example model id
    maxTokens: 4096,
  },
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `model` | String | erforderlich | Die Modell-Id. |
| `maxTokens` | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort ([Limits](#ausgabe-token-limits)); hat nichts mit dem Top-Level-Budget zu tun. |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Begrenzt jeden Anfrageversuch ([Anfrage-Timeout](#anfrage-timeout)). |
| `localeMap` | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale ([Locale-Codes](#an-den-provider-gesendete-locale-codes)). |

Liest `ANTHROPIC_API_KEY`.

## OpenAI [#openai]

```ts title="verbatra.config.ts"
provider: {
  id: "openai",
  options: {
    model: "gpt-5.4-mini", // example model id
    maxOutputTokens: 4096,
  },
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `model` | String | erforderlich | Die Modell-Id. |
| `maxOutputTokens` | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Begrenzt jeden Anfrageversuch. |
| `localeMap` | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |

Liest `OPENAI_API_KEY`.

## Gemini [#gemini]

```ts title="verbatra.config.ts"
provider: {
  id: "gemini",
  options: {
    model: "gemini-2.5-flash", // example model id
    maxOutputTokens: 4096,
  },
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `model` | String | erforderlich | Die Modell-Id. |
| `maxOutputTokens` | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Begrenzt jeden Anfrageversuch. |
| `localeMap` | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |

Liest `GEMINI_API_KEY`.

<Callout title="Das kostenlose Kontingent und seine Limits">
Ein Key aus dem [Google AI Studio](https://aistudio.google.com/apikey) braucht keine Zahlungsdaten, aber seine Grenzen pro Minute und pro Tag können einen ersten Lauf über viele Locales stoppen: Übersetze eine Locale nach der anderen oder senke `maxBatchSize` und starte erneut, um den Rest aufzugreifen.
</Callout>

## DeepL [#deepl]

```ts title="verbatra.config.ts"
provider: {
  id: "deepl",
  options: {
    glossaryId: "<your-glossary-id>",
  },
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `glossaryId` | String | keine | Ein Glossar, das du in DeepL angelegt hast, nativ angewendet. |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Die Mindestwartezeit pro Versuch, bis zu sechs Versuche. |
| `localeMap` | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |

Liest `DEEPL_API_KEY`; `options` darf `{}` sein. DeepL hat kein Modell und kein Ausgabe-Token-Limit und stuft mit einem Hinweis herab, statt fehlzuschlagen:

- **Platzhalter** reisen als nummerierte Markierungen in einem ignorierten Tag (`Hello {{name}}` als `Hello <x>{0}</x>`) und werden wieder eingesetzt. `PLACEHOLDER_UNSUPPORTED` hält einen Wert mit nicht wörtlichem Platzhalter oder mit `<`, `>`, `{` oder `}` im übrigen Text zurück, und ein Ergebnis mit verlorener, wiederholter, geänderter oder bloßer Markierung, unbekannter Entity oder fremdem Tag. Reines Markup geht als Klartext hinaus. <AvailableFrom version="0.12.0" />
- **Tonfall** wird auf Formalität abgebildet (`formal` formeller, `informal` informeller, `neutral` weggelassen). Ein Key aus dem kostenlosen Kontingent sendet gar keine Formalität und meldet `FORMALITY_DOWNGRADED`. Ein bezahlter Key fragt mit `prefer_more` oder `prefer_less` an, sodass eine Sprache ohne Formalität wie Schwedisch mit demselben Hinweis zurückfällt statt zu scheitern. Das [Glossar](#tonfall-und-glossar-über-die-provider-hinweg) wird nicht angewendet.

<AvailableFrom version="0.12.0" />

verbatra liefert DeepLs datierte [Sprachtabelle](https://developers.deepl.com/docs/getting-started/supported-languages) mit und lehnt eine nicht aufgeführte Sprache mit `LOCALE_UNSUPPORTED_BY_PROVIDER` ab, bevor etwas ausgegeben wird. Eine `glossaryId` funktioniert nur, wenn beide Sprachen auf DeepLs Glossarliste stehen (etwa `DE`, `EN`, `FR`, `JA`, `ZH`).

## Google Cloud Translation [#google-cloud-translation]

<AvailableFrom version="0.10.0" />

```ts title="verbatra.config.ts"
provider: {
  id: "google-translate",
  options: {},
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Begrenzt den ganzen Aufruf (keine Wiederholungen). |
| `localeMap` | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |

Liest `GOOGLE_TRANSLATE_API_KEY`, einen API-Schlüssel für ein Google-Cloud-Projekt mit aktivierter Cloud Translation API. Nur Basic (v2) funktioniert: Advanced (v3) braucht einen Service-Account.

- **Platzhalter** werden wie bei DeepL maskiert, in `<span translate="no">`; Zeilenumbrüche, Tabs und doppelte Leerzeichen werden ebenfalls zurückgehalten. <AvailableFrom version="0.12.0" />
- **Codes.** Jeder gesendete Code wird vor jedem Aufruf als wohlgeformtes BCP 47 geprüft (`en_US` scheitert mit `INVALID_REQUEST`). Regionale Codes sind erlaubt; ein Paar, das Google ablehnt, scheitert mit `INVALID_REQUEST` von der API.

<AvailableFrom version="0.12.0" />

verbatra liefert Googles datierte [Sprachtabelle](https://docs.cloud.google.com/translate/docs/languages) mit und lehnt eine nicht aufgeführte Sprache ab, bevor etwas ausgegeben wird. Ein regionaler Code, dessen Sprache nur als Ganzes aufgeführt ist, etwa `de-AT`, wird mit einer Warnung so gesendet, wie er geschrieben ist.

## OpenCode [#opencode]

<AvailableFrom version="0.12.0" />

Hier funktionieren nur Modelle von [OpenCode Zen](https://opencode.ai/docs/zen/), die über `/chat/completions` laufen (die Modelltabelle nennt den Endpunkt jedes Modells). OpenCode behält Go und die kostenlosen Zen-Modelle seinen eigenen Clients vor.

```ts title="verbatra.config.ts"
provider: {
  id: "opencode",
  options: {
    model: "glm-5.3", // example: a Zen model served over Chat Completions
    maxOutputTokens: 4096,
  },
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `model` | String | erforderlich | Die Modell-Id. |
| `maxOutputTokens` | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Begrenzt jeden Anfrageversuch. |
| `localeMap` | Map von Locale zu Code | keiner | Überschreibt den je Locale gesendeten Code. |

Fester Endpunkt, kein `baseUrl`. Liest `OPENCODE_API_KEY`.

## openai-compatible [#openai-compatible]

Jeder Server, der die OpenAI-Chat-Completions-API spricht: LM Studio, Ollama, vLLM oder eine gehostete API.

Der Server muss Chat Completions unter `<baseUrl>/chat/completions` mit striktem JSON-Schema-Output bereitstellen. Gateways, die nur ihre eigenen Client-Apps bedienen, funktionieren nicht.

```ts title="verbatra.config.ts"
provider: {
  id: "openai-compatible",
  options: {
    baseUrl: "http://192.168.178.74:1234/v1",
    model: "qwen2.5-14b-instruct", // example: whatever your server exposes
    maxOutputTokens: 1024,
  },
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `baseUrl` | `http`- oder `https`-URL | erforderlich | Die API-Wurzel, meist mit `/v1` am Ende. Eine URL, die auf `/chat/completions` oder `/completions` endet, wird abgelehnt; eine ohne `/v1` besteht die Validierung und scheitert erst bei der Anfrage. |
| `model` | String | erforderlich | Das Modell, das dein Server anbietet. |
| `maxOutputTokens` | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
| `apiKeyEnvVar` | Variablenname | keine | Die Variable mit dem Key dieses Servers. |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Begrenzt jeden Anfrageversuch. |
| `localeMap` | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |

Für eine gehostete API wie Mistral:

```ts title="verbatra.config.ts"
provider: {
  id: "openai-compatible",
  options: {
    baseUrl: "https://api.mistral.ai/v1",
    model: "mistral-large-latest", // example: check Mistral's current model list
    maxOutputTokens: 4096,
    apiKeyEnvVar: "MISTRAL_API_KEY",
  },
}
```

Die Antwort nutzt dasselbe strikte Schema wie `openai`; das erste balancierte JSON-Objekt wird aus umgebender Prosa oder einem Code-Fence genommen und validiert. `verbatra init --provider openai-compatible --base-url <url> --model <name>` schreibt diesen Block ([init](https://verbatra.kreitz-webdev.de/de/docs/cli/init.md#provider)), und `--api-key-env-var <NAME>` ergänzt den Namen der Variable.

### Keys sind optional [#keys-sind-optional]

Der Key wird der Reihe nach aufgelöst:

1. **`apiKeyEnvVar`**: Wenn gesetzt, muss seine Variable einen Key enthalten, sonst scheitert der Lauf mit `MISSING_API_KEY`.
2. **`OPENAI_COMPATIBLE_API_KEY`**: wird verwendet, wenn sie gesetzt und nicht leer ist.
3. **`"local"`**: ein fester, nicht geheimer Platzhalter, der einen Server ohne Key funktionieren lässt.

`apiKeyEnvVar` kann nicht die Variable eines gehosteten Providers nennen, und der Client liest nie `OPENAI_API_KEY`, ein gehosteter Key erreicht also nie eine eigene `baseUrl`.

<Callout type="warn" title="Ein echter Key über Klartext-http reist unverschlüsselt">
Mit einem Key und einer `http://`-URL zu einem Nicht-Loopback-Host geht der Key unverschlüsselt und ohne Warnung durch dein Netzwerk, verwende also `https://` für einen Server, der einen Key braucht.
</Callout>

### Ein lokales Modell wählen [#ein-lokales-modell-wählen]

Bevorzuge ein instruktionsoptimiertes, mehrsprachiges Modell ohne Reasoning, so groß, wie deine Hardware es gut ausführt, etwa `qwen2.5-14b-instruct`. Reasoning-Modelle und stark quantisierte Builds neigen dazu, die Antwort zu verpacken oder abzuschneiden, was als `INVALID_RESPONSE` oder `OUTPUT_TRUNCATED` scheitert.

## LibreTranslate [#libretranslate]

<AvailableFrom version="0.12.0" />

Ein selbst gehosteter [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate)-Server (Argos Translate, kein Sprachmodell). verbatra ruft nur seine HTTP-API auf, die AGPL-3.0-Lizenz des Servers erstreckt sich also nicht auf dein Projekt.

```ts title="verbatra.config.ts"
provider: {
  id: "libretranslate",
  options: {
    baseUrl: "http://localhost:5000",
  },
}
```

| Option | Typ | Default | Wirkung |
| --- | --- | --- | --- |
| `baseUrl` | `http`- oder `https`-URL | erforderlich | Die API-Wurzel, ohne `/translate`. |
| `requestTimeoutMs` | positive Ganzzahl | `120000` | Begrenzt den ganzen Aufruf (keine Wiederholungen). |
| `localeMap` | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |

Seine Sprachen sind die auf deinem Server installierten Modelle:

```bash
docker run -p 5000:5000 libretranslate/libretranslate --load-only en,de,fr
```

- **Key.** `LIBRETRANSLATE_API_KEY` wird nur als `api_key` gesendet, wenn sie gesetzt ist. Ein mit `--api-keys` gestarteter Server lässt den Lauf mit `MISSING_API_KEY` scheitern, wenn sie nicht gesetzt ist, und mit `AUTH_FAILED`, wenn er sie ablehnt.
- **Platzhalter** werden wie bei DeepL maskiert, als bloße `{0}`-Markierungen; Markup bleibt erhalten, daher zählen nur geschweifte Klammern neben einem Platzhalter.
- **Markup.** Ein Wert mit HTML-artigen Tags wird im `html`-Format gesendet: Der Text in den Tags wird übersetzt, die Tags bleiben (eine Formulierung über ein Tag hinweg kann leiden), und veränderte Tags werden abgelehnt.
- **Sprachprüfung.** Jedes Ziel warnt bei jedem Lauf `LOCALE_UNVERIFIED_BY_PROVIDER`; `verbatra doctor --locales --live` prüft sie gegen den Server.

`verbatra init --provider libretranslate --base-url <url>` schreibt diesen Block.

## none [#none]

<AvailableFrom version="0.12.0" />

Schaltet maschinelle Übersetzung per Richtlinie ab, für eine Regel, die verbietet, Strings an irgendeinen Dienst zu senden.

```ts title="verbatra.config.ts"
provider: { id: "none" }
```

`options` darf fehlen oder `{}` sein. Es wird kein Provider erzeugt, kein Key gelesen und keine Anfrage gestellt; was jeder Befehl stattdessen tut, steht unter [Ohne maschinelle Übersetzung arbeiten](https://verbatra.kreitz-webdev.de/de/docs/human-only-workflow.md).

## Tonfall und Glossar über die Provider hinweg [#tonfall-und-glossar-über-die-provider-hinweg]

Eine Anfrage enthält nur die Glossarbegriffe ihrer Ziel-Locale, und jede Ausgabe wird gegen sie geprüft.

| Provider | `tone` | `glossary` |
| --- | --- | --- |
| Anthropic, OpenAI, Gemini, OpenCode, openai-compatible | gesendet und eingehalten | Übersetzungen, verbotene Wiedergaben, `doNotTranslate`-Begriffe und Notizen als bindende Daten gesendet |
| DeepL | auf Formalität abgebildet | `GLOSSARY_IGNORED`; nur `glossaryId` wird angewendet |
| Google Cloud Translation, LibreTranslate | `FORMALITY_DOWNGRADED` bei `formal` oder `informal` | `GLOSSARY_IGNORED` |

## Verhalten, das jeder Provider teilt [#verhalten-das-jeder-provider-teilt]

### Batching [#batching]

Die Arbeit einer Locale geht in sequenziellen Sub-Batches von höchstens [`maxBatchSize`](https://verbatra.kreitz-webdev.de/de/docs/config-file.md#maxbatchsize) Einträgen hinaus. Ein fehlgeschlagener Sub-Batch wird zurückgehalten und beim nächsten Lauf erneut versucht, während der Rest weiter vorankommt. DeepL und Google Cloud Translation teilen einen Sub-Batch zusätzlich auf, damit er in ihre eigenen Anfragegrenzen passt.

### Wiederholungen [#wiederholungen]

Rate-Limits und Serverfehler werden mit Backoff wiederholt, bei OpenAI, OpenCode, openai-compatible, Anthropic und DeepL vom Client und bei Gemini von verbatra. Google Cloud Translation und LibreTranslate wiederholen nicht. Gemini hält eine genannte Wartezeit von bis zu 5 Sekunden ein und lässt eine längere, etwa bei erschöpftem Tageskontingent, sofort mit `RATE_LIMITED` scheitern, das die Wartezeit nennt.

### Anfrage-Timeout [#anfrage-timeout]

`requestTimeoutMs` (Default `120000` ms) verhindert, dass ein Server, der nie antwortet, einen Lauf blockiert und die Schreibsperre einer Locale hält. Erhöhe ihn für ein langsames lokales Modell oder eine große `maxBatchSize`.

```ts title="verbatra.config.ts"
provider: {
  id: "openai-compatible",
  options: {
    baseUrl: "http://192.168.178.74:1234/v1",
    model: "qwen2.5-14b-instruct",
    maxOutputTokens: 1024,
    requestTimeoutMs: 300000, // 5 minutes
  },
}
```

- **Pro Versuch.** Jede [Wiederholung](#wiederholungen) bekommt den vollen Timeout. Die LLM-Provider wiederholen auch einen Versuch im Timeout, und alle außer Gemini einen Verbindungsfehler, ein hängender Server braucht also bis zu drei Timeouts plus Backoff.
- **Der Fehler nennt die Ursache.** `TIMEOUT` heißt, dass ein Versuch rechtzeitig keine Antwort bekommen hat; wiederholt abgelehnte Verbindungen scheitern als `PROVIDER_ERROR`.
- **DeepL** kann eine laufende Anfrage nicht abbrechen, ein unterbrochener Lauf lässt sie also bei DeepL zu Ende laufen.

### An den Provider gesendete Locale-Codes [#an-den-provider-gesendete-locale-codes]

<AvailableFrom version="0.12.0" />

Dateien, Lock-Datei und Translation Memory verwenden immer die Codes deiner Konfiguration. Nur die Anfrage wird in das übersetzt, was der Provider erwartet:

| Provider | Quell-Locale | Ziel-Locale |
| --- | --- | --- |
| DeepL | Nur die Sprache: `en-US` als `EN`, `zh-Hant-TW` als `ZH`. | `zh-Hant`, `zh-TW`, `zh-HK`, `zh-MO` als `ZH-HANT`; `zh-Hans`, `zh-CN`, `zh-SG` als `ZH-HANS`. DeepL-Varianten bleiben (`EN-GB`, `EN-US`, `PT-BR`, `PT-PT`, `ES-419`, `FR-CA`, `FR-FR`, `DE-CH`, `DE-DE`). Spanisch mit einer lateinamerikanischen oder karibischen Region (`MX`, `AR`, `CO`, `CL`, `PE`, `VE`, `EC`, `GT`, `CU`, `BO`, `DO`, `HN`, `PY`, `SV`, `NI`, `CR`, `PA`, `UY`, `PR`, `US`, `419`) als `ES-419`. Andere Regionen und Schriften fallen weg: `de-AT` als `DE`. |
| Google Cloud Translation | `zh-Hant` (`zh-HK`, `zh-MO`) als `zh-TW`, `zh-Hans` (`zh-SG`) als `zh-CN`, `nb` als `no`; alles andere so, wie es geschrieben ist. | Wie bei der Quelle. |
| LibreTranslate | Nur die Sprache (`de-AT` als `de`), außer dass `pt-BR` bleibt und Chinesisch als `zh-Hans` oder `zh-Hant` geht (`zh-TW` als `zh-Hant`). | Wie bei der Quelle. |
| Anthropic, OpenAI, Gemini, OpenCode, openai-compatible | So, wie er geschrieben ist. | Wie bei der Quelle. |

Ein LLM bekommt zusätzlich die [Namen von Sprache, Schrift und Region](https://verbatra.kreitz-webdev.de/de/docs/translation-safety.md#namen-von-sprache-schrift-und-region). DeepL hat kein allgemeines Englisch oder Portugiesisch als Ziel, ein Ziel, das am Ende ein bloßes `en` oder `pt` ist (etwa `en-AU`), wird deshalb vor dem Lauf abgelehnt: Bilde es auf `EN-GB`, `EN-US`, `PT-BR` oder `PT-PT` ab.

`localeMap` überschreibt den Code pro Locale:

```ts title="verbatra.config.ts"
provider: {
  id: "deepl",
  options: {
    localeMap: {
      "en-AU": "EN-GB",
      "fr-BE": "FR-FR",
    },
  },
}
```

- **Keys** müssen `sourceLocale` oder eine Ziel-Locale wie konfiguriert sein, sonst scheitert die Konfiguration mit `CONFIG_INVALID`. Die Zuordnung gehört unter `options`, bei jedem Provider außer `none`.
- **Werte** sind nicht leere Strings mit höchstens 64 Zeichen und werden unverändert gesendet: an einen Maschinenübersetzungs-Provider als Sprachcode, an ein LLM anstelle des Codes (`"pt-BR (Brazilian Portuguese)"` funktioniert), dessen Sprachnamen trotzdem aus dem Key kommen. Ein bloßes `EN` oder `PT` für DeepL scheitert mit `INVALID_REQUEST`; ein Wert, den der Provider ablehnt, lässt seinen Sub-Batch scheitern.
- **Wirkung auf das Translation Memory.** Nur neue und geänderte Strings gehen mit einem neuen Code hinaus. Ein nicht leeres `localeMap` ist Teil des Fingerprints im [Translation Memory](https://verbatra.kreitz-webdev.de/de/docs/the-cache.md), eine Änderung beginnt also einen eigenen Bereich.

### Die Sprachunterstützung eines Providers prüfen [#die-sprachunterstützung-eines-providers-prüfen]

<AvailableFrom version="0.12.0" />

Jede konfigurierte Locale wird beurteilt, bevor etwas ausgegeben wird:

| Provider | Beurteilt gegen | Vor dem Lauf abgelehnt | Gewarnt bei |
| --- | --- | --- | --- |
| DeepL | Seine mitgelieferte Sprachtabelle, mit Glossar- und Formalitätsunterstützung je Sprache | Eine nicht aufgeführte Quell- oder Zielsprache | Einem Glossar für ein Paar außerhalb der Glossarsprachen, einem Tonfall ohne Formalität, einem nur teilweise aufgeführten Code |
| Google Cloud Translation | Seine mitgelieferte Sprachtabelle | Eine nicht aufgeführte Sprache | Jedem Glossar, einem Tonfall `formal` oder `informal`, einem regionalen Code, der nur als Sprache aufgeführt ist |
| LibreTranslate | Nichts vor einem Lauf; mit `doctor --live` das `/languages` des Servers | Nie | Jeder Ziel-Locale bei jedem Lauf, jedem Glossar, einem Tonfall `formal` oder `informal` |
| Anthropic, OpenAI, Gemini, OpenCode, openai-compatible | Nichts: Ein LLM akzeptiert jede Sprache | Nie | Einer Sprache außerhalb der [gut getesteten Liste](https://verbatra.kreitz-webdev.de/de/docs/language-support.md#unterstützung-vor-einem-lauf-prüfen) |
| none | Entfällt | Nie | Nie |

Eine nicht unterstützte Locale wird mit [`LOCALE_UNSUPPORTED_BY_PROVIDER`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#locale_unsupported_by_provider) (Exit `2`) abgelehnt, bevor ein Provider erzeugt wird; eine Warnung lehnt nie ab und erscheint als [Hinweis](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#sdk-notice-codes). [`verbatra doctor`](https://verbatra.kreitz-webdev.de/de/docs/cli/doctor.md#locale-unterstützung) meldet jedes Urteil, und sein Flag `--live` prüft gegen die aktuelle Liste des Providers, aber `translate` verwendet immer die mitgelieferte Tabelle. Für eine seitdem ergänzte Sprache bilde die Locale in `localeMap` ab: Ein expliziter Code wird mit einer Warnung gesendet, nicht abgelehnt.

### Strukturierte Fehler [#strukturierte-fehler]

Ein Provider-Fehlschlag erscheint als [strukturierter, geheimnisfreier Fehler](https://verbatra.kreitz-webdev.de/de/docs/translation-safety.md#fehler-geben-nichts-preis), der nur seinen eigenen Sub-Batch betrifft. Ein `PROVIDER_ERROR` nennt nur Host und Port einer `baseUrl` von openai-compatible oder LibreTranslate, und bei Google nur `translation.googleapis.com`, nie den Query-String mit seinem Key.

### Ausgabe-Token-Limits [#ausgabe-token-limits]

Die LLM-Provider begrenzen die Tokens jeder Antwort; ein Modell, das an der Grenze stoppt, erzeugt [`OUTPUT_TRUNCATED`](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#output_truncated). verbatra teilt einen abgeschnittenen Sub-Batch in Hälften, bis hinunter zu einem Eintrag, und hält nur einen Eintrag zurück, der weiterhin überläuft. Um das dauerhaft zu beheben, senke `maxBatchSize` oder erhöhe `maxTokens` (Anthropic) beziehungsweise `maxOutputTokens`. Ein Reasoning-Modell verbraucht verborgene Reasoning-Tokens aus demselben Budget, gib ihm also reichlich Spielraum.

### Review-Flags [#review-flags]

Eine verdächtige Übersetzung wird bei jedem Provider zum Review markiert, nicht abgelehnt. Siehe [Review-Gründe](https://verbatra.kreitz-webdev.de/de/docs/error-codes.md#review-reason-codes) und [In Studio prüfen](https://verbatra.kreitz-webdev.de/de/docs/review-in-studio.md).
