Home/Resolving/Resolution Ladder ENУКРРУС API Reference (ReDoc) ↗

Resolution Ladder

The exact order /v1/resolve runs in, and what each match value means.

Resolution is two lookups and a ladder. All of it runs against an in-memory snapshot of the catalog — no query per request.

Step 1 — find the provider

The value you sent is normalised and matched against provider codes, then provider aliases. No match is provider_not_found (404).

Step 2 — find the language

The value you sent is normalised (see Aliases and Normalisation) and matched against canonical codes first, then aliases. Canonical codes are registered first and never overwritten, so an alias can never shadow a real language code.

If nothing matches exactly, the code is progressively shortened:

zh-Hant-HK  →  zh-hant  →  zh-hk  →  zh

Both qualifier axes appear because providers disagree about which one matters — DeepL wants zh-Hans, Papago wants zh-CN. A tag with an unknown qualifier degrades to the language it qualifies rather than 404ing: de-AT-1996 resolves to de-AT, reported in matched_alias.

Still nothing? language_not_found (404).

Step 3 — the ladder

Now that both are known, in order:

1. exact — an explicit row for this pair

Someone configured it. Return its code.

{ "provider": "deepl_api", "language": "zh-CN", "code": "ZH-HANS", "match": "exact" }

If that row says is_supported: false, stop here: supported: false, code: null. The pair is known not to work and the request should not be attempted.

2. variant — a less specific tag of the same language has a row

No row for ar-EG, but one for ar? Use it, and name it in via_language. Baidu spells Arabic ara, so this is a code no amount of shortening the tag would have produced.

{ "provider": "baidu_translate", "language": "ar-EG", "code": "ara", "match": "variant", "via_language": "ar" }

If the row it finds says is_supported: false, that ends the ladder as well, and via_language names the language whose row refused it. The most specific statement wins: a provider that does not translate Traditional Chinese cannot translate zh-Hant-HK either, and stepping over the refusal to reach zh would answer with a Simplified code.

3. canonical — the language carries no qualifier

A base language needs no mapping: its own code is the answer.

{ "language": "uk", "code": "uk", "match": "canonical" }

A base language with no row resolves to itself

Configuration only ever needs to say something about regional languages — the ones providers disagree about. Where a provider's own documented language list has been recorded, its base languages carry rows too: an explicit code where that provider spells the language differently, and an explicit supported: false where it does not translate the language at all. Everywhere else the language's own code is the answer, and no row is needed.

4. The provider's fallback policy

Only reached for a regional language with nothing configured. See Fallback Policies for how to choose one.

Policy Result match
base_language the base language's code — pt-BR → pt base_language
passthrough the canonical code unchanged passthrough
strict supported: false, code: null —

Every provider currently uses base_language. See Fallback Policies for why strict is not a default.

Reading match as a caller

match Trust level What to do
exact Configured deliberately Use it.
variant Configured for a near tag Use it. Worth pinning if it recurs.
canonical Nothing to decide Use it.
base_language Derived — you lose the region Use it, but if regional fidelity matters to you, check the pair.
passthrough Derived — untested against this API Use it, and watch for provider errors.

match is null in exactly one case: supported: false, code: null. That is not a rung of the ladder that ran out — it is a recorded fact about the pair, and the request should not be attempted. via_language tells you whether the refusal was recorded against this language or inherited from a less specific one.

Most callers can ignore match entirely and just send code. It is there for the ones that cannot.

Worked example

GET /v1/resolve?provider=deepl_api&language=zh_hant_hk

  1. deepl_api matches a provider code.
  2. zh_hant_hk normalises to zh-hant-hk. No canonical code matches, but that spelling is a registered alias of zh-HK. Language = zh-HK, matched_alias: "zh-hant-hk".
  3. DeepL has an explicit row for zh-HK → ZH-HANT, in DeepL's own upper-case spelling.
{ "query": "zh_hant_hk", "provider": "deepl_api", "language": "zh-HK",
  "code": "ZH-HANT", "supported": true, "match": "exact",
  "matched_alias": "zh-hant-hk", "via_language": null }

Next