Skip to main content
In this guide, you’ll translate a pre-recorded audio file into multiple languages using the Voice Translate Job API. You’ll create a job, upload the source file, poll for results, and download each completed output. The example translates an English podcast episode into a German plain-text transcript and a Spanish PCM audio file.
The Voice Translate Job API is in closed alpha. It is only available to select DeepL customers and may change without notice. Contact your customer success manager to request access.
For live audio, use the real-time Voice API instead.

Prerequisites

  • A DeepL API key with Voice Translate Job API access
  • An audio file in a supported source format
  • curl and jq (for the shell examples below)

The four-step workflow

Every translation follows the same pattern: create a job, upload the file, poll for status, then download results.
The API processes jobs asynchronously, so polling is required. Results for each target are produced independently: a target can complete or fail while others are still processing.

Step 1: Create the job

Send a POST request with your file metadata and translation targets. The response gives you an upload_url to put your file and a job_id to track progress.
If you are using a DeepL API Free account, replace https://api.deepl.com with https://api-free.deepl.com in all requests.
A successful response returns HTTP 201:
Save the job_id and upload_url — you need both in the next step. You have 5 minutes to upload the file after creating the job; if you miss the window, the job expires and you must create a new one. The content_length in the request must match the actual file size in bytes. A mismatch causes the upload to fail.
The curl snippets in Steps 1–4 are illustrative. They show each API call in isolation and do not automatically pass values (such as job_id or upload_url) between steps. For a fully runnable end-to-end example that captures and threads these values automatically, see the complete shell script below.

Step 2: Upload the source file

PUT your audio file directly to the upload_url from step 1. Set Content-Type to match the content_type you declared when creating the job.
A successful upload returns HTTP 200 with no body. The job transitions from pending to uploaded, and processing begins automatically. The upload URL is pre-signed and single-use. Do not add the Authorization header to this request — it goes directly to object storage.

Step 3: Poll for job status

Check the job status by sending a GET request with your job_id. Each target in the results array has its own status field.
While processing, the response looks like this:
Results are returned in the same order as the targets in your create request. Poll every 5–10 seconds. Non-terminal statuses include pending, uploaded, and processing. Terminal statuses are complete, failed, and downloaded. When a target completes, its result includes a download_url:
Targets can complete or fail independently. Download completed targets as they finish rather than waiting for all targets to complete.

Step 4: Download the results

Fetch each completed target using its download_url. Save the output with an appropriate file extension for the content type. Capture the poll response and extract each URL, then download each file separately:
A successful download returns HTTP 200 with the file content as the response body. No JSON envelope is returned. Download URLs are also single-use and don’t require an Authorization header. Once you download a result, the target transitions to downloaded. Results are deleted after download, or after 1 hour from when they became available — whichever comes first. After all targets are terminal, the job is deleted and returns 404 on subsequent status checks.

Verify the output

After the script completes, confirm the following:
  • transcript-de.txt contains readable German text — open the file and check that the transcript reflects the spoken content of your source audio.
  • audio-es.pcm is a valid audio file — play it with a tool that accepts raw PCM (for example, ffplay -f s16le -ar 16000 -ac 1 audio-es.pcm) and confirm you hear Spanish speech.
If either file is empty or unreadable, the download URL may have expired or been consumed by a previous request. Re-run the polling step to check the target status before attempting another download.

Handling failures

A target’s error.message describes what went wrong, but won’t always be specific enough to act on directly. Common causes:
  • Audio quality: very low bitrate or heavily distorted audio can cause processing to fail for a specific target
  • Format mismatch: the declared content_type doesn’t match the actual file encoding
  • Quota: check your concurrent job limits if failures correlate with high submission volume
When some targets fail and others complete, download the successful results before investigating failures. A single-target failure does not affect other targets in the same job.

Complete shell script

This script ties all four steps together and polls until every target reaches a terminal state.
translate_audio.sh

Next steps