Skip to main content
The Realtime Transcription API is available to Enterprise plan customers on request. Tiro must enable the API for your workspace before you can follow this guide. In this guide, you stream one audio file at real-time pace, print the transcripts and translations in your terminal, and close the session.

Before you begin

  • A workspace with the Realtime Transcription API enabled. See the requirements in Overview.
  • An API key bound to that workspace. If the key has scopes, it needs realtime_transcription:write. Put the key in the TIRO_API_KEY environment variable.
  • Python 3.9 or later and the websocket-client package. Install it with pip install websocket-client.
  • ffmpeg to convert your audio file to PCM.
1

Convert audio to 16 kHz mono PCM

The Realtime Transcription API accepts only 16,000 Hz, mono, signed 16-bit little-endian PCM. The data must be raw, with no header. Convert any audio file to this format with ffmpeg.
This format is 32,000 bytes per second. Use the same format when you stream microphone input.
2

Create a session

Create the session on your server. This example transcribes Korean and translates it to English. If you do not need a translation, leave out translationLocale.
On success, you receive 201 Created with the session.
You receive streamToken only in this response. Keep it safe, because you use the same token to reconnect while the session is OPEN. Use wsUrl exactly as returned. Do not build it yourself.
3

Connect over WebSocket

On the client, connect to wsUrl and put streamToken in the Authorization header. You cannot send the token in a query string or a cookie.
After you connect, the first message is session.started. It usually arrives within about a second, and rarely takes tens of seconds. You can start sending audio before it arrives.
4

Send audio and read results

Split the audio into 3,200-byte (100 ms) chunks and send each as a binary frame. Send recorded files at real-time pace too. If you get more than 60 seconds ahead of real time, Tiro closes the connection with close 4029.Results arrive as transcript and translation text messages. An isFinal: false message replaces the whole previous text for the same segmentId. When isFinal: true arrives, that segment is final.
5

Close the session

After the last audio frame, send {"type": "session.end"}. Tiro sends all remaining results with isFinal: true, sends session.ended, and closes the connection with close 1000. Keep the connection open until you receive session.ended. Sending the remaining results takes up to 30 seconds.
If you cannot use the WebSocket, close the session from your server with POST /v1/external/realtime-transcriptions/{id}/end.
If you close the WebSocket connection without ending the session, the session stays OPEN. It holds one of the workspace’s 10 concurrent session slots until it ends automatically after 15 minutes without audio.

Full example

The script below combines the steps above. It streams a PCM file at real-time pace, prints the results, and closes the session. If the connection drops, it does not reconnect and ends the session over REST. To add reconnection, follow the reconnection rules.
stream_pcm.py
Run it with the path to a PCM file as the argument.

Next steps

WebSocket protocol

Message fields, errors, reconnection, and close codes.

API reference

REST APIs to create, get, list, and end sessions.