Skip to main content
In this tutorial you’ll run a small Python program that captures audio from your microphone, streams it to the DeepL Voice API, and prints the transcript plus German and French translations to your terminal, sentence by sentence, while you speak. The same pattern works for any live audio source: a meeting bot, a phone bridge, or a broadcast feed.

Prerequisites

Building with an AI coding agent?

Wire it up to the DeepL Docs MCP Server so it can search and read this documentation while it writes code. In Claude Code:
Then describe what you want to build. To get the same result as this tutorial, paste:
Setup instructions for Claude Desktop, Cursor, VS Code, and other MCP clients are on the Docs MCP Server page.

Run the complete example

Install the dependencies:
Then save this as live_translation.py and replace YOUR_AUTH_KEY with your DeepL API key:
live_translation.py
Run it and speak in any supported source language. Each sentence prints once it’s final, first the transcript, then each translation. Press Ctrl+C when you’re done: the script stops recording, waits for the remaining results, and exits cleanly.

How it works

The program does three things: it creates a session over HTTPS, streams audio to the WebSocket URL it gets back, and handles result messages until the server confirms everything is final.

The session request

create_session sends a POST request with the audio format and target languages. The only required field is source_media_content_type; for raw microphone audio, that’s PCM at 16 kHz. The response contains the WebSocket URL and a one-time token, and the program connects to {streaming_url}?token={token}:
If you know the speaker’s language in advance, add "source_language": "en" and "source_language_mode": "fixed" to the request body. This skips language detection and reduces latency. Without them, the language is detected automatically. See the Request Session reference for all parameters, including glossary and formality options.

Sending audio

send_microphone_audio sends each 200-millisecond microphone chunk as a JSON text message with the raw audio base64-encoded:
Keep chunks between 50 and 250 milliseconds for the best latency. When the audio ends (Ctrl+C or the safety cap), the function sends one final message that tells the API to finalize all pending results:

Receiving transcripts and translations

While audio is being sent, the server pushes source_transcript_update and target_transcript_update messages on the same connection:
Concluded segments are final and sent only once; tentative segments are provisional and refined by later updates. receive_results appends concluded text to a per-language buffer and prints the buffer whenever a sentence completes, which keeps the terminal readable. A UI would also render the tentative text as a live preview that updates in place; see Understanding Voice Sessions for this delivery model. After end_of_source_media, the server sends the remaining updates, then end_of_stream as the very last message, at which point it’s safe to close the connection. See the WebSocket Streaming reference for the full message schema.

Reconnecting after a drop

Networks drop, and the Voice API lets you resume a session instead of starting over. If the WebSocket closes unexpectedly, exchange your token for a fresh streaming URL and token, then reconnect. Session state, including configuration and translation context, is preserved.
The response has the same shape as the session response above. Always pass the token from your most recent session or reconnection response: each token is single-use, and presenting an outdated one invalidates the session (a 400-level error). In that case, create a new session with create_session(). To add this to the example, wrap the websockets.connect block in a try/except websockets.exceptions.ConnectionClosed loop that calls reconnect() and connects again with the new URL and token.

Simulate a live stream from a file

If you don’t have a microphone, or you want reproducible input while developing, stream a pre-recorded file at real-time pace instead. Set "source_media_content_type": "audio/auto" in the session request so the format is detected, and swap send_microphone_audio for a reader that paces itself:
Any recording of speech in a supported format works, for example an MP3 of a podcast episode.
Don’t send audio faster than 2x real-time. Uploading a file as fast as the network allows triggers rate limits and terminates the session.

Next steps