From 12ce909d2a58bcc6f09d580c59b257b444be1357 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Tue, 22 Sep 2026 10:17:32 +0000
Subject: [PATCH] docs: add generated pages from pipeline run 20260922-100739
Generated 3 pages for: Languages, Voice, unknown
- docs/voice/translate-a-pre-recorded-audio-file.mdx: No guide (tutorial or how-to) covers the 'Translate Audio Files' endpoints
- docs/languages/query-supported-languages-for-a-resource.mdx: No guide (tutorial or how-to) covers the 'Languages' endpoints
- docs/learning-how-tos/cookbook/google-sheets: docs/learning-how-tos/cookbook/google-sheets has under 100 words
---
docs.json | 6 +-
...ery-supported-languages-for-a-resource.mdx | 173 +++++++++++++++++
.../translate-a-pre-recorded-audio-file.mdx | 177 ++++++++++++++++++
3 files changed, 355 insertions(+), 1 deletion(-)
create mode 100644 docs/languages/query-supported-languages-for-a-resource.mdx
create mode 100644 docs/voice/translate-a-pre-recorded-audio-file.mdx
diff --git a/docs.json b/docs.json
index b4873789..17b88de6 100644
--- a/docs.json
+++ b/docs.json
@@ -110,6 +110,9 @@
"docs/resources/privacy"
]
}
+ ],
+ "pages": [
+ "docs/languages/query-supported-languages-for-a-resource"
]
},
{
@@ -157,7 +160,8 @@
"docs/voice/understanding-voice-sessions",
"docs/voice/message-encoding",
"docs/voice/supported-voice-languages",
- "docs/voice/voice-api-requirements"
+ "docs/voice/voice-api-requirements",
+ "docs/voice/translate-a-pre-recorded-audio-file"
]
},
{
diff --git a/docs/languages/query-supported-languages-for-a-resource.mdx b/docs/languages/query-supported-languages-for-a-resource.mdx
new file mode 100644
index 00000000..5d234907
--- /dev/null
+++ b/docs/languages/query-supported-languages-for-a-resource.mdx
@@ -0,0 +1,173 @@
+---
+title: "Query supported languages for a resource"
+description: "Use GET /v3/languages to fetch which languages and features a specific DeepL API resource supports, then filter and use that data in your integration."
+covers: [Languages]
+---
+
+The `/v3/languages` endpoint tells you exactly which languages a given DeepL API resource supports, whether each language can be used as a source, target, or both, and which optional features (formality, glossaries, tag handling) are available per language.
+
+This guide shows you how to query languages for a specific resource and use the response to drive language validation and feature detection in your integration.
+
+
+ The `/v3/languages` endpoint replaces the deprecated `/v2/languages` endpoint. If you're currently using `/v2/languages`, see the [migration guide](/docs/languages/migrating-from-v2-languages) for differences and code examples.
+
+
+## Prerequisites
+
+- A DeepL API key. Find yours on your [account page](https://www.deepl.com/your-account/keys).
+- If you're on the free plan, replace `https://api.deepl.com` with `https://api-free.deepl.com` in all examples below.
+
+## Step 1: Choose a resource
+
+The `resource` parameter is required. It tells the endpoint which DeepL API product you're querying language support for:
+
+| **Value** | **Product** |
+|---|---|
+| `translate_text` | Text translation (`/v2/translate`) |
+| `translate_document` | Document translation (`/v2/document`) |
+| `voice` | Speech transcription and translation (`/v3/voice`) |
+| `write` | Text improvement (`/v2/write`) |
+| `glossary` | Glossary management |
+| `style_rules` | Style rules |
+| `translation_memory` | Translation memories |
+
+For this guide, we'll use `translate_text`.
+
+## Step 2: Fetch the language list
+
+Make a `GET` request to `/v3/languages` with your chosen resource:
+
+```sh
+curl -X GET 'https://api.deepl.com/v3/languages?resource=translate_text' \
+ --header 'Authorization: DeepL-Auth-Key YOUR_API_KEY'
+```
+
+The response is a JSON array. Each entry describes one language and its capabilities for the requested resource:
+
+Example response (truncated):
+
+```json
+[
+ {
+ "lang": "de",
+ "name": "German",
+ "status": "stable",
+ "usable_as_source": true,
+ "usable_as_target": true,
+ "features": {
+ "formality": { "status": "stable" },
+ "glossary": { "status": "stable" },
+ "tag_handling": { "status": "stable" }
+ }
+ },
+ {
+ "lang": "en",
+ "name": "English",
+ "status": "stable",
+ "usable_as_source": true,
+ "usable_as_target": false,
+ "features": {
+ "glossary": { "status": "stable" },
+ "tag_handling": { "status": "stable" }
+ }
+ },
+ {
+ "lang": "en-US",
+ "name": "English (American)",
+ "status": "stable",
+ "usable_as_source": false,
+ "usable_as_target": true,
+ "features": {
+ "glossary": { "status": "stable" },
+ "tag_handling": { "status": "stable" }
+ }
+ }
+]
+```
+
+Notice that `en` and `en-US` are separate entries: `en` is source-only, and `en-US` is target-only. Some languages have regional or script variants like this — always check `usable_as_source` and `usable_as_target` rather than assuming a language code is valid in both roles.
+
+
+ Do not hardcode assumptions about language code format. Codes follow BCP 47 and can vary significantly — `de`, `en-US`, `zh-Hans` are all valid. Treat language codes as opaque identifiers and store them as strings. See the [language release process](/docs/resources/language-release-process) for details.
+
+
+## Step 3: Separate source and target languages
+
+Filter the response by `usable_as_source` and `usable_as_target` to build your source and target language lists:
+
+```python
+import urllib.request
+import urllib.parse
+import json
+
+API_KEY = "YOUR_API_KEY"
+
+# Fetch languages for text translation
+url = "https://api.deepl.com/v3/languages?resource=translate_text"
+req = urllib.request.Request(
+ url,
+ headers={"Authorization": f"DeepL-Auth-Key {API_KEY}"}
+)
+with urllib.request.urlopen(req) as response:
+ languages = json.loads(response.read())
+
+# Separate source and target languages
+source_languages = [lang for lang in languages if lang["usable_as_source"]]
+target_languages = [lang for lang in languages if lang["usable_as_target"]]
+
+print(f"Source languages: {len(source_languages)}")
+print(f"Target languages: {len(target_languages)}")
+
+# Build a lookup by language code
+lang_by_code = {lang["lang"]: lang for lang in languages}
+```
+
+## Step 4: Check feature support for a language pair
+
+Before making a translation request with an optional feature (formality, glossary, tag handling), check whether the relevant languages support it. Each language entry includes a `features` object listing which optional features it supports. Check this object for both source and target languages before using a feature in a request. For full details on which languages must support a feature for each resource, see the [API reference for `GET /v3/languages`](/api-reference/languages/retrieve-languages-by-resource).
+
+The `features` dict on each language entry from Step 3 contains exactly the features that language supports — you can check this directly without any additional API calls:
+
+```python
+# Requires lang_by_code from Step 3
+
+def feature_supported(source_lang, target_lang, feature_name):
+ """Return True if the feature is available for the given language pair."""
+ # Formality only needs to be supported by the target language,
+ # because it affects how the output is phrased, not how the source is parsed.
+ if feature_name == "formality":
+ return feature_name in target_lang.get("features", {})
+
+ # All other features (glossary, tag_handling) require both languages to support them.
+ source_ok = feature_name in source_lang.get("features", {})
+ target_ok = feature_name in target_lang.get("features", {})
+ return source_ok and target_ok
+
+
+# Example: check if formality is supported for English → German
+source = lang_by_code.get("en")
+target = lang_by_code.get("de")
+
+print(feature_supported(source, target, "formality"))
+# True — German supports formality as a target language
+
+print(feature_supported(source, target, "glossary"))
+# True — English and German both support glossary
+```
+
+## Step 5: Include beta languages (optional)
+
+By default, the endpoint returns only `stable` languages. To include `beta` languages, add `include=beta`:
+
+```sh
+curl -X GET 'https://api.deepl.com/v3/languages?resource=translate_text&include=beta' \
+ --header 'Authorization: DeepL-Auth-Key YOUR_API_KEY'
+```
+
+Each language and each feature entry carries a `status` field: `stable`, `beta`, or `early_access`. If you include beta languages, filter on this field before exposing them to end users or using them in production workflows.
+
+## Next steps
+
+- See [Using the Languages API](/docs/languages/using-the-languages-api) for additional query patterns and examples
+- Review the [API reference for `GET /v3/languages`](/api-reference/languages/retrieve-languages-by-resource) and [`GET /v3/languages/resources`](/api-reference/languages/retrieve-resources)
+- If you're migrating from `/v2/languages`, see the [migration guide](/docs/languages/migrating-from-v2-languages)
\ No newline at end of file
diff --git a/docs/voice/translate-a-pre-recorded-audio-file.mdx b/docs/voice/translate-a-pre-recorded-audio-file.mdx
new file mode 100644
index 00000000..658202a0
--- /dev/null
+++ b/docs/voice/translate-a-pre-recorded-audio-file.mdx
@@ -0,0 +1,177 @@
+---
+title: "Translate a Pre-Recorded Audio File"
+description: "Submit a pre-recorded audio file for translation, poll for results, and download translated transcripts or audio using the Voice Translate Job API."
+covers: [Translate Audio Files]
+---
+
+The Voice Translate Job API translates pre-recorded audio files asynchronously. Unlike the real-time Voice API (which streams live audio over WebSocket), this API accepts an uploaded audio file and returns one or more translated outputs: plain text transcripts, SRT subtitles, or translated speech audio. Use it for podcasts, meeting recordings, video files, and other pre-recorded content.
+
+This guide walks through the complete workflow: creating a job, uploading your audio file, polling for results, and downloading them.
+
+## Prerequisites
+
+- A DeepL API account with Voice Translate Job API access (currently closed alpha — contact your customer success manager to request access)
+- `curl` for running the examples
+- An audio file to translate (see [Supported Source Audio Formats](/api-reference/jobs-voice-translate/create-voice-translate-job#supported-source-audio-formats) for accepted formats)
+
+## Overview of the workflow
+
+Translating an audio file takes four steps:
+
+1. Create a job to tell the API what outputs you want
+2. Upload your audio file to the URL returned in step 1
+3. Poll the job status until all targets are complete
+4. Download each completed result
+
+Steps 1 and 2 must happen within 5 minutes of each other. After all results are downloaded, the job is deleted.
+
+
+ API Free users should use `https://api-free.deepl.com` in place of `https://api.deepl.com` in all requests below.
+
+
+## Step 1: Create a job
+
+Send a POST request to `/v1/jobs/voice/translate` describing your source file and the outputs you want. You must declare the source file's `content_length` (in bytes) and `content_type` before uploading — the API uses these to prepare the upload URL.
+
+This example translates an English MP3 into a German plain-text transcript and a Spanish PCM audio file:
+
+```bash
+curl -X POST https://api.deepl.com/v1/jobs/voice/translate \
+ -H "Authorization: DeepL-Auth-Key YOUR_AUTH_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "source_file": {
+ "name": "podcast-episode-42.mp3",
+ "content_type": "audio/mpeg",
+ "content_length": 15728640
+ },
+ "parameters": {
+ "source_language": "en"
+ },
+ "targets": [
+ { "language": "de", "type": "text/plain" },
+ { "language": "es", "type": "audio/pcm;encoding=s16le;rate=16000" }
+ ]
+ }'
+```
+
+A successful response returns `201` with a `job_id`, an `upload_url`, and a `signature`:
+
+```json
+{
+ "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994",
+ "signature": "eyJhbGciOiJIUzI1NiIs...",
+ "upload_url": "https://assets.deepl.com/collections/a74d88fb-ed2a-4943-a664-a4512398b994/assets/b1c2d3e4-f5a6-7890-abcd-ef1234567890"
+}
+```
+
+Save the `job_id` — you'll need it to poll status and download results. The `upload_url` is where you send the audio file in the next step.
+
+For all supported output types, see [Supported Output Formats](/api-reference/jobs-voice-translate/create-voice-translate-job#supported-output-formats). For available languages, see the reference page.
+
+## Step 2: Upload the audio file
+
+PUT your audio file directly to the `upload_url`. Set `Content-Type` to match the `content_type` you declared in step 1, and `Content-Length` to the exact byte size.
+
+```bash
+curl -X PUT "https://assets.deepl.com/collections/a74d88fb-ed2a-4943-a664-a4512398b994/assets/b1c2d3e4-f5a6-7890-abcd-ef1234567890" \
+ -H "Content-Type: audio/mpeg" \
+ -H "Content-Length: 15728640" \
+ --data-binary @podcast-episode-42.mp3
+```
+
+A successful upload returns `200` with an empty body. Processing begins automatically once the upload completes.
+
+
+ You have 5 minutes from job creation to complete the upload. If you miss this window, the job expires and you'll need to create a new one.
+
+
+The `Content-Length` header must exactly match the `content_length` you declared when creating the job. A mismatch results in a `400` error.
+
+## Step 3: Poll for results
+
+GET the job status by `job_id`. Each target in the `results` array has its own `status` field and progresses independently.
+
+```bash
+curl https://api.deepl.com/v1/jobs/voice/translate/a74d88fb-ed2a-4943-a664-a4512398b994 \
+ -H "Authorization: DeepL-Auth-Key YOUR_AUTH_KEY"
+```
+
+While processing, the response looks like this:
+
+```json
+{
+ "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994",
+ "operation": "translate",
+ "product": "voice",
+ "parameters": { "source_language": "en" },
+ "source_file": {
+ "name": "podcast-episode-42.mp3",
+ "content_type": "audio/mpeg",
+ "content_length": 15728640
+ },
+ "targets": [
+ { "language": "de", "type": "text/plain" },
+ { "language": "es", "type": "audio/pcm;encoding=s16le;rate=16000" }
+ ],
+ "results": [
+ { "status": "processing" },
+ { "status": "processing" }
+ ],
+ "created_at": "2026-10-01T01:03:03.444Z",
+ "updated_at": "2026-10-01T04:03:03.333Z"
+}
+```
+
+Results are returned in the same order as the `targets` array from your create request.
+
+Poll every 5-10 seconds. When a target's status changes to `complete`, its result object includes a `download_url` and a `signature`:
+
+```json
+{
+ "results": [
+ {
+ "status": "complete",
+ "download_url": "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6",
+ "signature": "eyJhbGciOiJIUzI1NiIs..."
+ },
+ {
+ "status": "failed",
+ "error": { "message": "processing failed" }
+ }
+ ]
+}
+```
+
+Individual targets can reach `complete` or `failed` status independently. Don't wait for all targets before downloading completed ones — a job can have a mix of statuses at the same time.
+
+For the full status lifecycle (`pending` → `uploaded` → `processing` → `complete`), see the [Get Job Status](/api-reference/jobs-voice-translate/get-voice-translate-job-status#result-status-lifecycle) reference.
+
+## Step 4: Download results
+
+GET each completed result from its `download_url`. No authentication header is required for the download — the URL itself is access-controlled.
+
+```bash
+curl -o german-transcript.txt \
+ "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6"
+```
+
+For audio targets, use a file extension that matches the output format (`.wav` for PCM, `.mp3` for MPEG, and so on).
+
+
+ Download results within 1 hour of the upload completing. After this window, results expire and the job is deleted. Once a result is marked `downloaded`, assets are queued for deletion.
+
+
+## Handling failures
+
+If a target's status is `failed`, the `error.message` field describes what went wrong. A failure on one target doesn't affect the others — you can still download any that reached `complete`.
+
+If the source file itself is invalid (wrong format, corrupted, or over 3 hours long), all targets will fail. Source audio over 3 hours is rejected even if the file is under 1 GB. For longer recordings, split the source into separate files and submit each as its own job.
+
+For rate limits, file size limits, and concurrent job limits, see [Voice API Requirements](/docs/voice/voice-api-requirements).
+
+## Next steps
+
+- Check [Supported Source Audio Formats](/api-reference/jobs-voice-translate/create-voice-translate-job#supported-source-audio-formats) and [Supported Output Formats](/api-reference/jobs-voice-translate/create-voice-translate-job#supported-output-formats) for the full list of accepted inputs and producible outputs
+- See the [Create Job](/api-reference/jobs-voice-translate/create-voice-translate-job) and [Get Job Status](/api-reference/jobs-voice-translate/get-voice-translate-job-status) endpoint references for complete request and response schemas
+- For live audio, see the [Real-Time Voice Quickstart](/docs/voice/real-time-voice-quickstart)
\ No newline at end of file