How it works

The translation pipeline

Every request that hits AdaptiveAPI flows through the same five-stage pipeline. The job of each stage is to keep the wire format intact while moving human text in and out of the right language.

The five stages

  1. Tokenise. Wrap untranslatable spans (IDs, URLs, code, JSON inside JSON) in <adaptiveapi id="TAG_n"/> placeholders.
  2. Translate. Send the tokenised text to the configured translator.
  3. Verify. Confirm every placeholder reappears in the output exactly once. If not, fall back to source text and increment adaptiveapi_placeholder_integrity_failures_total.
  4. Detokenise. Replace placeholders with their original verbatim spans.
  5. Re-emit. Stitch back into the upstream wire format (chat-completion JSON, Anthropic message, MCP JSON-RPC, generic JSON, SSE event).

Streaming

The pipeline supports two streaming strategies. Pick per route, override per request with X-AdaptiveApi-Stream-Mode.

Sentence-boundary (default)

Buffer per choices[i].delta.content, flush at sentence boundaries once the buffer reaches 80 chars (configurable), translate the completed segment, re-emit a synthetic SSE delta. Clients see token-by-token UI with a modest per-sentence latency cost. Best balance of fidelity and perceived responsiveness.

Progressive

Translate smaller fragments more often, accepting some retranslation churn. Lower first-token latency at the cost of slightly less stable phrasing mid-sentence. Useful for chat UIs where the first words on screen matter.

Post-completion

Buffer the entire response, translate once, emit a single delta. Cheaper per-call when answers are short. Set stream_mode: "post" per route or pass X-AdaptiveApi-Stream-Mode: post.

Tool calls

OpenAI's tool_calls[*].function.arguments is a JSON string containing JSON. The pipeline parses the inner JSON, walks it with a key-aware denylist, translates the leaves that are actually human text, and re-serialises.

The default denylist:

Argument keys are preserved verbatim. tool_call_id and function.name never change. Extend per tenant via proxy rules:

{
  "toolArgKeys": ["internal_note", "customer_id"]
}

Glossaries

Glossaries are tenant-scoped and bind to a route or override per request with X-AdaptiveApi-Glossary. They map 1:1 to DeepL v3 multilingual glossaries on the wire, so terms behave identically whether you call DeepL directly or through AdaptiveAPI.

Two entry kinds:

Style rules

DeepL v3 style rules with up to ten 300-character custom instructions per rule, passed to DeepL on every translate call. Useful for things like:

PII redaction

The redactor runs early in the pipeline, before translation and before the upstream call. Built-in regex detectors cover email, Luhn-validated cards, US SSN, IBAN, IPv4, and phone numbers. Microsoft Presidio plugs in as a sidecar for higher recall (names, locations, organisations). Custom regex rules let you teach the redactor about your own identifiers.

Full coverage in PII detection.

Placeholder integrity

Each translation round trip has a hard invariant: every <adaptiveapi id="TAG_n"/> tag emitted into the source must reappear exactly once in the translator output. If it does not, the pipeline falls back to the source text, increments the adaptiveapi_placeholder_integrity_failures_total counter, and logs the failure. Alert above 0.5% over your observation window.