Style rules & customization
Translation gets the words right. Style rules get everything else right. Number formats, date formats, formality, quote styles, currency, and domain terminology all bend to the locale your user actually expects. The model keeps thinking in one shape. Your user keeps reading their own.
The case for style rules
A user types Was kostet das Produkt 1.250,00 €? in a German
checkout flow. Their bank statement shows 1.250,00 €. Their
spreadsheets use commas as decimal separators and dots as thousands
separators. That is what they expect to see, end to end.
Now your model is trained on US-format text. It thinks the literal string
1.250,00 means "1 point 250 comma 00." It will not arithmetic
that correctly. It might treat 1.250 as "1250" or as "1.25"
depending on context. The user gets a confused answer. You log a bug.
Style rules fix this without retraining anyone. The LLM sees
1,250.00. It computes correctly. The reply comes back with
every numeric span re-formatted to 1.250,00 € for the user.
Same for dates, currency symbols, formality, terminology.
What a style rule contains
A style rule is bound to a route or referenced per request via X-AdaptiveApi-Style-Rule. It has three parts:
- Locale formatting. Number, date, currency, and quote conventions for the target language.
- Tone preset. Formality (formal, informal), register (technical, marketing, casual), and audience.
- Custom instructions. Up to ten 300-character natural-language directives passed to DeepL on every translate call.
Number formats
The most common bug source. Locale presets cover the obvious cases. Custom instructions cover the rest.
| Locale | Decimal separator | Thousands separator | Example |
|---|---|---|---|
| en-US | . | , | 1,234,567.89 |
| de-DE | , | . | 1.234.567,89 |
| fr-FR | , | (space) | 1 234 567,89 |
| en-IN | . | , (lakh) | 12,34,567.89 |
The pipeline normalises numbers to the source locale before the model sees them, then re-formats them to the target locale on the way back. Numeric spans inside placeholders (which the translator does not modify) are converted explicitly.
Date and time formats
Dates are even more locale-bound than numbers. The model gets ISO. The user gets their own.
| Locale | Short date | Long date |
|---|---|---|
| en-US | 04/27/2026 | April 27, 2026 |
| en-GB | 27/04/2026 | 27 April 2026 |
| de-DE | 27.04.2026 | 27. April 2026 |
| ja-JP | 2026/04/27 | 2026年4月27日 |
Times follow the same rule. 12-hour with am/pm in en-US, 24-hour in most of
the rest of the world. The style rule's timeFormat can be
locale-default, 12h, or 24h.
Currency formats
Symbol position, spacing, and minor-unit grouping all vary. The pipeline normalises to ISO 4217 amounts on the way in and re-formats per locale on the way out.
| Locale | EUR | USD | JPY |
|---|---|---|---|
| en-US | €1,250.00 | $1,250.00 | ¥1,250 |
| de-DE | 1.250,00 € | 1.250,00 $ | 1.250 ¥ |
| fr-FR | 1 250,00 € | 1 250,00 $ | 1 250 ¥ |
Formality
Languages with grammatical formality (German, French, Spanish, Italian, Dutch, Polish, Japanese, Korean) need an explicit tone choice.
- Formal. Sie / vous / usted / Lei / Sie. Default for B2B, banking, healthcare, legal.
- Informal. du / tu / tú / tu / je. Default for consumer apps, gaming, social.
- Locale default. Pick the convention common to the locale and audience.
Set formality: "formal" on the style rule, or override per
request with X-AdaptiveApi-Formality: informal. DeepL maps
this to its native formality flag where supported, and falls back to a
custom instruction otherwise.
Quote styles and punctuation
Easy to overlook, hard to unsee once you do.
| Locale | Quotes | Apostrophe |
|---|---|---|
| en-US | "text" | ' |
| de-DE | „text" | ' |
| fr-FR | « text » | ' |
| ja-JP | 「text」 | ' |
Domain terminology
Style rules pair naturally with glossaries. A glossary handles the
one-word-to-one-word case (always render checkout as
Kasse). Style rules handle the broader patterns
(always use formal address; render technical names in English; expand
acronyms on first use).
See Translation pipeline for the glossary mechanics.
Custom instructions
Up to ten 300-character natural-language instructions per style rule. They are passed to DeepL on every translate call (DeepL v3 supports per-call style instructions natively). Useful for things that do not map cleanly to preset switches.
- "Translate marketing copy idiomatically rather than literally."
- "Always use the formal Sie form, even for short responses."
- "Keep code snippets, function names, and CLI flags in English."
- "Render percentages with a thin space before the percent sign (12 %)."
- "For currency, use the ISO code (EUR) instead of the symbol (€)."
- "Address the reader in the second person plural where the source uses 'we'."
Worked example: a German B2B SaaS app
You run a financial-reporting SaaS that takes user questions and returns analyses. Most users are German finance teams.
{
"id": "s_finance_de",
"name": "Finance, formal German",
"locale": {
"target": "de-DE",
"numberFormat": "de-DE",
"dateFormat": "de-DE",
"timeFormat": "24h",
"currency": { "defaultCode": "EUR", "format": "de-DE" },
"quoteStyle": "de"
},
"tone": { "formality": "formal", "register": "professional" },
"customInstructions": [
"Always address the reader formally (Sie).",
"Render financial figures with a non-breaking space between value and currency.",
"Keep ticker symbols and ISIN codes in English without translation.",
"Translate technical accounting terms using HGB-aligned vocabulary where applicable."
]
}
Bind it to a route, or override per request:
curl -X POST "https://adaptiveapi.example.com/v1/rt_yourtenant_xxxxx/chat/completions" \
-H "Authorization: Bearer sk-..." \
-H "X-AdaptiveApi-Target-Lang: de" \
-H "X-AdaptiveApi-Style-Rule: s_finance_de" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "Wie viel Umsatz haben wir im Q1 mit 1.250 Kunden gemacht?"}
]
}'
What happens on the wire:
- The user query is normalised.
1.250becomes1,250for the model. - The system prompt context (formality, register) is injected for the translation step, not the model step.
- The model thinks in English, computes with the US-format numbers, and answers.
- The reply comes back. Numeric spans get re-formatted to
1.250. Currency to1.250,00 €. Dates to27.04.2026. - Sie, not du. ISIN codes left alone. HGB-aligned terms used where possible.
Worked example: a global gaming app
Same product, different audience. Style rule for casual French players, heavy on idiomatic translation.
{
"id": "s_gaming_fr",
"name": "Gaming, casual French",
"locale": {
"target": "fr-FR",
"numberFormat": "fr-FR",
"dateFormat": "fr-FR",
"quoteStyle": "fr"
},
"tone": { "formality": "informal", "register": "casual" },
"customInstructions": [
"Use the informal tu form throughout.",
"Translate idiomatically. Slang is welcome where the source is casual.",
"Keep game-mechanics terms (XP, HP, loot, raid) in English."
]
}
Per-route vs per-request
Bind a default style rule to the route. Override per request with the
X-AdaptiveApi-Style-Rule header. Useful when one client
surface (admin console) needs a different tone than another (chatbot)
while sharing the same route token and translator backend.
Tip. Style rules are the right place for "this LLM keeps getting the format wrong" bugs. Adding a custom instruction is faster than re-prompting the model, and the rule applies to every call without further code changes.