Skip to content

Commit e94a125

Browse files
Merge pull request #239 from DeepLcom/v3-languages-beta
v3/languages beta
2 parents 84aafd1 + 46bda16 commit e94a125

10 files changed

Lines changed: 867 additions & 8 deletions

api-reference/languages.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ curl -X GET 'https://api.deepl.com/v2/languages?type=target' \
210210
```http Example request: supported target languages
211211
GET /v2/languages?type=target HTTP/2
212212
Host: api.deepl.com
213-
Authorization: DeepL-Auth-Key [yourAuthKey]
213+
Authorization: DeepL-Auth-Key [yourAuthKey]
214214
User-Agent: YourApp/1.2.3
215215
```
216216
```json Example response
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
---
2+
title: 'Common use cases [BETA]'
3+
description: "Pseudocode examples for common language and feature lookup patterns using the v3/languages endpoints."
4+
---
5+
6+
This page shows how to use the `/v3/languages` endpoints for common integration tasks. Examples are written
7+
as pseudocode and are product-agnostic unless otherwise noted.
8+
9+
For background on how features and feature dependency types work, see the
10+
[overview](/api-reference/languages/retrieve-supported-languages-by-product).
11+
12+
<Note>
13+
The examples below do not account for language pair exceptions. For most integrations this is fine — exceptions
14+
are rare and the API handles them gracefully by disabling the unsupported feature rather than failing. If you
15+
need precise feature support for specific language pairs, see
16+
[Handling language pair exceptions](#handling-language-pair-exceptions) at the end of this page.
17+
</Note>
18+
19+
---
20+
21+
## Populate source and target language dropdowns
22+
23+
A single call to `GET /v3/languages` returns all languages for a product. Filter by `usable_as_source` and
24+
`usable_as_target` to populate each dropdown separately.
25+
26+
```
27+
GET /v3/languages?product=translate_text
28+
29+
languages = response
30+
31+
source_options = languages.filter(l => l.usable_as_source)
32+
target_options = languages.filter(l => l.usable_as_target)
33+
34+
render source_dropdown(source_options)
35+
render target_dropdown(target_options)
36+
```
37+
38+
---
39+
40+
## Show formality options only when supported
41+
42+
`formality` is a target-only feature. Check the selected target language's `features` array — no need to look
43+
at the source language.
44+
45+
```
46+
GET /v3/languages?product=translate_text
47+
48+
languages = response
49+
target = languages.find(l => l.lang == selected_target_lang)
50+
51+
if target.features.includes("formality"):
52+
show formality_selector // e.g. ["default", "more", "less"]
53+
else:
54+
hide formality_selector
55+
```
56+
57+
---
58+
59+
## Check if a glossary can be used for a given language pair
60+
61+
`glossary` is a source-and-target feature — both languages must support it.
62+
63+
```
64+
GET /v3/languages?product=translate_text
65+
66+
languages = response
67+
68+
source = languages.find(l => l.lang == source_lang)
69+
target = languages.find(l => l.lang == target_lang)
70+
71+
glossary_allowed = source.features.includes("glossary")
72+
and target.features.includes("glossary")
73+
```
74+
75+
---
76+
77+
## List target languages that accept glossaries from a given source language
78+
79+
Filter to targets where both the source and target support the `glossary` feature.
80+
81+
```
82+
GET /v3/languages?product=translate_text
83+
84+
languages = response
85+
source_lang = "en"
86+
87+
source = languages.find(l => l.lang == source_lang)
88+
89+
if not source.features.includes("glossary"):
90+
return [] // source doesn't support glossary at all
91+
92+
targets_with_glossary = languages
93+
.filter(l => l.usable_as_target)
94+
.filter(l => l.features.includes("glossary"))
95+
```
96+
97+
---
98+
99+
## Show writing style options for the Write product
100+
101+
`writing_style` is a target-only feature on the `write` product. Check the target language's `features` array.
102+
103+
```
104+
GET /v3/languages?product=write
105+
106+
languages = response
107+
target = languages.find(l => l.lang == selected_target_lang)
108+
109+
if target.features.includes("writing_style"):
110+
show writing_style_selector
111+
else:
112+
hide writing_style_selector
113+
```
114+
115+
---
116+
117+
## Determine feature support programmatically
118+
119+
Use `/v3/languages/products` to drive feature checks at runtime — without hardcoding which features are
120+
target-only or source-and-target into your client.
121+
122+
```
123+
GET /v3/languages/products
124+
GET /v3/languages?product=translate_text
125+
126+
products = first response
127+
languages = second response
128+
129+
product = products.find(p => p.name == "translate_text")
130+
source = languages.find(l => l.lang == source_lang)
131+
target = languages.find(l => l.lang == target_lang)
132+
133+
for feature in product.features:
134+
supported = true
135+
if feature.required_on_source and not source.features.includes(feature.name):
136+
supported = false
137+
if feature.required_on_target and not target.features.includes(feature.name):
138+
supported = false
139+
```
140+
141+
---
142+
143+
## Handling language pair exceptions
144+
145+
In rare cases, feature support for a specific pair differs from what the individual language objects indicate.
146+
The `/v3/languages/exceptions` endpoint exposes these cases. When an exception exists for a pair, its `features`
147+
array is authoritative — use it directly instead of intersecting the individual language `features` arrays.
148+
149+
The example below shows a full glossary pair check that accounts for exceptions:
150+
151+
```
152+
GET /v3/languages?product=translate_text
153+
GET /v3/languages/exceptions?product=translate_text
154+
155+
languages = first response
156+
exceptions = second response
157+
158+
exception = exceptions.find(e => e.source_lang == source_lang && e.target_lang == target_lang)
159+
160+
if exception:
161+
features = exception.features
162+
else:
163+
source = languages.find(l => l.lang == source_lang)
164+
target = languages.find(l => l.lang == target_lang)
165+
features = intersect(source.features, target.features)
166+
167+
glossary_allowed = features.includes("glossary")
168+
```
169+
170+
The same pattern applies to any feature check — replace `"glossary"` with the feature you are checking.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
title: 'Migrating from v2/languages'
3+
description: "How to migrate from the v2/languages endpoint to the v3/languages endpoints."
4+
---
5+
6+
This page covers the differences between the `/v2/languages` endpoint and the v3 endpoints, and how to update your integration.
7+
8+
<Warning>
9+
Only `GET` requests are supported on the v3 endpoints. Unlike `/v2/languages`, POST is not supported.
10+
</Warning>
11+
12+
## What changed
13+
14+
### Single endpoint for source and target
15+
16+
v2 uses a single endpoint with a `type` query parameter to distinguish source from target:
17+
18+
```
19+
GET /v2/languages?type=source
20+
GET /v2/languages?type=target
21+
```
22+
23+
v3 uses a single endpoint that returns all languages for a product, with each language indicating whether it is
24+
usable as a source, a target, or both:
25+
26+
```
27+
GET /v3/languages?product=translate_text
28+
```
29+
30+
### New product identifiers
31+
32+
v2 languages are implicitly tied to text and document translation. v3 introduces an explicit `product` parameter that applies across all DeepL API products:
33+
34+
| v2 | v3 `product` value |
35+
|---|---|
36+
| *(implicit, text/document translation only)* | `translate_text` |
37+
| *(implicit, text/document translation only)* | `translate_document` |
38+
| *(separate `/v2/glossary-language-pairs` endpoint)* | `glossary` |
39+
| *(not supported)* | `voice` |
40+
| *(not supported)* | `write` |
41+
42+
The v3 endpoints replace both `/v2/languages` and `/v2/glossary-language-pairs`.
43+
44+
### Features instead of `supports_formality`
45+
46+
v2 target languages include a boolean `supports_formality` field. v3 replaces this with a `features` array that covers additional capabilities per product:
47+
48+
| v2 field | v3 equivalent |
49+
|---|---|
50+
| `"supports_formality": true` | `"features": ["formality"]` on the language object |
51+
52+
For example, querying languages for text translation:
53+
54+
```sh
55+
curl -X GET 'https://api.deepl.com/v3/languages?product=translate_text' \
56+
--header 'Authorization: DeepL-Auth-Key [yourAuthKey]'
57+
```
58+
59+
```json Example response (truncated)
60+
[
61+
{
62+
"lang": "de",
63+
"name": "German",
64+
"usable_as_source": true,
65+
"usable_as_target": true,
66+
"features": ["formality", "tag_handling", "glossary"]
67+
},
68+
{
69+
"lang": "en-US",
70+
"name": "English (American)",
71+
"usable_as_source": false,
72+
"usable_as_target": true,
73+
"features": ["tag_handling", "glossary"]
74+
}
75+
]
76+
```
77+
78+
The response indicates German supports `formality`, but English (American) does not.
79+
80+
See the [overview](/api-reference/languages/retrieve-supported-languages-by-product) for the full list of features per product.
81+
82+
### Response field names
83+
84+
| v2 field | v3 field |
85+
|----------------------|------------------------|
86+
| `language` | `lang` |
87+
| `name` | `name` *(unchanged)* |
88+
| `supports_formality` | `features["formality]` |
89+
90+
### Language code casing
91+
92+
v2 returned language codes in non-standard casing (e.g. `EN-US`, `ZH-HANT`). v3 returns codes compliant with BCP 47: lowercase base language (`en`, `de`), uppercase region subtag (`en-US`, `pt-BR`), and title-case script subtag (`zh-Hant`).
93+
94+
DeepL accepts language codes case-insensitively as input across all endpoints. However, if your integration stores or compares codes returned by `/v2/languages`, update those comparisons to be case-insensitive or to expect the new casing.
95+
96+
## Migrating glossary language pair queries
97+
98+
If you currently use `/v2/glossary-language-pairs` to discover which language pairs are supported for glossaries, use one of the following:
99+
100+
- `GET /v3/languages?product=glossary` to check which languages support glossary management (i.e. creating a glossary for that language). Filter by `usable_as_source` and `usable_as_target` as needed. Any combination of a valid source and target language is a supported glossary language pair.
101+
- `GET /v3/languages?product=translate_text` to check which languages support using a glossary during text translation. Languages that include `"glossary"` in their `features` array support the `glossary_id` parameter on the translate endpoint.
102+
- Similarly, use `product=translate_document` to check glossary support for document translation.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
openapi: get /v3/languages/exceptions
3+
title: "Retrieve language pair exceptions [BETA]"
4+
---
5+
6+
<Info>
7+
This endpoint is available for testing in BETA. Breaking changes may be pushed with little or no advance notice, and we provide no guarantees of stability.
8+
</Info>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
openapi: get /v3/languages
3+
title: "Retrieve languages [BETA]"
4+
---
5+
6+
<Info>
7+
This endpoint is available for testing in BETA. Breaking changes may be pushed with little or no advance notice, and we provide no guarantees of stability.
8+
</Info>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
openapi: get /v3/languages/products
3+
title: "Retrieve language products [BETA]"
4+
---
5+
6+
<Info>
7+
This endpoint is available for testing in BETA. Breaking changes may be pushed with little or no advance notice, and we provide no guarantees of stability.
8+
</Info>

0 commit comments

Comments
 (0)