Automatic Translation
Lesson rewritten November 3, 2026. It previously relied on the
/v1/audio/translationsendpoint andwhisper-1, both deprecated and discontinued on February 26, 2027, as well as a repurposed Realtime assistant session acting as an interpreter. OpenAI now offers two paths: for recordings, transcription in the original language withgpt-transcribe, followed by text translation; for live speech, a dedicated translation session withgpt-realtime-translate. The code has been verified with SDKopenai3.42.1 and thewebsocket-clientlibrary. Sources: File transcription · Realtime translation · Deprecations.
Two needs, two tools
Translating audio covers two very different scenarios, and OpenAI handles them with different tools:
| Need | Tool as of November 2026 | Result |
|---|---|---|
| A recording to translate (meeting, podcast, archived call) | gpt-transcribe to transcribe in the original language, then a text model to translate | Translated text in your target language |
| Live speech to interpret (call, conference, class) | Realtime translation session with gpt-realtime-translate | Translated audio and transcripts, generated as speech occurs |
Legacy path: /v1/audio/translations with whisper-1 | Deprecated, discontinued February 26, 2027 | English text only |
OpenAI’s guide emphasizes one point: simply changing the model ID in a /v1/audio/translations request does not migrate anything. The old endpoint, which could only translate to English, has no direct replacement.
Translating a recording
This method first transcribes faithfully in the spoken language, then translates the text. It works for any target language—unlike the old endpoint, which produced only English—and gives you both texts, which is useful for verification:
from openai import OpenAI
client = OpenAI()
def translate_recording(path: str, target_language: str) -> dict[str, str]:
"""Transcribes a recording in its original language, then translates the text."""
with open(path, "rb") as f:
transcription = client.audio.transcriptions.create(model="gpt-transcribe", file=f)
response = client.responses.create(
model="gpt-6-luna",
instructions=(
f"Translate the text provided by the user into {target_language}. "
"Keep the tone and style. Respond only with the translation."
),
input=transcription.text,
)
return {"original": transcription.text, "translation": response.output_text}
result = translate_recording("reunion_fr.mp3", "German")
print(result["translation"])
Two choices deserve explanation. The translation instruction goes in instructions, while the transcription arrives as plain data in input: a recording can contain anything, including a phrase that looks like a command, and it must not be able to modify the instruction. The gpt-6-luna model is what OpenAI recommends for large-scale, cost-sensitive processing; for delicate legal or technical text, choose a more capable model, such as gpt-6.1-sol.
Interpreting live speech
To translate while someone is speaking, OpenAI offers a special kind of Realtime session. The guide clearly distinguishes it from a voice agent session:
| Voice agent session | Translation session |
|---|---|
Connects to /v1/realtime | Connects to /v1/realtime/translations |
| The model acts as an assistant | The model acts as an interpreter |
Conversation and response cycle (response.create) | Continuous stream from incoming audio, no response.create |
| Can call tools | Produces translated audio and transcripts |
The transport depends on where the audio arrives. In a browser, WebRTC sends the microphone input and receives the translated voice as audio tracks; your server creates a short-lived client secret for this via /v1/realtime/translations/client_secrets, so your API key never leaves the server. On the server side, when the audio already arrives raw (a phone stream, a capture), a WebSocket connection is enough:
import base64
import json
import os
import websocket # pip install websocket-client
ws = websocket.WebSocket()
ws.connect(
"wss://api.openai.com/v1/realtime/translations?model=gpt-realtime-translate",
header=[
f"Authorization: Bearer {os.environ['OPENAI_API_KEY']}",
"OpenAI-Safety-Identifier: hashed-user-id", # hashed identifier of your user
],
)
# Output language of the interpreter
ws.send(json.dumps({"type": "session.update", "session": {"audio": {"output": {"language": "en"}}}}))
def send_audio(pcm16: bytes) -> None:
"""Appends a chunk of source audio: 16-bit PCM, mono, 24 kHz."""
ws.send(json.dumps({"type": "session.input_audio_buffer.append", "audio": base64.b64encode(pcm16).decode()}))
While you send the audio, including silences, the session returns events to process on the fly: session.output_audio.delta carries the translated audio in base64, session.output_transcript.delta the translated text, and session.input_transcript.delta the transcription of the original. When the source stops, send session.close: the service finishes the current translation, then responds with session.closed.
translation: list[str] = []
while True:
event = json.loads(ws.recv())
if event["type"] == "session.output_transcript.delta":
translation.append(event["delta"])
elif event["type"] == "error":
raise RuntimeError(f"Translation error: {event['error']['code']}")
elif event["type"] == "session.closed":
break
ws.close()
print("".join(translation))
Do not neglect the error event: a rejected key does not fail the connection itself; it arrives just afterward as an error event with code invalid_api_key (observed November 3, 2026). In production, reception runs in parallel with sending, in a separate thread or task, and the translated audio goes to the player or phone line as it arrives: the official guide provides a complete version, including audio playback.
Key takeaways
/v1/audio/translationsandwhisper-1shut down on February 26, 2027, with no direct replacement: changing the model is not enough- For a recording:
gpt-transcribein the original language, then text translation by a text model, to any language - Keep the translation instruction in
instructionsand the transcription as plain data - For live speech: a translation session (
/v1/realtime/translations,gpt-realtime-translate), which acts as the interpreter, withoutresponse.create - WebRTC in the browser, with a client secret created by the server; WebSocket on the server side, with 16-bit PCM audio at 24 kHz