From 7c87ac7c2250610360bf1b0bffc3f0443b804663 Mon Sep 17 00:00:00 2001 From: David Fenster Date: Wed, 22 Apr 2026 23:24:00 -0400 Subject: [PATCH 1/5] docs(jobs): add new docs for voice job api --- api-reference/jobs-voice-translate.mdx | 374 +++++++++++ .../jobs-voice-translate.openapi.yaml | 620 ++++++++++++++++++ .../create-voice-translate-job.mdx | 4 + .../get-voice-translate-job-status.mdx | 4 + docs.json | 8 + 5 files changed, 1010 insertions(+) create mode 100644 api-reference/jobs-voice-translate.mdx create mode 100644 api-reference/jobs-voice-translate.openapi.yaml create mode 100644 api-reference/jobs-voice-translate/create-voice-translate-job.mdx create mode 100644 api-reference/jobs-voice-translate/get-voice-translate-job-status.mdx diff --git a/api-reference/jobs-voice-translate.mdx b/api-reference/jobs-voice-translate.mdx new file mode 100644 index 0000000..c942201 --- /dev/null +++ b/api-reference/jobs-voice-translate.mdx @@ -0,0 +1,374 @@ +--- +title: "Translate Audio Files" +sidebarTitle: "Overview" +description: "Translate pre-recorded audio files into text or audio in other languages using asynchronous jobs." +public: true +--- + + + **Experimental.** This API may change without notice. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). See [alpha and beta features](/docs/resources/alpha-and-beta-features) for details. + + +The Voice Translate API provides asynchronous translation of audio files into text or audio in other languages. + +Unlike the [real-time Voice API](/api-reference/voice), which streams audio over a WebSocket connection, the Voice Translate API processes entire audio files asynchronously. This makes it suitable for pre-recorded content such as podcasts, meeting recordings, or media files up to 1 GB. + +Each job can produce multiple translation targets simultaneously. For example, a single English podcast can be translated into German text and Spanish audio in one job. + +For full request and response schemas, 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. + +## Workflow + +Translating an audio file is a four-step process: + + + + ### Create Job + Make a `POST` request to `/v1/jobs/voice/translate` with file metadata, processing parameters, and translation targets. + + The response includes a `job_id`, an `upload_url`, and a `signature` for authenticating the upload. + + + + The examples below use our API Pro endpoint `https://api.deepl.com`. If you're an API Free user, remember to update your requests to use `https://api-free.deepl.com` instead. + + ```sh Example request + curl -X POST 'https://api.deepl.com/v1/jobs/voice/translate' \ + --header 'Authorization: DeepL-Auth-Key [yourAuthKey]' \ + --header 'Content-Type: application/json' \ + --data '{ + "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" } + ] + }' + ``` + + ```json Example response + { + "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "upload_url": "https://assets.deepl.com/collections/a74d88fb-.../assets/b1c2d3e4-...", + "signature": "eyJhbGciOiJIUzI1NiIs..." + } + ``` + + + The examples below use our API Pro endpoint `https://api.deepl.com`. If you're an API Free user, remember to update your requests to use `https://api-free.deepl.com` instead. + + ```http Example request + POST /v1/jobs/voice/translate HTTP/2 + Host: api.deepl.com + Authorization: DeepL-Auth-Key [yourAuthKey] + Content-Type: application/json + + { + "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" } + ] + } + ``` + + ```json Example response + { + "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "upload_url": "https://assets.deepl.com/collections/a74d88fb-.../assets/b1c2d3e4-...", + "signature": "eyJhbGciOiJIUzI1NiIs..." + } + ``` + + + + See the [Create Job endpoint reference](/api-reference/jobs-voice-translate/create-voice-translate-job) for the full request and response schema. + + + ### Upload File + Upload the source audio file to the `upload_url` returned in step 1. + + + + ```sh Upload with authorization header (recommended) + curl -X PUT '{upload_url}' \ + --header 'Authorization: DeepL-Signature {signature}' \ + --header 'Content-Type: application/octet-stream' \ + --data-binary @podcast-episode-42.mp3 + ``` + + + ```http Upload with authorization header (recommended) + PUT {upload_url} HTTP/2 + Authorization: DeepL-Signature {signature} + Content-Type: application/octet-stream + + [binary audio data] + ``` + + + + See [Choosing an authentication method](#choosing-an-authentication-method) for details on the two upload options. + + + ### Poll Status + Poll `GET /v1/jobs/voice/translate/{job_id}` until all targets reach a terminal status (`complete`, `downloaded`, or `failed`). We recommend polling every 5 seconds. + + + + The examples below use our API Pro endpoint `https://api.deepl.com`. If you're an API Free user, remember to update your requests to use `https://api-free.deepl.com` instead. + + ```sh Example request + curl 'https://api.deepl.com/v1/jobs/voice/translate/a74d88fb-ed2a-4943-a664-a4512398b994' \ + --header 'Authorization: DeepL-Auth-Key [yourAuthKey]' + ``` + + ```json Example response: processing + { + "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "product": "voice", + "operation": "translate", + "created_at": "2026-10-01T01:03:03.444Z", + "updated_at": "2026-10-01T04:03:03.333Z", + "usage": { "storage_used": 31457280 }, + "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" } + ], + "results": [ + { "status": "processing" }, + { "status": "processing" } + ] + } + ``` + + ```json Example response: complete with mixed results + { + "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "product": "voice", + "operation": "translate", + "created_at": "2026-10-01T01:03:03.444Z", + "updated_at": "2026-10-01T04:03:03.333Z", + "usage": { "storage_used": 31457280 }, + "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" } + ], + "results": [ + { + "status": "complete", + "download_url": "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6", + "signature": "eyJhbGciOiJIUzI1NiIs..." + }, + { + "status": "failed", + "error": { "message": "processing failed" } + } + ] + } + ``` + + + The examples below use our API Pro endpoint `https://api.deepl.com`. If you're an API Free user, remember to update your requests to use `https://api-free.deepl.com` instead. + + ```http Example request + GET /v1/jobs/voice/translate/a74d88fb-ed2a-4943-a664-a4512398b994 HTTP/2 + Host: api.deepl.com + Authorization: DeepL-Auth-Key [yourAuthKey] + ``` + + ```json Example response: processing + { + "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "product": "voice", + "operation": "translate", + "created_at": "2026-10-01T01:03:03.444Z", + "updated_at": "2026-10-01T04:03:03.333Z", + "usage": { "storage_used": 31457280 }, + "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" } + ], + "results": [ + { "status": "processing" }, + { "status": "processing" } + ] + } + ``` + + ```json Example response: complete with mixed results + { + "job_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "product": "voice", + "operation": "translate", + "created_at": "2026-10-01T01:03:03.444Z", + "updated_at": "2026-10-01T04:03:03.333Z", + "usage": { "storage_used": 31457280 }, + "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" } + ], + "results": [ + { + "status": "complete", + "download_url": "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6", + "signature": "eyJhbGciOiJIUzI1NiIs..." + }, + { + "status": "failed", + "error": { "message": "processing failed" } + } + ] + } + ``` + + + + See the [Get Job Status endpoint reference](/api-reference/jobs-voice-translate/get-voice-translate-job-status) for the full response schema. + + + ### Download Result + Download completed results using the `download_url` and `signature` from the poll response. + + + + ```sh Download with authorization header (recommended) + curl '{download_url}' \ + --header 'Authorization: DeepL-Signature {signature}' \ + --output translated-output.txt + ``` + + + ```http Download with authorization header (recommended) + GET {download_url} HTTP/2 + Authorization: DeepL-Signature {signature} + ``` + + + + After a result is downloaded, its status changes to `downloaded` and the assets are marked for deletion. See [Choosing an authentication method](#choosing-an-authentication-method) for details on the two download options. + + + +## Choosing an authentication method + +By default, the API returns an unsigned `upload_url` and `download_url`. Use the `Authorization: DeepL-Signature {signature}` header to authenticate uploads and downloads. Both methods use time-limited credentials. + +If you need to delegate uploads or downloads to browsers, mobile clients, or other systems that cannot set custom headers, pass `?include=signed_url` to the create or poll request to get pre-signed URLs instead. + + + Use the `Authorization` header by default. A leaked signed URL could allow an attacker to upload malicious content to your job or download your results. + + +For a full comparison of authentication methods, see the [Create Job endpoint reference](/api-reference/jobs-voice-translate/create-voice-translate-job). + +## Result Status Lifecycle + +Each target result progresses through the following statuses independently: + +`pending` -> `uploaded` -> `processing` -> `complete` -> `downloaded` + +A target may transition to `failed` at any point during processing. When a target fails, the `error` field contains a description of the failure. + +Jobs must be uploaded within 5 minutes of creation, and results must be downloaded within 1 hour of upload. After all results are downloaded or the job expires, the job is deleted and returns `404`. + +## Limits + +| **Limit** | **Value** | +| :--- | :--- | +| Maximum file size | 1 GB (1,073,741,824 bytes) | +| Time to upload after job creation | 5 minutes | +| Time to download results after upload | 1 hour | +| Maximum concurrent jobs per customer | 10 | +| Maximum concurrent jobs per customer (files > 100 MB) | 2 | +| Maximum targets per job | No limit (constrained by storage quota) | + +Usage is billed based on the duration of the source audio. + +## Supported Source Audio Formats + +| **MIME type** | +| :--- | +| `audio/mpeg` | +| `audio/wav` | +| `audio/ogg` | +| `audio/flac` | +| `audio/mp4` | +| `audio/webm` | + +## Supported Languages + +Source and target languages are the same as those supported by the [real-time Voice API](/api-reference/voice#supported-languages). + + + `source_language` is optional. If omitted, the language is detected automatically. + + +## Supported Output Formats + +Each target specifies a `type` for the desired output format. + +| **Type** | **Description** | +| :--- | :--- | +| `text/plain` | Plain text transcript | +| `audio/opus` | Opus audio | +| `audio/flac` | FLAC audio | +| `audio/pcm;encoding=s16le;rate=16000` | PCM 16-bit signed LE, 16 kHz | +| `audio/pcm;encoding=s16le;rate=24000` | PCM 16-bit signed LE, 24 kHz | +| `audio/pcm;encoding=ulaw;rate=8000` | PCM u-law, 8 kHz | +| `audio/pcm;encoding=alaw;rate=8000` | PCM A-law, 8 kHz | +| `audio/x-matroska;codecs=aac` | Matroska with AAC | +| `audio/x-matroska;codecs=flac` | Matroska with FLAC | +| `audio/x-matroska;codecs=opus` | Matroska with Opus | +| `audio/x-matroska;codecs=pcm_s16le;rate=16000` | Matroska with PCM 16 kHz | +| `audio/x-matroska;codecs=pcm_s16le;rate=24000` | Matroska with PCM 24 kHz | +| `video/mp2t;codecs=aac` | MPEG-TS with AAC | +| `video/mp2t;codecs=opus` | MPEG-TS with Opus | +| `audio/ogg;codecs=flac` | Ogg with FLAC | +| `audio/ogg;codecs=opus` | Ogg with Opus | +| `audio/webm;codecs=opus` | WebM with Opus | + +## Next steps + +Now that you understand how to translate audio files asynchronously: + +- **Create a job:** Review the [Create Job endpoint reference](/api-reference/jobs-voice-translate/create-voice-translate-job) for the full request and response schema +- **Poll job status:** Review the [Get Job Status endpoint reference](/api-reference/jobs-voice-translate/get-voice-translate-job-status) for the full response schema +- **Try realtime translation:** Use the [Voice API](/api-reference/voice) for streaming audio translation over WebSocket instead of batch processing diff --git a/api-reference/jobs-voice-translate.openapi.yaml b/api-reference/jobs-voice-translate.openapi.yaml new file mode 100644 index 0000000..f47c3ed --- /dev/null +++ b/api-reference/jobs-voice-translate.openapi.yaml @@ -0,0 +1,620 @@ +openapi: 3.0.3 +info: + title: DeepL Voice Translate API + description: |- + **Experimental.** This API may change without notice. Breaking changes will be communicated via the changelog. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). + + The Voice Translate API provides asynchronous translation of audio files into text or audio in other languages. + + ## Workflow + + Translating an audio file is a four-step process: + + 1. **Create Job** (`POST /v1/jobs/voice/translate`): Submit file metadata, processing parameters, and translation targets. The response includes the `job_id`, an `upload_url`, and a `signature`. If `?include=signed_url` is specified, a `signed_upload_url` is also returned. + 2. **Upload File** (`PUT {upload_url}`): Upload the audio file directly to the storage service. Use one of: + - `PUT {upload_url}` with header `Authorization: DeepL-Signature {signature}` and `Content-Type: application/octet-stream` + - `PUT {signed_upload_url}` with `Content-Type: application/octet-stream` (no authorization header needed) + 3. **Poll Status** (`GET /v1/jobs/voice/translate/{job_id}`): Check the job status. Each target has its own status. When a target reaches `complete`, the response includes a `download_url` and `signature` for that target. If `?include=signed_url` is specified, a `signed_download_url` is also returned. + 4. **Download Result** (`GET {download_url}`): Retrieve the translated output directly from the storage service. Use one of: + - `GET {download_url}` with header `Authorization: DeepL-Signature {signature}` + - `GET {signed_download_url}` (no authorization header needed) + + Upload and download URLs are opaque and returned by the API. Do not construct them manually. + + ## Choosing an Authentication Method + + The API supports two ways to authenticate uploads and downloads. Both methods use time-limited credentials. + + - **Authorization header (recommended)**: Use the `upload_url` or `download_url` with the header `Authorization: DeepL-Signature {signature}`. This keeps credentials out of the URL, preventing leaks through server logs, browser history, or referrer headers. It also protects against man-in-the-middle interception; a leaked signed URL could allow an attacker to upload malicious content to your job. + - **Signed URL**: Request a pre-signed URL by adding `?include=signed_url` to the create or poll request. The returned `signed_upload_url` or `signed_download_url` embeds the credential in the URL itself, so no authorization header is needed. This is useful when delegating uploads or downloads to browsers, mobile clients, or third-party systems that cannot set custom headers. + + Use the authorization header by default. Use signed URLs only when the consuming system cannot set custom HTTP headers. + + ## Result Status Lifecycle + + Each target result progresses through the following statuses: + + `pending` -> `uploaded` -> `processing` -> `complete` -> `downloaded` + + A target may also transition to `failed` at any point during processing. After a result is downloaded, its assets are marked for deletion and the status becomes `downloaded`. Once all results are downloaded or the job expires, the job itself is deleted and returns `404`. + version: "1.0.0" + termsOfService: https://www.deepl.com/pro-license + contact: + name: DeepL - Contact us + url: https://www.deepl.com/contact-us + +servers: + - url: https://api.deepl.com + description: DeepL API Pro + - url: https://api-free.deepl.com + description: DeepL API Free + +tags: + - name: VoiceTranslate + description: "**Experimental.** Async voice translation jobs. This API may change without notice." + +paths: + /v1/jobs/voice/translate: + post: + tags: + - VoiceTranslate + operationId: createVoiceTranslateJob + summary: Create a voice translation job + description: |- + Creates an async voice translation job. The response includes an upload URL for the source audio file. + + The request body is validated against the voice/translate schema. Invalid parameters or unsupported target types return `400`. + security: + - auth_header: [] + parameters: + - $ref: '#/components/parameters/IncludeParam' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateJobRequest' + example: + 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" + responses: + "201": + description: Job created successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/CreateJobResponse' + example: + job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" + upload_url: "https://assets.deepl.com/collections/a74d88fb-ed2a-4943-a664-a4512398b994/assets/b1c2d3e4-f5a6-7890-abcd-ef1234567890" + signature: "eyJhbGciOiJIUzI1NiIs..." + "400": + $ref: '#/components/responses/BadRequest' + "401": + $ref: '#/components/responses/Unauthorized' + "403": + $ref: '#/components/responses/Forbidden' + "404": + description: Invalid product/operation combination. + "429": + $ref: '#/components/responses/TooManyRequests' + + /v1/jobs/voice/translate/{job_id}: + get: + tags: + - VoiceTranslate + operationId: getVoiceTranslateJobStatus + summary: Get voice translation job status + description: |- + Returns the current status of a voice translation job, including per-target result statuses. + + When a target's status is `complete`, the response includes a `download_url` and `signature` for that target. Results are returned in the same order as the targets in the create request. + security: + - auth_header: [] + parameters: + - $ref: '#/components/parameters/JobIdParam' + - $ref: '#/components/parameters/IncludeParam' + responses: + "200": + description: Job status retrieved successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/JobStatusResponse' + examples: + processing: + summary: Job still processing + value: + job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" + product: "voice" + operation: "translate" + created_at: "2026-10-01T01:03:03.444Z" + updated_at: "2026-10-01T04:03:03.333Z" + usage: + storage_used: 31457280 + 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" + results: + - status: "processing" + - status: "processing" + complete: + summary: Job with mixed results + value: + job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" + product: "voice" + operation: "translate" + created_at: "2026-10-01T01:03:03.444Z" + updated_at: "2026-10-01T04:03:03.333Z" + usage: + storage_used: 31457280 + 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" + results: + - status: "complete" + download_url: "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6" + signature: "eyJhbGciOiJIUzI1NiIs..." + - status: "failed" + error: + message: "processing failed" + "401": + $ref: '#/components/responses/Unauthorized' + "404": + $ref: '#/components/responses/NotFound' + "429": + $ref: '#/components/responses/TooManyRequests' + +components: + securitySchemes: + auth_header: + type: apiKey + description: >- + Authentication with `Authorization` header and `DeepL-Auth-Key` + authentication scheme. Value format: `DeepL-Auth-Key YOUR_API_KEY` + name: Authorization + in: header + + parameters: + JobIdParam: + name: job_id + in: path + required: true + description: The unique identifier of the job, returned by the create job endpoint. + schema: + type: string + format: uuid + example: "a74d88fb-ed2a-4943-a664-a4512398b994" + + IncludeParam: + name: include + in: query + required: false + description: |- + Additional fields to include in the response. + - `signed_url`: Include pre-signed URLs (`signed_upload_url` on create, `signed_download_url` on status) that can be used without an authorization header. + schema: + type: array + items: + type: string + enum: + - signed_url + style: form + explode: true + + headers: + Retry-After: + description: Number of seconds to wait before retrying the request. + schema: + type: integer + example: 5 + + responses: + BadRequest: + description: Bad request. Check the error message and request parameters. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + message: "/targets/0/type: Value is not valid" + + Unauthorized: + description: Authorization failed. Please supply a valid `DeepL-Auth-Key` via the `Authorization` header. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + message: "Invalid Authorization header" + + Forbidden: + description: Access denied. Your API key does not have permission to use this feature. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + message: "Forbidden" + + NotFound: + description: The requested resource could not be found. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + message: "Not found" + + TooManyRequests: + description: Too many requests. Wait for the duration indicated by the `Retry-After` header before retrying. + headers: + Retry-After: + $ref: '#/components/headers/Retry-After' + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + message: "Too many requests" + + schemas: + ErrorResponse: + type: object + required: + - message + properties: + message: + type: string + description: A human-readable description of the error. + + SourceContentType: + type: string + description: The MIME type of the source audio file. + enum: + - audio/mpeg + - audio/wav + - audio/ogg + - audio/flac + - audio/mp4 + - audio/webm + + SourceFile: + type: object + description: Metadata about the source audio file to be uploaded. + required: + - name + - content_type + - content_length + properties: + name: + type: string + minLength: 1 + description: The file name of the source audio file. + example: "podcast-episode-42.mp3" + content_type: + $ref: '#/components/schemas/SourceContentType' + content_length: + type: integer + format: int64 + minimum: 1 + maximum: 1073741824 + description: The size of the source audio file in bytes. Maximum 1 GB (1,073,741,824 bytes). + example: 15728640 + + SourceLanguage: + type: string + description: BCP-47 language code of the source audio. + enum: + - ar + - cs + - de + - en + - es + - fr + - id + - it + - ja + - ko + - nl + - pl + - pt + - ro + - ru + - sv + - tr + - uk + + TargetLanguage: + type: string + description: BCP-47 language code of the translation target. + enum: + - ar + - bg + - bn + - cs + - da + - de + - el + - en + - en-GB + - en-US + - es + - et + - fi + - fr + - ga + - he + - hr + - hu + - id + - it + - ja + - ko + - lt + - lv + - mt + - nb + - nl + - pl + - pt + - pt-BR + - pt-PT + - ro + - ru + - sk + - sl + - sv + - th + - tl + - tr + - uk + - vi + - zh-Hans + - zh-Hant + + TargetOutputType: + type: string + description: The desired output format for the translation target. + enum: + - text/plain + - audio/opus + - audio/flac + - "audio/pcm;encoding=s16le;rate=16000" + - "audio/pcm;encoding=s16le;rate=24000" + - "audio/pcm;encoding=ulaw;rate=8000" + - "audio/pcm;encoding=alaw;rate=8000" + - "audio/x-matroska;codecs=aac" + - "audio/x-matroska;codecs=flac" + - "audio/x-matroska;codecs=opus" + - "audio/x-matroska;codecs=pcm_s16le;rate=16000" + - "audio/x-matroska;codecs=pcm_s16le;rate=24000" + - "video/mp2t;codecs=aac" + - "video/mp2t;codecs=opus" + - "audio/ogg;codecs=flac" + - "audio/ogg;codecs=opus" + - "audio/webm;codecs=opus" + + JobParameters: + type: object + description: Processing parameters for the voice translation job. + properties: + source_language: + allOf: + - $ref: '#/components/schemas/SourceLanguage' + - description: Language of the source audio. If omitted, the language is detected automatically. + + Target: + type: object + description: A translation target specifying the desired output language and format. + required: + - language + - type + properties: + language: + $ref: '#/components/schemas/TargetLanguage' + type: + $ref: '#/components/schemas/TargetOutputType' + + CreateJobRequest: + type: object + required: + - source_file + - targets + properties: + source_file: + $ref: '#/components/schemas/SourceFile' + parameters: + $ref: '#/components/schemas/JobParameters' + targets: + type: array + minItems: 1 + description: One or more translation targets. Each target produces a separate result. + items: + $ref: '#/components/schemas/Target' + + CreateJobResponse: + type: object + required: + - job_id + - upload_url + - signature + properties: + job_id: + type: string + format: uuid + description: The unique identifier of the created job. + upload_url: + type: string + format: uri + description: |- + The URL to upload the source audio file to via `PUT` with `Content-Type: application/octet-stream`. + Requires the `Authorization: DeepL-Signature {signature}` header. + See [Upload File](/api-reference/jobs-voice-translate#upload-file) for details. + signature: + type: string + description: >- + A short-lived token used to authorize the file upload. + Pass it via the `Authorization` header as `DeepL-Signature {signature}` when uploading to the `upload_url`. + signed_upload_url: + type: string + format: uri + description: A pre-signed upload URL that does not require an authorization header. Only present when `?include=signed_url` is specified. + + SourceFileInfo: + type: object + description: Metadata about the uploaded source file. + required: + - name + - content_type + - content_length + properties: + name: + type: string + description: The file name of the source audio file. + content_type: + type: string + description: The MIME type of the source audio file. + content_length: + type: integer + format: int64 + description: The size of the source audio file in bytes. + + Usage: + type: object + properties: + storage_used: + type: integer + format: int64 + description: Total storage used by this job in bytes, including source and output files. + + ResultStatus: + type: string + description: |- + The processing status of a target result. + - `pending`: Job created, awaiting file upload. + - `uploaded`: File uploaded, awaiting processing. + - `processing`: Translation in progress. + - `complete`: Translation complete, result available for download. + - `downloaded`: Result has been downloaded. Assets are marked for deletion. + - `failed`: Processing failed. See the `error` field for details. + enum: + - pending + - uploaded + - processing + - complete + - downloaded + - failed + + TargetError: + type: object + required: + - message + properties: + message: + type: string + description: A human-readable description of the processing error. + + TargetResult: + type: object + description: The processing result for a single translation target. + required: + - status + properties: + status: + $ref: '#/components/schemas/ResultStatus' + download_url: + type: string + format: uri + description: |- + The URL to download the translated result via `GET`. + Requires the `Authorization: DeepL-Signature {signature}` header. + Only present when `status` is `complete`. + See [Download Result](/api-reference/jobs-voice-translate#download-result) for details. + signature: + type: string + description: A short-lived token used to authorize the result download. Only present when `status` is `complete`. + signed_download_url: + type: string + format: uri + description: A pre-signed download URL that does not require an authorization header. Only present when `status` is `complete` and `?include=signed_url` is specified. + error: + allOf: + - $ref: '#/components/schemas/TargetError' + description: Details about the processing failure. Only present when `status` is `failed`. + + JobStatusResponse: + type: object + required: + - job_id + - product + - operation + - created_at + - updated_at + - usage + - source_file + - parameters + - targets + - results + properties: + job_id: + type: string + format: uuid + description: The unique identifier of the job. + product: + type: string + description: The product identifier. + example: "voice" + operation: + type: string + description: The operation identifier. + example: "translate" + created_at: + type: string + format: date-time + description: When the job was created (ISO 8601). + updated_at: + type: string + format: date-time + description: When the job was last updated (ISO 8601). + usage: + $ref: '#/components/schemas/Usage' + source_file: + $ref: '#/components/schemas/SourceFileInfo' + parameters: + $ref: '#/components/schemas/JobParameters' + targets: + type: array + description: The translation targets as specified in the create request. + items: + $ref: '#/components/schemas/Target' + results: + type: array + description: Per-target processing results, in the same order as the `targets` array. + items: + $ref: '#/components/schemas/TargetResult' diff --git a/api-reference/jobs-voice-translate/create-voice-translate-job.mdx b/api-reference/jobs-voice-translate/create-voice-translate-job.mdx new file mode 100644 index 0000000..9da2298 --- /dev/null +++ b/api-reference/jobs-voice-translate/create-voice-translate-job.mdx @@ -0,0 +1,4 @@ +--- +openapi: post /v1/jobs/voice/translate +title: "Create a voice translation job" +--- diff --git a/api-reference/jobs-voice-translate/get-voice-translate-job-status.mdx b/api-reference/jobs-voice-translate/get-voice-translate-job-status.mdx new file mode 100644 index 0000000..b3a1264 --- /dev/null +++ b/api-reference/jobs-voice-translate/get-voice-translate-job-status.mdx @@ -0,0 +1,4 @@ +--- +openapi: get /v1/jobs/voice/translate/{job_id} +title: "Get voice translation job status" +--- diff --git a/docs.json b/docs.json index a6debbe..9659bbd 100644 --- a/docs.json +++ b/docs.json @@ -265,6 +265,14 @@ "api-reference/voice/websocket-streaming", "api-reference/voice/reconnect-session" ] + }, + { + "group": "Translate Audio Files", + "pages": [ + "api-reference/jobs-voice-translate", + "api-reference/jobs-voice-translate/create-voice-translate-job", + "api-reference/jobs-voice-translate/get-voice-translate-job-status" + ] } ] } From c224c3c6120a846ae24b3d682ba5c32f77d44ae6 Mon Sep 17 00:00:00 2001 From: David Fenster Date: Thu, 23 Apr 2026 13:02:29 -0400 Subject: [PATCH 2/5] docs(jobs): s/experimental/alpha/g also remove from nav bar --- api-reference/jobs-voice-translate.mdx | 2 +- api-reference/jobs-voice-translate.openapi.yaml | 4 ++-- docs.json | 8 -------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/api-reference/jobs-voice-translate.mdx b/api-reference/jobs-voice-translate.mdx index c942201..b75d30b 100644 --- a/api-reference/jobs-voice-translate.mdx +++ b/api-reference/jobs-voice-translate.mdx @@ -6,7 +6,7 @@ public: true --- - **Experimental.** This API may change without notice. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). See [alpha and beta features](/docs/resources/alpha-and-beta-features) for details. + **Alpha.** This API may change without notice. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). See [alpha and beta features](/docs/resources/alpha-and-beta-features) for details. The Voice Translate API provides asynchronous translation of audio files into text or audio in other languages. diff --git a/api-reference/jobs-voice-translate.openapi.yaml b/api-reference/jobs-voice-translate.openapi.yaml index f47c3ed..c4b77ad 100644 --- a/api-reference/jobs-voice-translate.openapi.yaml +++ b/api-reference/jobs-voice-translate.openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.0.3 info: title: DeepL Voice Translate API description: |- - **Experimental.** This API may change without notice. Breaking changes will be communicated via the changelog. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). + **Alpha.** This API may change without notice. Breaking changes will be communicated via the changelog. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). The Voice Translate API provides asynchronous translation of audio files into text or audio in other languages. @@ -51,7 +51,7 @@ servers: tags: - name: VoiceTranslate - description: "**Experimental.** Async voice translation jobs. This API may change without notice." + description: "**Alpha.** Async voice translation jobs. This API may change without notice." paths: /v1/jobs/voice/translate: diff --git a/docs.json b/docs.json index 9659bbd..a6debbe 100644 --- a/docs.json +++ b/docs.json @@ -265,14 +265,6 @@ "api-reference/voice/websocket-streaming", "api-reference/voice/reconnect-session" ] - }, - { - "group": "Translate Audio Files", - "pages": [ - "api-reference/jobs-voice-translate", - "api-reference/jobs-voice-translate/create-voice-translate-job", - "api-reference/jobs-voice-translate/get-voice-translate-job-status" - ] } ] } From 5433be74a059b5fd66a9c0e9776d6a7f72275f23 Mon Sep 17 00:00:00 2001 From: David Fenster Date: Thu, 23 Apr 2026 16:30:37 -0400 Subject: [PATCH 3/5] add voice job api to roadmap file also qualify "job" where the api was just voice translation api so it isnt confused with realtime voice api --- api-reference/jobs-voice-translate.mdx | 4 ++-- api-reference/jobs-voice-translate.openapi.yaml | 4 ++-- docs/resources/roadmap-and-release-notes.mdx | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/api-reference/jobs-voice-translate.mdx b/api-reference/jobs-voice-translate.mdx index b75d30b..248448e 100644 --- a/api-reference/jobs-voice-translate.mdx +++ b/api-reference/jobs-voice-translate.mdx @@ -9,9 +9,9 @@ public: true **Alpha.** This API may change without notice. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). See [alpha and beta features](/docs/resources/alpha-and-beta-features) for details. -The Voice Translate API provides asynchronous translation of audio files into text or audio in other languages. +The Voice Translate Job API provides asynchronous translation of audio files into text or audio in other languages. -Unlike the [real-time Voice API](/api-reference/voice), which streams audio over a WebSocket connection, the Voice Translate API processes entire audio files asynchronously. This makes it suitable for pre-recorded content such as podcasts, meeting recordings, or media files up to 1 GB. +Unlike the [real-time Voice API](/api-reference/voice), which streams audio over a WebSocket connection, the Voice Translate Job API processes entire audio files asynchronously. This makes it suitable for pre-recorded content such as podcasts, meeting recordings, or media files up to 1 GB. Each job can produce multiple translation targets simultaneously. For example, a single English podcast can be translated into German text and Spanish audio in one job. diff --git a/api-reference/jobs-voice-translate.openapi.yaml b/api-reference/jobs-voice-translate.openapi.yaml index c4b77ad..3a2ffbe 100644 --- a/api-reference/jobs-voice-translate.openapi.yaml +++ b/api-reference/jobs-voice-translate.openapi.yaml @@ -1,10 +1,10 @@ openapi: 3.0.3 info: - title: DeepL Voice Translate API + title: DeepL Voice Translate Job API description: |- **Alpha.** This API may change without notice. Breaking changes will be communicated via the changelog. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). - The Voice Translate API provides asynchronous translation of audio files into text or audio in other languages. + The Voice Translate Job API provides asynchronous translation of audio files into text or audio in other languages. ## Workflow diff --git a/docs/resources/roadmap-and-release-notes.mdx b/docs/resources/roadmap-and-release-notes.mdx index 5b48ce0..16ab0db 100644 --- a/docs/resources/roadmap-and-release-notes.mdx +++ b/docs/resources/roadmap-and-release-notes.mdx @@ -12,6 +12,10 @@ rss: true +## April 23 - Voice Translate Job API (Alpha) +- Added the [Voice Translate Job API](/api-reference/jobs-voice-translate) for asynchronous translation of pre-recorded audio files into text or audio in other languages. Suitable for podcasts, meeting recordings, and media files up to 1 GB. +- This is an alpha feature. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). See [alpha and beta features](/docs/resources/alpha-and-beta-features) for details. + ## April 17 - New Language Variants: German (Swiss) and French (Canadian) - Added support for two new target language variants: `de-CH` (German, Swiss) and `fr-CA` (French, Canadian) for text translation. These variants are now generally available. - Use these language codes as `target_lang` values to produce translations tailored to Swiss German and Canadian French. From 8f77c357f342f2b2ca9d085b1c01fd7d63f4d0dc Mon Sep 17 00:00:00 2001 From: David Fenster Date: Thu, 23 Apr 2026 16:38:20 -0400 Subject: [PATCH 4/5] remove jobs voice api doc and roadmap change --- .../jobs-voice-translate.openapi.yaml | 620 ------------------ docs/resources/roadmap-and-release-notes.mdx | 4 - 2 files changed, 624 deletions(-) delete mode 100644 api-reference/jobs-voice-translate.openapi.yaml diff --git a/api-reference/jobs-voice-translate.openapi.yaml b/api-reference/jobs-voice-translate.openapi.yaml deleted file mode 100644 index 3a2ffbe..0000000 --- a/api-reference/jobs-voice-translate.openapi.yaml +++ /dev/null @@ -1,620 +0,0 @@ -openapi: 3.0.3 -info: - title: DeepL Voice Translate Job API - description: |- - **Alpha.** This API may change without notice. Breaking changes will be communicated via the changelog. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). - - The Voice Translate Job API provides asynchronous translation of audio files into text or audio in other languages. - - ## Workflow - - Translating an audio file is a four-step process: - - 1. **Create Job** (`POST /v1/jobs/voice/translate`): Submit file metadata, processing parameters, and translation targets. The response includes the `job_id`, an `upload_url`, and a `signature`. If `?include=signed_url` is specified, a `signed_upload_url` is also returned. - 2. **Upload File** (`PUT {upload_url}`): Upload the audio file directly to the storage service. Use one of: - - `PUT {upload_url}` with header `Authorization: DeepL-Signature {signature}` and `Content-Type: application/octet-stream` - - `PUT {signed_upload_url}` with `Content-Type: application/octet-stream` (no authorization header needed) - 3. **Poll Status** (`GET /v1/jobs/voice/translate/{job_id}`): Check the job status. Each target has its own status. When a target reaches `complete`, the response includes a `download_url` and `signature` for that target. If `?include=signed_url` is specified, a `signed_download_url` is also returned. - 4. **Download Result** (`GET {download_url}`): Retrieve the translated output directly from the storage service. Use one of: - - `GET {download_url}` with header `Authorization: DeepL-Signature {signature}` - - `GET {signed_download_url}` (no authorization header needed) - - Upload and download URLs are opaque and returned by the API. Do not construct them manually. - - ## Choosing an Authentication Method - - The API supports two ways to authenticate uploads and downloads. Both methods use time-limited credentials. - - - **Authorization header (recommended)**: Use the `upload_url` or `download_url` with the header `Authorization: DeepL-Signature {signature}`. This keeps credentials out of the URL, preventing leaks through server logs, browser history, or referrer headers. It also protects against man-in-the-middle interception; a leaked signed URL could allow an attacker to upload malicious content to your job. - - **Signed URL**: Request a pre-signed URL by adding `?include=signed_url` to the create or poll request. The returned `signed_upload_url` or `signed_download_url` embeds the credential in the URL itself, so no authorization header is needed. This is useful when delegating uploads or downloads to browsers, mobile clients, or third-party systems that cannot set custom headers. - - Use the authorization header by default. Use signed URLs only when the consuming system cannot set custom HTTP headers. - - ## Result Status Lifecycle - - Each target result progresses through the following statuses: - - `pending` -> `uploaded` -> `processing` -> `complete` -> `downloaded` - - A target may also transition to `failed` at any point during processing. After a result is downloaded, its assets are marked for deletion and the status becomes `downloaded`. Once all results are downloaded or the job expires, the job itself is deleted and returns `404`. - version: "1.0.0" - termsOfService: https://www.deepl.com/pro-license - contact: - name: DeepL - Contact us - url: https://www.deepl.com/contact-us - -servers: - - url: https://api.deepl.com - description: DeepL API Pro - - url: https://api-free.deepl.com - description: DeepL API Free - -tags: - - name: VoiceTranslate - description: "**Alpha.** Async voice translation jobs. This API may change without notice." - -paths: - /v1/jobs/voice/translate: - post: - tags: - - VoiceTranslate - operationId: createVoiceTranslateJob - summary: Create a voice translation job - description: |- - Creates an async voice translation job. The response includes an upload URL for the source audio file. - - The request body is validated against the voice/translate schema. Invalid parameters or unsupported target types return `400`. - security: - - auth_header: [] - parameters: - - $ref: '#/components/parameters/IncludeParam' - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/CreateJobRequest' - example: - 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" - responses: - "201": - description: Job created successfully. - content: - application/json: - schema: - $ref: '#/components/schemas/CreateJobResponse' - example: - job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" - upload_url: "https://assets.deepl.com/collections/a74d88fb-ed2a-4943-a664-a4512398b994/assets/b1c2d3e4-f5a6-7890-abcd-ef1234567890" - signature: "eyJhbGciOiJIUzI1NiIs..." - "400": - $ref: '#/components/responses/BadRequest' - "401": - $ref: '#/components/responses/Unauthorized' - "403": - $ref: '#/components/responses/Forbidden' - "404": - description: Invalid product/operation combination. - "429": - $ref: '#/components/responses/TooManyRequests' - - /v1/jobs/voice/translate/{job_id}: - get: - tags: - - VoiceTranslate - operationId: getVoiceTranslateJobStatus - summary: Get voice translation job status - description: |- - Returns the current status of a voice translation job, including per-target result statuses. - - When a target's status is `complete`, the response includes a `download_url` and `signature` for that target. Results are returned in the same order as the targets in the create request. - security: - - auth_header: [] - parameters: - - $ref: '#/components/parameters/JobIdParam' - - $ref: '#/components/parameters/IncludeParam' - responses: - "200": - description: Job status retrieved successfully. - content: - application/json: - schema: - $ref: '#/components/schemas/JobStatusResponse' - examples: - processing: - summary: Job still processing - value: - job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" - product: "voice" - operation: "translate" - created_at: "2026-10-01T01:03:03.444Z" - updated_at: "2026-10-01T04:03:03.333Z" - usage: - storage_used: 31457280 - 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" - results: - - status: "processing" - - status: "processing" - complete: - summary: Job with mixed results - value: - job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" - product: "voice" - operation: "translate" - created_at: "2026-10-01T01:03:03.444Z" - updated_at: "2026-10-01T04:03:03.333Z" - usage: - storage_used: 31457280 - 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" - results: - - status: "complete" - download_url: "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6" - signature: "eyJhbGciOiJIUzI1NiIs..." - - status: "failed" - error: - message: "processing failed" - "401": - $ref: '#/components/responses/Unauthorized' - "404": - $ref: '#/components/responses/NotFound' - "429": - $ref: '#/components/responses/TooManyRequests' - -components: - securitySchemes: - auth_header: - type: apiKey - description: >- - Authentication with `Authorization` header and `DeepL-Auth-Key` - authentication scheme. Value format: `DeepL-Auth-Key YOUR_API_KEY` - name: Authorization - in: header - - parameters: - JobIdParam: - name: job_id - in: path - required: true - description: The unique identifier of the job, returned by the create job endpoint. - schema: - type: string - format: uuid - example: "a74d88fb-ed2a-4943-a664-a4512398b994" - - IncludeParam: - name: include - in: query - required: false - description: |- - Additional fields to include in the response. - - `signed_url`: Include pre-signed URLs (`signed_upload_url` on create, `signed_download_url` on status) that can be used without an authorization header. - schema: - type: array - items: - type: string - enum: - - signed_url - style: form - explode: true - - headers: - Retry-After: - description: Number of seconds to wait before retrying the request. - schema: - type: integer - example: 5 - - responses: - BadRequest: - description: Bad request. Check the error message and request parameters. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - example: - message: "/targets/0/type: Value is not valid" - - Unauthorized: - description: Authorization failed. Please supply a valid `DeepL-Auth-Key` via the `Authorization` header. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - example: - message: "Invalid Authorization header" - - Forbidden: - description: Access denied. Your API key does not have permission to use this feature. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - example: - message: "Forbidden" - - NotFound: - description: The requested resource could not be found. - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - example: - message: "Not found" - - TooManyRequests: - description: Too many requests. Wait for the duration indicated by the `Retry-After` header before retrying. - headers: - Retry-After: - $ref: '#/components/headers/Retry-After' - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - example: - message: "Too many requests" - - schemas: - ErrorResponse: - type: object - required: - - message - properties: - message: - type: string - description: A human-readable description of the error. - - SourceContentType: - type: string - description: The MIME type of the source audio file. - enum: - - audio/mpeg - - audio/wav - - audio/ogg - - audio/flac - - audio/mp4 - - audio/webm - - SourceFile: - type: object - description: Metadata about the source audio file to be uploaded. - required: - - name - - content_type - - content_length - properties: - name: - type: string - minLength: 1 - description: The file name of the source audio file. - example: "podcast-episode-42.mp3" - content_type: - $ref: '#/components/schemas/SourceContentType' - content_length: - type: integer - format: int64 - minimum: 1 - maximum: 1073741824 - description: The size of the source audio file in bytes. Maximum 1 GB (1,073,741,824 bytes). - example: 15728640 - - SourceLanguage: - type: string - description: BCP-47 language code of the source audio. - enum: - - ar - - cs - - de - - en - - es - - fr - - id - - it - - ja - - ko - - nl - - pl - - pt - - ro - - ru - - sv - - tr - - uk - - TargetLanguage: - type: string - description: BCP-47 language code of the translation target. - enum: - - ar - - bg - - bn - - cs - - da - - de - - el - - en - - en-GB - - en-US - - es - - et - - fi - - fr - - ga - - he - - hr - - hu - - id - - it - - ja - - ko - - lt - - lv - - mt - - nb - - nl - - pl - - pt - - pt-BR - - pt-PT - - ro - - ru - - sk - - sl - - sv - - th - - tl - - tr - - uk - - vi - - zh-Hans - - zh-Hant - - TargetOutputType: - type: string - description: The desired output format for the translation target. - enum: - - text/plain - - audio/opus - - audio/flac - - "audio/pcm;encoding=s16le;rate=16000" - - "audio/pcm;encoding=s16le;rate=24000" - - "audio/pcm;encoding=ulaw;rate=8000" - - "audio/pcm;encoding=alaw;rate=8000" - - "audio/x-matroska;codecs=aac" - - "audio/x-matroska;codecs=flac" - - "audio/x-matroska;codecs=opus" - - "audio/x-matroska;codecs=pcm_s16le;rate=16000" - - "audio/x-matroska;codecs=pcm_s16le;rate=24000" - - "video/mp2t;codecs=aac" - - "video/mp2t;codecs=opus" - - "audio/ogg;codecs=flac" - - "audio/ogg;codecs=opus" - - "audio/webm;codecs=opus" - - JobParameters: - type: object - description: Processing parameters for the voice translation job. - properties: - source_language: - allOf: - - $ref: '#/components/schemas/SourceLanguage' - - description: Language of the source audio. If omitted, the language is detected automatically. - - Target: - type: object - description: A translation target specifying the desired output language and format. - required: - - language - - type - properties: - language: - $ref: '#/components/schemas/TargetLanguage' - type: - $ref: '#/components/schemas/TargetOutputType' - - CreateJobRequest: - type: object - required: - - source_file - - targets - properties: - source_file: - $ref: '#/components/schemas/SourceFile' - parameters: - $ref: '#/components/schemas/JobParameters' - targets: - type: array - minItems: 1 - description: One or more translation targets. Each target produces a separate result. - items: - $ref: '#/components/schemas/Target' - - CreateJobResponse: - type: object - required: - - job_id - - upload_url - - signature - properties: - job_id: - type: string - format: uuid - description: The unique identifier of the created job. - upload_url: - type: string - format: uri - description: |- - The URL to upload the source audio file to via `PUT` with `Content-Type: application/octet-stream`. - Requires the `Authorization: DeepL-Signature {signature}` header. - See [Upload File](/api-reference/jobs-voice-translate#upload-file) for details. - signature: - type: string - description: >- - A short-lived token used to authorize the file upload. - Pass it via the `Authorization` header as `DeepL-Signature {signature}` when uploading to the `upload_url`. - signed_upload_url: - type: string - format: uri - description: A pre-signed upload URL that does not require an authorization header. Only present when `?include=signed_url` is specified. - - SourceFileInfo: - type: object - description: Metadata about the uploaded source file. - required: - - name - - content_type - - content_length - properties: - name: - type: string - description: The file name of the source audio file. - content_type: - type: string - description: The MIME type of the source audio file. - content_length: - type: integer - format: int64 - description: The size of the source audio file in bytes. - - Usage: - type: object - properties: - storage_used: - type: integer - format: int64 - description: Total storage used by this job in bytes, including source and output files. - - ResultStatus: - type: string - description: |- - The processing status of a target result. - - `pending`: Job created, awaiting file upload. - - `uploaded`: File uploaded, awaiting processing. - - `processing`: Translation in progress. - - `complete`: Translation complete, result available for download. - - `downloaded`: Result has been downloaded. Assets are marked for deletion. - - `failed`: Processing failed. See the `error` field for details. - enum: - - pending - - uploaded - - processing - - complete - - downloaded - - failed - - TargetError: - type: object - required: - - message - properties: - message: - type: string - description: A human-readable description of the processing error. - - TargetResult: - type: object - description: The processing result for a single translation target. - required: - - status - properties: - status: - $ref: '#/components/schemas/ResultStatus' - download_url: - type: string - format: uri - description: |- - The URL to download the translated result via `GET`. - Requires the `Authorization: DeepL-Signature {signature}` header. - Only present when `status` is `complete`. - See [Download Result](/api-reference/jobs-voice-translate#download-result) for details. - signature: - type: string - description: A short-lived token used to authorize the result download. Only present when `status` is `complete`. - signed_download_url: - type: string - format: uri - description: A pre-signed download URL that does not require an authorization header. Only present when `status` is `complete` and `?include=signed_url` is specified. - error: - allOf: - - $ref: '#/components/schemas/TargetError' - description: Details about the processing failure. Only present when `status` is `failed`. - - JobStatusResponse: - type: object - required: - - job_id - - product - - operation - - created_at - - updated_at - - usage - - source_file - - parameters - - targets - - results - properties: - job_id: - type: string - format: uuid - description: The unique identifier of the job. - product: - type: string - description: The product identifier. - example: "voice" - operation: - type: string - description: The operation identifier. - example: "translate" - created_at: - type: string - format: date-time - description: When the job was created (ISO 8601). - updated_at: - type: string - format: date-time - description: When the job was last updated (ISO 8601). - usage: - $ref: '#/components/schemas/Usage' - source_file: - $ref: '#/components/schemas/SourceFileInfo' - parameters: - $ref: '#/components/schemas/JobParameters' - targets: - type: array - description: The translation targets as specified in the create request. - items: - $ref: '#/components/schemas/Target' - results: - type: array - description: Per-target processing results, in the same order as the `targets` array. - items: - $ref: '#/components/schemas/TargetResult' diff --git a/docs/resources/roadmap-and-release-notes.mdx b/docs/resources/roadmap-and-release-notes.mdx index 16ab0db..5b48ce0 100644 --- a/docs/resources/roadmap-and-release-notes.mdx +++ b/docs/resources/roadmap-and-release-notes.mdx @@ -12,10 +12,6 @@ rss: true -## April 23 - Voice Translate Job API (Alpha) -- Added the [Voice Translate Job API](/api-reference/jobs-voice-translate) for asynchronous translation of pre-recorded audio files into text or audio in other languages. Suitable for podcasts, meeting recordings, and media files up to 1 GB. -- This is an alpha feature. To request access, [submit a support request](https://support.deepl.com/hc/en-us/requests/new). See [alpha and beta features](/docs/resources/alpha-and-beta-features) for details. - ## April 17 - New Language Variants: German (Swiss) and French (Canadian) - Added support for two new target language variants: `de-CH` (German, Swiss) and `fr-CA` (French, Canadian) for text translation. These variants are now generally available. - Use these language codes as `target_lang` values to produce translations tailored to Swiss German and Canadian French. From 30c0675a1a95dab7bcd0342cc60e98016e07dce9 Mon Sep 17 00:00:00 2001 From: David Fenster Date: Fri, 24 Apr 2026 14:58:10 -0400 Subject: [PATCH 5/5] update voice job api schema to prep for alpha --- api-reference/openapi.yaml | 428 +++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index ff919a7..c07d4f4 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -85,6 +85,8 @@ tags: description: |- The Voice API provides real-time voice transcription and translation services. Use a two-step flow: first request a streaming URL via REST, then establish a WebSocket connection for streaming audio and receiving transcriptions. +- name: VoiceTranslateJob + description: "**Alpha.** Async voice translation jobs. This API may change without notice." x-hideTryItPanel: true x-codeSamples: false paths: @@ -2929,6 +2931,135 @@ paths: $ref: '#/components/responses/ServiceUnavailable' security: - auth_header: [] + /v1/jobs/voice/translate: + post: + tags: + - VoiceTranslateJob + operationId: createVoiceTranslateJob + summary: Create a voice translation job + description: Creates an async voice translation job. The response includes an upload URL for the source audio file. + security: + - auth_header: [] + parameters: + - $ref: '#/components/parameters/VoiceTranslateJobIncludeParam' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VoiceTranslateCreateJobRequest' + example: + 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" + responses: + "201": + description: Job created successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/VoiceTranslateCreateJobResponse' + example: + job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" + upload_url: "https://assets.deepl.com/collections/a74d88fb-ed2a-4943-a664-a4512398b994/assets/b1c2d3e4-f5a6-7890-abcd-ef1234567890" + signature: "eyJhbGciOiJIUzI1NiIs..." + "400": + $ref: '#/components/responses/VoiceTranslateJobBadRequest' + "401": + $ref: '#/components/responses/Unauthorized' + "403": + $ref: '#/components/responses/Forbidden' + "429": + $ref: '#/components/responses/TooManyRequests' + /v1/jobs/voice/translate/{job_id}: + get: + tags: + - VoiceTranslateJob + operationId: getVoiceTranslateJobStatus + summary: Get voice translation job status + description: |- + Returns the current status of a voice translation job, including per-target result statuses. + + When a target's status is `complete`, the response includes a `download_url` and `signature` for that target. Results are returned in the same order as the targets in the create request. + security: + - auth_header: [] + parameters: + - $ref: '#/components/parameters/VoiceTranslateJobIdParam' + - $ref: '#/components/parameters/VoiceTranslateJobIncludeParam' + responses: + "200": + description: Job status retrieved successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/VoiceTranslateJobStatusResponse' + examples: + processing: + summary: Job still processing + value: + job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" + product: "voice" + operation: "translate" + created_at: "2026-10-01T01:03:03.444Z" + updated_at: "2026-10-01T04:03:03.333Z" + usage: + storage_used: 31457280 + 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" + results: + - status: "processing" + - status: "processing" + complete: + summary: Job with mixed results + value: + job_id: "a74d88fb-ed2a-4943-a664-a4512398b994" + product: "voice" + operation: "translate" + created_at: "2026-10-01T01:03:03.444Z" + updated_at: "2026-10-01T04:03:03.333Z" + usage: + storage_used: 31457280 + 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" + results: + - status: "complete" + download_url: "https://assets.deepl.com/collections/a74d88fb/assets/c3d4e5f6" + signature: "eyJhbGciOiJIUzI1NiIs..." + - status: "failed" + error: + message: "processing failed" + "401": + $ref: '#/components/responses/Unauthorized' + "404": + $ref: '#/components/responses/NotFound' + "429": + $ref: '#/components/responses/TooManyRequests' components: headers: X-Trace-ID: @@ -2946,6 +3077,30 @@ components: schema: type: string example: 04DE5AD98A02647D83285A36021911C6 + VoiceTranslateJobIdParam: + name: job_id + in: path + required: true + description: The unique identifier of the job, returned by the create job endpoint. + schema: + type: string + format: uuid + example: "a74d88fb-ed2a-4943-a664-a4512398b994" + VoiceTranslateJobIncludeParam: + name: include + in: query + required: false + description: |- + Additional fields to include in the response. + - `signed_url`: Include pre-signed URLs (`signed_upload_url` on create, `signed_download_url` on status) that can be used without an authorization header. + schema: + type: array + items: + type: string + enum: + - signed_url + style: form + explode: true GlossaryID: name: glossary_id description: A unique ID assigned to the glossary. @@ -2965,6 +3120,14 @@ components: schema: $ref: '#/components/schemas/TargetLanguage' responses: + VoiceTranslateJobBadRequest: + description: Bad request. Check the error message and request parameters. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + message: "/targets/0/type: Value is not valid" BadRequest: description: Bad request. Please check error message and your parameters. BadRequestGlossaries: @@ -5488,3 +5651,268 @@ components: example: "DeepL API Key Prod" usage: $ref: '#/components/schemas/UsageBreakdown' + ErrorResponse: + type: object + required: + - message + properties: + message: + type: string + description: A human-readable description of the error. + code: + type: string + description: A machine-readable identifier for the error, when available. Clients should match on this value rather than on `message` when branching on error types. + example: "invalid_content_type" + VoiceTranslateJobSourceContentType: + type: string + description: The MIME type of the source audio file. + enum: + - audio/mpeg + - audio/wav + - audio/ogg + - audio/flac + - audio/mp4 + - audio/webm + JobSourceFileRequest: + type: object + description: Metadata about the source audio file to be uploaded. + required: + - name + - content_type + - content_length + properties: + name: + type: string + minLength: 1 + description: The file name of the source audio file. + example: "podcast-episode-42.mp3" + content_type: + $ref: '#/components/schemas/VoiceTranslateJobSourceContentType' + content_length: + type: integer + format: int64 + minimum: 1 + maximum: 1073741824 + description: The size of the source audio file in bytes. Maximum 1 GB (1,073,741,824 bytes). + example: 15728640 + JobSourceFileResponse: + type: object + description: Metadata about the uploaded source audio file. + required: + - name + - content_type + - content_length + properties: + name: + type: string + description: The file name of the source audio file. + content_type: + type: string + description: The MIME type of the source audio file. + content_length: + type: integer + format: int64 + description: The size of the source audio file in bytes. + VoiceTranslateJobTargetOutputType: + type: string + description: The desired output format for the translation target. + enum: + - text/plain + - audio/opus + - audio/flac + - "audio/pcm;encoding=s16le;rate=16000" + - "audio/pcm;encoding=s16le;rate=24000" + - "audio/pcm;encoding=ulaw;rate=8000" + - "audio/pcm;encoding=alaw;rate=8000" + - "audio/x-matroska;codecs=aac" + - "audio/x-matroska;codecs=flac" + - "audio/x-matroska;codecs=opus" + - "audio/x-matroska;codecs=pcm_s16le;rate=16000" + - "audio/x-matroska;codecs=pcm_s16le;rate=24000" + - "video/mp2t;codecs=aac" + - "video/mp2t;codecs=opus" + - "audio/ogg;codecs=flac" + - "audio/ogg;codecs=opus" + - "audio/webm;codecs=opus" + VoiceTranslateJobParametersRequest: + type: object + description: Processing parameters for the voice translation job. + properties: + source_language: + allOf: + - $ref: '#/components/schemas/SourceLanguage' + - description: Language of the source audio. If omitted, the language is detected automatically. + VoiceTranslateJobParametersResponse: + type: object + description: Processing parameters as applied to the voice translation job. + properties: + source_language: + allOf: + - $ref: '#/components/schemas/SourceLanguage' + - description: Language of the source audio. + VoiceTranslateJobTargetRequest: + type: object + description: A translation target specifying the desired output language and format. + required: + - language + - type + properties: + language: + $ref: '#/components/schemas/TargetLanguage' + type: + $ref: '#/components/schemas/VoiceTranslateJobTargetOutputType' + VoiceTranslateJobTargetResponse: + type: object + description: A translation target as recorded on the job. + required: + - language + - type + properties: + language: + $ref: '#/components/schemas/TargetLanguage' + type: + $ref: '#/components/schemas/VoiceTranslateJobTargetOutputType' + VoiceTranslateCreateJobRequest: + type: object + required: + - source_file + - targets + properties: + source_file: + $ref: '#/components/schemas/JobSourceFileRequest' + parameters: + $ref: '#/components/schemas/VoiceTranslateJobParametersRequest' + targets: + type: array + minItems: 1 + description: One or more translation targets. Each target produces a separate result. + items: + $ref: '#/components/schemas/VoiceTranslateJobTargetRequest' + VoiceTranslateCreateJobResponse: + type: object + required: + - job_id + - upload_url + - signature + properties: + job_id: + type: string + format: uuid + description: The unique identifier of the created job. + upload_url: + type: string + format: uri + description: |- + The URL to upload the source audio file to via `PUT` with `Content-Type: application/octet-stream`. + Requires the `Authorization: DeepL-Signature {signature}` header. + See [Upload File](/api-reference/jobs-voice-translate#upload-file) for details. + signature: + type: string + description: >- + A short-lived token used to authorize the file upload. + Pass it via the `Authorization` header as `DeepL-Signature {signature}` when uploading to the `upload_url`. + signed_upload_url: + type: string + format: uri + description: A pre-signed upload URL that does not require an authorization header. Only present when `?include=signed_url` is specified. + JobUsage: + type: object + properties: + storage_used: + type: integer + format: int64 + description: Total storage used by this job in bytes, including source and output files. + ResultStatus: + type: string + description: |- + The processing status of a target result. + - `pending`: Job created, awaiting file upload. + - `uploaded`: File uploaded, awaiting processing. + - `processing`: Translation in progress. + - `complete`: Translation complete, result available for download. + - `downloaded`: Result has been downloaded. Assets are marked for deletion. + - `failed`: Processing failed. See the `error` field for details. + enum: + - pending + - uploaded + - processing + - complete + - downloaded + - failed + VoiceTranslateJobTargetResult: + type: object + description: The processing result for a single translation target. + required: + - status + properties: + status: + $ref: '#/components/schemas/ResultStatus' + download_url: + type: string + format: uri + description: |- + The URL to download the translated result via `GET`. + Requires the `Authorization: DeepL-Signature {signature}` header. + Only present when `status` is `complete`. + See [Download Result](/api-reference/jobs-voice-translate#download-result) for details. + signature: + type: string + description: A short-lived token used to authorize the result download. Only present when `status` is `complete`. + signed_download_url: + type: string + format: uri + description: A pre-signed download URL that does not require an authorization header. Only present when `status` is `complete` and `?include=signed_url` is specified. + error: + allOf: + - $ref: '#/components/schemas/ErrorResponse' + description: Details about the processing failure. Only present when `status` is `failed`. + VoiceTranslateJobStatusResponse: + type: object + required: + - job_id + - product + - operation + - created_at + - updated_at + - usage + - source_file + - parameters + - targets + - results + properties: + job_id: + type: string + format: uuid + description: The unique identifier of the job. + product: + type: string + description: The product identifier. + example: "voice" + operation: + type: string + description: The operation identifier. + example: "translate" + created_at: + type: string + format: date-time + description: When the job was created (ISO 8601). + updated_at: + type: string + format: date-time + description: When the job was last updated (ISO 8601). + usage: + $ref: '#/components/schemas/JobUsage' + source_file: + $ref: '#/components/schemas/JobSourceFileResponse' + parameters: + $ref: '#/components/schemas/VoiceTranslateJobParametersResponse' + targets: + type: array + description: The translation targets as specified in the create request. + items: + $ref: '#/components/schemas/VoiceTranslateJobTargetResponse' + results: + type: array + description: Per-target processing results, in the same order as the `targets` array. + items: + $ref: '#/components/schemas/VoiceTranslateJobTargetResult'