Supported languages
TrueIdiom translates between 35 languages. Every one of them works as a source or a target, so any pair in the table below is a pair you can submit. Codes are matched exactly — a code outside this table is refused before any work starts, not silently approximated.
The language table
| Language | Code | Counts as dense script |
|---|---|---|
| English | en |
No |
| Spanish | es |
No |
| French | fr |
No |
| French (Canada) | fr-CA |
No |
| German | de |
No |
| Italian | it |
No |
| Portuguese (Brazil) | pt-BR |
No |
| Portuguese (Portugal) | pt-PT |
No |
| Dutch | nl |
No |
| Chinese (Simplified) | zh-Hans |
Yes — billed at 3.5× |
| Chinese (Traditional) | zh-Hant |
Yes — billed at 3.5× |
| Japanese | ja |
Yes — billed at 3.5× |
| Korean | ko |
Yes — billed at 3.5× |
| Arabic | ar |
No |
| Russian | ru |
No |
| Hindi | hi |
Yes — billed at 3.5× |
| Turkish | tr |
No |
| Vietnamese | vi |
No |
| Thai | th |
Yes — billed at 3.5× |
| Indonesian | id |
No |
| Polish | pl |
No |
| Ukrainian | uk |
No |
| Czech | cs |
No |
| Romanian | ro |
No |
| Hungarian | hu |
No |
| Greek | el |
No |
| Swedish | sv |
No |
| Danish | da |
No |
| Norwegian (Bokmål) | nb |
No |
| Finnish | fi |
No |
| Malay | ms |
No |
| Persian | fa |
No |
| Urdu | ur |
No |
| Marathi | mr |
Yes — billed at 3.5× |
| Nepali | ne |
Yes — billed at 3.5× |
Chinese and Portuguese are split into their written variants rather than
offered as one code, because the two are not interchangeable in a document
anyone ships: zh-Hans and zh-Hant are different
scripts, and pt-BR and pt-PT differ in vocabulary
and register.
French is offered twice: fr is French as written in France, and
fr-CA is Canadian French. Québec French differs in vocabulary,
in typography and in how numbers and currency are written, so a text meant
for Canadian readers should be requested as fr-CA.
How codes are matched
Matching is case-insensitive on the exact code. Nothing else is accepted:
ENandenboth resolve toen.zh-hansresolves tozh-Hans.en-USandfr-FRare rejected — a regional code that is not in the table is not folded to its base language.- Bare
zhand bareptare rejected — the variant is the thing being chosen, so there is no default to fall back on.
en-US would
mean quietly deciding that a regional request is the same as the base
language; refusing it means the offered set is unambiguous and you find out
at request time, not in the delivered text.
Terminology and translation-memory uploads are the one place codes are read
more loosely, because the files come from other tools: each code is read as
the language in the table it stands for. A regional tag such as
en-US or en-GB is accepted there and applies to
en, and a Chinese tag by region counts by script
(zh-TW as zh-Hant, zh-CN as
zh-Hans). The variants stay apart there too: a
pt-PT glossary or memory never applies to a pt-BR
request, nor zh-Hans to zh-Hant, nor
fr to fr-CA or the other way round — while
fr-FR and fr-BE are read as fr. So bare
zh and pt are refused, as is a code whose language
is not in the table. A glossary CSV’s language columns may also name
the language instead of coding it (English,
Chinese (Simplified)).
Source and target
There is no restricted direction list. Every language in the table can be a source or a target, and each side of a pair is validated on its own.
target_langis required on every translation request.source_langis optional where an endpoint accepts it, and defaults toen. Send it explicitly whenever the source is not English.
Translation memory and terminology are held per language pair. A glossary or memory you build for English → French applies to that pair only; the reverse direction and every other pair start empty. Their capacity allowances are also counted per pair — see Limits & quotas.
What a rejected code returns
An unsupported code fails validation before any translation work begins, so
nothing is billed and nothing is stored. The response is 422
with a string detail beginning
unsupported language(s):, naming the codes exactly as you sent
them and then listing the supported set. (In the batch shape the same
rejection is reported inside the batch’s validation message, as
unsupported language followed by the code.)
HTTP/1.1 422 Unprocessable Entity
content-type: application/json
{"detail":"unsupported language(s): 'en-CA'. Supported: en, es, fr, fr-CA, de, it, pt-BR, pt-PT, nl, zh-Hans, zh-Hant, ja, ko, ar, ru, hi, tr, vi, th, id, pl, uk, cs, ro, hu, el, sv, da, nb, fi, ms, fa, ur, mr, ne"}
Branch on the type of detail, not on the status code: framework
parameter validation also returns 422, but with an
array detail. Both shapes are described on
Conventions & errors.
Dense-script billing weight
Chinese, Japanese, Korean, Thai, Hindi, Marathi and Nepali pack far more content into a character than Latin text does. Billing is denominated in source characters, so a pair involving one of those scripts counts 3.5 characters of allowance per source character.
- The weight applies when either side of the pair is a
dense script — into one (
en→ja) or out of one (ja→en). - It is applied once, never squared, when both sides are dense.
- Arabic, Russian, Turkish and Vietnamese are not weighted. They are alphabetic and sit close to Latin, and weighting them would overcharge.
The weighted count is what the monthly allowance check uses, so a request that would pass the allowance unweighted can still be refused — see Do Chinese, Japanese, Thai and Hindi count the same? and Dense-script character weighting in the API reference.
What's next
- Text translation API — where
source_langandtarget_langare sent, and what comes back. - Pricing & billing FAQ — how source characters and the dense-script weight turn into a monthly allowance.
- Getting started — run a first translation and watch the memory answer the second one.