Skip to content

Speech-to-text API

Two ways to transcribe: a REST endpoint for finished audio, and a realtime WebSocket for live speech.

Two transports, one model

Sprag transcribes speech two ways. Both run Rhythm and take the same API key. They differ in whether the audio has already finished.

RESTRealtime
InputA finished audio fileA live audio stream
TransportPOST /v1/audio/transcriptionsWebSocket
Result arrivesOnce, when the whole file is doneIn fragments, as each turn ends
Word timingsYes, via timestampsNot on this path
Speaker labelsYes, via diarizationNot on this path
Use it forRecordings, voicemail, uploaded mediaLive conversation, captions, meeting notes

Which to use

Use REST when the audio already exists as a file. It is one request, there is no session to manage, and it is the only path that returns word timings and speaker labels.

Use realtime for a live stream, where one session covers a whole conversation and Sprag finds the turn boundaries for you. Neither path returns words mid-utterance: Rhythm decodes a turn once the turn closes. What realtime saves is the round trip per turn, since the socket stays open and the audio has already arrived by the time the speaker stops.

Authentication

Both paths take the same API key. REST sends it as a bearer token.

Authorization: Bearer $SPRAG_API_KEY

Browsers cannot set that header on a WebSocket upgrade, so realtime sessions opened from a browser pass the credential as a subprotocol pair instead: sprag-jwt with a short-lived Sprag JWT, or sprag-api-key with an API key. Realtime covers that handshake.

Errors

Handle failures separately on each path; one handler will not cover both.

REST answers with an HTTP status: 400 for a bad request, 401, 402, and 403 for credentials, payment, and organization membership, 404 for an unknown model, 413 for an oversized body, 429 for rate limits, and 500, 502, and 503 for server-side faults. REST has the table with meanings.

Realtime fails in three places. The upgrade is rejected with HTTP 403 before a socket exists; an open session reports a rejected event in band as an error event; and the server closes the socket with a code (1003, 1008, 1011, or 1013). Realtime lists what each one means.

The errors reference has the full error shape and retry guidance.