From 200086ea51bcf53ab8be69f6c607a4ffbdeb8ffe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 20 Aug 2026 10:06:31 +0000 Subject: [PATCH] docs: add generated pages from pipeline run 20260820-095624 Generated 3 pages for: Languages, Voice, unknown - docs/voice/translate-an-audio-file-with-the-voice-translate-job-api.mdx: No guide (tutorial or how-to) covers the 'Translate Audio Files' endpoints - docs/languages/query-language-support-for-a-specific-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 +- ...nguage-support-for-a-specific-resource.mdx | 192 ++++++++++++++++++ ...-file-with-the-voice-translate-job-api.mdx | 161 +++++++++++++++ 3 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 docs/languages/query-language-support-for-a-specific-resource.mdx create mode 100644 docs/voice/translate-an-audio-file-with-the-voice-translate-job-api.mdx diff --git a/docs.json b/docs.json index 38559381..256fae06 100644 --- a/docs.json +++ b/docs.json @@ -102,6 +102,9 @@ } ] } + ], + "pages": [ + "docs/languages/query-language-support-for-a-specific-resource" ] }, { @@ -149,7 +152,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-an-audio-file-with-the-voice-translate-job-api" ] }, { diff --git a/docs/languages/query-language-support-for-a-specific-resource.mdx b/docs/languages/query-language-support-for-a-specific-resource.mdx new file mode 100644 index 00000000..e8e49753 --- /dev/null +++ b/docs/languages/query-language-support-for-a-specific-resource.mdx @@ -0,0 +1,192 @@ +--- +title: "Query language support for a specific resource" +description: "Use the v3/languages endpoint to look up which languages and features are available for a specific DeepL API resource before you make translation requests." +covers: [Languages] +--- + +The `/v3/languages` endpoint tells you which languages a given DeepL API resource supports and which optional features (formality, glossaries, tag handling, and more) are available per language. Calling it before you build language selectors or validate user input lets you stay current as DeepL adds languages, without maintaining a hardcoded list. + +This guide shows you how to query language support for a resource, read the response, and check whether a specific feature is available for a language pair. + + +The `resource` parameter is required. If you're migrating from `/v2/languages`, see the [migration guide](/docs/languages/migrating-from-v2-languages) — the v3 response structure is different. + + +## Before you start + +You need a DeepL API key. Find yours on the [API Keys & Limits page](https://www.deepl.com/your-account/keys). If you're on the Free plan, use `https://api-free.deepl.com` instead of `https://api.deepl.com` in all requests below. + +## Step 1: Choose your resource + +The `resource` parameter identifies which DeepL API product you're querying language support for. Choose the value that matches what you're building: + +| **`resource` value** | **What it covers** | +|---|---| +| `translate_text` | Text translation via `/v2/translate` | +| `translate_document` | Document translation via `/v2/document` | +| `glossary` | Glossary management via `/v2/` and `/v3/glossaries` | +| `voice` | Speech transcription and translation via `/v3/voice` | +| `write` | Text improvement via `/v2/write` | +| `style_rules` | Style rules via the style rules endpoints | +| `translation_memory` | Translation memory features | + +## Step 2: Fetch supported languages + +Call `GET /v3/languages` with your chosen `resource` value. This example queries languages for text translation: + +```sh +curl -X GET 'https://api.deepl.com/v3/languages?resource=translate_text' \ + --header 'Authorization: DeepL-Auth-Key [yourAuthKey]' +``` + +The response is an array where each object represents one language: + +```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" } + } + } +] +``` + +A few things to notice in this response: + +- `en` is source-only (`usable_as_source: true`, `usable_as_target: false`). For target languages, use a regional variant like `en-US` or `en-GB`. +- Language codes follow [BCP 47](https://developers.deepl.com/docs/resources/language-release-process). Don't assume codes are always two letters — treat them as opaque identifiers. +- The `features` object lists optional capabilities available for that language with this resource. A feature's absence means it isn't supported. + +## Step 3: Filter source and target languages + +Use `usable_as_source` and `usable_as_target` to build your language selectors: + +```python +import requests + +def get_languages(resource, auth_key): + response = requests.get( + "https://api.deepl.com/v3/languages", + params={"resource": resource}, + headers={"Authorization": f"DeepL-Auth-Key {auth_key}"}, + ) + response.raise_for_status() + return response.json() + +languages = get_languages("translate_text", auth_key="[yourAuthKey]") + +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("Source languages:", [lang["lang"] for lang in source_languages]) +print("Target languages:", [lang["lang"] for lang in target_languages]) +``` + +## Step 4: Check feature availability for a language pair + +Some features, like formality, depend on both the source and target language supporting it. To know which language must support a feature for it to be available, call `GET /v3/languages/resources`: + +```sh +curl -X GET 'https://api.deepl.com/v3/languages/resources' \ + --header 'Authorization: DeepL-Auth-Key [yourAuthKey]' +``` + +```json +[ + { + "name": "translate_text", + "features": [ + { "name": "formality", "needs_target_support": true }, + { "name": "glossary", "needs_source_support": true, "needs_target_support": true }, + { "name": "tag_handling", "needs_source_support": true, "needs_target_support": true }, + { "name": "auto_detection", "needs_source_support": true } + ] + } +] +``` + +For `formality`, only `needs_target_support` is set. This means you only need to check whether the target language's `features` object contains `formality` — the source language doesn't matter. + +For `glossary`, both `needs_source_support` and `needs_target_support` are set. Both languages in the pair must support `glossary` for you to use a glossary on that translation. + +Here's a helper that combines both calls to check whether a feature is available for a given pair: + +```python +def is_feature_available(feature_name, source_lang, target_lang, resource_name, languages, resources): + # Find the feature's requirements from the resources list + resource_info = next(r for r in resources if r["name"] == resource_name) + feature_req = next( + (f for f in resource_info["features"] if f["name"] == feature_name), + None, + ) + if feature_req is None: + return False # Feature not defined for this resource + + lang_map = {lang["lang"]: lang for lang in languages} + + if feature_req.get("needs_source_support"): + source = lang_map.get(source_lang, {}) + if feature_name not in source.get("features", {}): + return False + + if feature_req.get("needs_target_support"): + target = lang_map.get(target_lang, {}) + if feature_name not in target.get("features", {}): + return False + + return True + +# Example: can we use a glossary for EN → DE? +available = is_feature_available("glossary", "en", "de", "translate_text", languages, resources) +print(f"Glossary available for EN→DE: {available}") # True +``` + +## Including beta languages + +By default, the endpoint only returns stable languages. To include languages in beta, add `include=beta` to your request: + +```sh +curl -X GET 'https://api.deepl.com/v3/languages?resource=translate_text&include=beta' \ + --header 'Authorization: DeepL-Auth-Key [yourAuthKey]' +``` + +Beta languages appear in the response with `"status": "beta"`. Use the `status` field to decide whether to surface them to end users or restrict them to internal testing. + + +Don't hardcode the list of languages returned by this endpoint. New languages are added regularly — call the endpoint at startup (or on a schedule) and cache the result rather than maintaining a static list. See the [language release process](/docs/resources/language-release-process) for details on how DeepL introduces new languages. + + +## Next steps + +- See the full API reference: [Retrieve languages](/api-reference/languages/retrieve-languages-by-resource) and [Retrieve language resources](/api-reference/languages/retrieve-resources) +- Browse all languages the API currently supports: [Languages supported](/docs/getting-started/supported-languages) +- If you're coming from `/v2/languages`: [Migrating from v2/languages](/docs/languages/migrating-from-v2-languages) \ No newline at end of file diff --git a/docs/voice/translate-an-audio-file-with-the-voice-translate-job-api.mdx b/docs/voice/translate-an-audio-file-with-the-voice-translate-job-api.mdx new file mode 100644 index 00000000..fec14e8a --- /dev/null +++ b/docs/voice/translate-an-audio-file-with-the-voice-translate-job-api.mdx @@ -0,0 +1,161 @@ +--- +title: "Translate an Audio File with the Voice Translate Job API" +description: "Submit a pre-recorded audio file for translation and download the results using the asynchronous Voice Translate Job API." +covers: [Translate Audio Files] +--- + +The Voice Translate Job API translates pre-recorded audio files asynchronously. You submit a job, upload your audio file, poll for results, and download each output when it's ready. This guide walks through all four steps with a complete curl example. + +Use this API for batch or offline workloads: podcasts, meeting recordings, video files, and similar pre-recorded content. For live audio, use the [real-time Voice API](/docs/voice/overview). + + + This API is only available to select DeepL customers and may change without notice. See [alpha and beta features](/docs/resources/alpha-and-beta-features) for details, or contact your customer success manager to request access. + + +## Prerequisites + +- A DeepL API account with Voice Translate Job API access +- Your DeepL API key (set as `DEEPL_API_KEY` in the examples below) +- A pre-recorded audio file in a [supported format](/api-reference/jobs-voice-translate/reference#supported-source-audio-formats) + +For file size, duration, concurrency, and supported format constraints, see the [Translate Audio Files reference](/api-reference/jobs-voice-translate/reference#limits). + +API Pro users call `https://api.deepl.com`. API Free users call `https://api-free.deepl.com` instead. + +## The four-step workflow + +Every translation follows the same pattern: + +1. **Create a job** to declare your source file and desired outputs. The API returns an upload URL. +2. **Upload your audio file** directly to that URL. +3. **Poll for status** until all targets are complete (or failed). +4. **Download each result** from its download URL. + +The sections below walk through each step. + +## Step 1: Create a job + +Send a POST request to `/v1/jobs/voice/translate` with the source file metadata and your desired translation targets. + +The `content_length` and `content_type` fields in `source_file` must match your actual file exactly. The API uses them to provision a pre-signed upload URL, so mismatches will cause the upload in step 2 to fail. + +```bash +curl -X POST "https://api.deepl.com/v1/jobs/voice/translate" \ + -H "Authorization: DeepL-Auth-Key $DEEPL_API_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 includes 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` for polling and the `upload_url` for the next step. You have 5 minutes to complete the upload before the URL expires. + +Each job can have multiple targets in different output types, so a single English recording can produce a German transcript, French subtitles, and Spanish audio in one request. See the [Translate Audio Files reference](/api-reference/jobs-voice-translate/reference) for the full list of output types and supported languages. + +## Step 2: Upload your audio file + +PUT your audio file to the `upload_url` returned in step 1. Set `Content-Type` to the same value you declared in `source_file.content_type`. + +Do not include your DeepL API key in the upload request. The URL is pre-signed and only requires the `Content-Type` header. Adding an `Authorization` header will cause the request to fail. + +```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" \ + --data-binary @podcast-episode-42.mp3 +``` + +A `200 OK` response with no body means the upload succeeded. Processing starts automatically once the file is received. + +## Step 3: Poll for status + +Check the job status by sending a GET request to `/v1/jobs/voice/translate/{job_id}`. Each target in the `results` array has its own `status` field that progresses independently. + +```bash +curl "https://api.deepl.com/v1/jobs/voice/translate/a74d88fb-ed2a-4943-a664-a4512398b994" \ + -H "Authorization: DeepL-Auth-Key $DEEPL_API_KEY" +``` + +While targets are still 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" +} +``` + +When a target completes, its result entry includes a `download_url` and `signature`: + +```json +{ + "results": [ + { + "status": "complete", + "download_url": "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6", + "signature": "eyJhbGciOiJIUzI1NiIs..." + }, + { + "status": "failed", + "error": { "message": "processing failed" } + } + ] +} +``` + +Results are returned in the same order as the `targets` array in your create request, so `results[0]` corresponds to `targets[0]`. + +Poll every 10-30 seconds for files under 100 MB. Larger files or longer recordings may take several minutes. Keep polling until every result has reached a terminal status: `complete`, `failed`, or `downloaded`. + +## Step 4: Download results + +For each target with `status: complete`, download the result from its `download_url`. No authentication header is needed — the URL is pre-signed. + +```bash +# Download the German plain-text transcript +curl -o translation_de.txt \ + "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6" +``` + +After you download a result, its status transitions to `downloaded` and the asset is queued for deletion. You have 1 hour from the time the upload completes to download all results. After that window, or once all results are downloaded, the job is deleted and returns `404`. + +## Handling partial failures + +Individual targets can fail while others succeed. Check each result's `status` independently and handle `failed` results by reading the `error.message` field. You cannot retry a failed target within an existing job; you need to create a new job. \ No newline at end of file