Streaming
Murf Speech to Text uses a single WebSocket connection. You send audio as binary frames and control messages as JSON; the server sends back partial transcripts while the caller is speaking, and a final transcript when you end the turn.
Endpoint
Speech to Text (Beta) is available in the India region only. Connect to wss://in.api.murf.ai/v1/transcription/stream-input.
Pass your API key as the api_key query parameter or api-key header. See Authentication.
Quickstart
Session lifecycle
A connection is a session. A session can contain many turns, for example one per caller utterance in a voice agent.
Partial and final transcripts
Each message carries the transcript of the current turn in transcript. The same text is also in rawEvent.transcript.
partial: the transcript of the turn so far. Eachpartialcontains the whole turn up to that point, so replace the text you are showing instead of appending to it.final: the completed transcript of the turn. Use this text as the caller’s utterance, and readrawEvent.wordsif you need word timestamps.
Ending a turn with Finalize
The server does not end a turn on silence. It keeps sending partial updates, and the turn ends only when you send Finalize or CloseStream. In a voice agent, send Finalize when your own end-of-turn detection fires: the server transcribes any pending speech immediately and sends a final message with rawEvent.event set to EndOfTurn and rawEvent.trigger set to manual.
A final message is sent only after you send Finalize or CloseStream. It is not sent automatically when the speaker pauses. If your code waits for final to decide that the caller has finished, make sure your code also sends Finalize.
If there was no pending speech when you sent Finalize, you still receive a final message. Its transcript is empty.
After Finalize, keep sending audio on the same connection to start the next turn. rawEvent.turn_index goes up by one, rawEvent.sequence_id keeps counting, and audio_window_start / audio_window_end remain relative to the start of the session, so all turns share one timeline.
Keeping the connection open
While you are not sending audio, for example while your agent is speaking, send a KeepAlive message so the connection is not closed for inactivity:
Prefer KeepAlive over streaming silence. Silence still counts as audio on the wire.
If the server receives no audio and no KeepAlive for too long, it sends an Error message and closes the connection with code 4008. See Errors.
Reading results
A partial message:
A final message has the same shape. rawEvent.event is EndOfTurn, and rawEvent also includes trigger and words:
Word times are already on the session timeline, so you don’t need to convert them. Quote rawEvent.request_id when you contact support.
Authentication
Speech to Text does not accept tokens from GET /v1/auth/token.
Query parameters
Coming soon
The following parameters are accepted on the connection URL but have no effect yet. Do not rely on them in production.
Concurrency
Each open Speech to Text connection uses one slot until it closes, whether or not you’re sending audio. Speech to Text limits are separate from Text to Speech concurrency. If you hit the limit, new connections close with code 4004. See Rate Limits & Concurrency for plan details.
Best practices
- Replace
partialtranscripts, don’t append them. Eachpartialcontains the whole turn so far. Use thefinaltranscript as the completed turn. - Send audio in small frames. Send 20 to 100 ms of audio per frame. Larger frames delay transcription.
- Stream at real-time pace when sending pre-recorded audio.
- Send your telephony codec as-is. If your provider sends 8 kHz µ-law, declare
mulawat8000instead of converting the audio yourself. See Audio formats. - Use
Finalizeat the end of each turn in voice agents. The server does not end a turn on silence. - Keep one connection per call. Use
Finalizebetween turns rather than reconnecting. - Handle errors by close code, not by message text. See Errors.
- Quote
rawEvent.request_idwhen you contact support.
FAQs
Do I get partial (interim) transcripts?
Yes. partial messages show the transcript of the current turn while the caller is speaking. Each one replaces the previous one. When the turn ends, you receive a final message.
When does a turn end?
When you send Finalize or CloseStream. The server does not end a turn on silence. Automatic end of turn (commit_mode=auto) is coming soon.
Can I transcribe a recorded file?
Yes, by streaming it over the WebSocket, as in the WAV example above. There is no separate file or batch transcription endpoint.
What happens to stereo audio?
Stereo input is mixed down to mono before transcription. Each channel is not transcribed separately.
Can it tell different speakers apart?
No. Speaker diarization is not available. Audio with several speakers is transcribed as a single stream.
Can I change the language mid-session?
No. Language, keywords and the audio format are set when you connect. Open a new connection to change them.
Is my audio stored?
Audio is processed for transcription. See FAQ for how Murf handles data security and retention.
How am I billed?
$0.24 per hour of audio, billed per second. Enterprise customers can get custom pricing. When your balance runs low, the server sends one QuotaWarning message per session. If credits run out, the connection closes with code 4005.