Skip to main content

Start a live transcription

Live speech uses two REST calls around a WebSocket stream:

  1. create a session;
  2. connect to the returned WebSocket URL and stream audio;
  3. receive recognition messages;
  4. stop the session to finalize the call.

The account must have Live Transcription enabled. Otherwise, the start and stop operations return 403 Forbidden.

1. Start the session​

Authenticate as described in Authentication, then call:

curl --request POST "https://api.example.com/api/v1/live-speech/start" \
--header "Authorization: Bearer $SPEECHLYTICS_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"name": "support-call-42",
"numberOfChannels": 2,
"language": 1,
"translationLanguage": 4,
"username": "agent@example.com",
"local": "1001",
"remote": "+15551234567",
"sampleRate": 16000,
"multilingualDetection": false,
"autoTranslationDirection": false
}'
FieldMeaning
nameDisplay name of the call.
numberOfChannels1 for mono, 2 for stereo.
languageSpoken language (Language enum). Defaults to 1 (English).
translationLanguageOptional live translation target. Omit or send 0 for none.
username, local, remoteAgent identity, agent number and customer number, as for recorded calls.
sampleRateSample rate of the audio you will stream, for example 16000 or 8000. The stored recording is always 16 kHz.
multilingualDetectionRe-detect the language on every segment. Needs Live Language Detection.
autoTranslationDirectionTranslate each speaker into the other speaker's detected language. Needs Live Language Detection.

The response supplies everything needed to stream and view the call:

{
"id": 4821,
"url": "wss://api.example.com/ws/transcribe?sessionId=4821",
"pinCode": "3418"
}

Save the session id; it is also the call id. The PIN lets a viewer follow the live call in the Speechlytics live viewer without an account.

2. Stream audio​

Connect to the returned url and authenticate with the Authorization header. Both the raw JWT and Bearer <jwt> are accepted. Browsers cannot set headers on a WebSocket, so stream from a server-side client.

Send audio as binary messages:

  1. Begin the stream with a standard WAV header describing the audio (16-bit PCM, sampleRate, numberOfChannels). The simplest approach is to stream a WAV file from its first byte.
  2. Follow it with interleaved 16-bit PCM samples, paced in real time. A practical chunk is 9,600 bytes per channel.

For stereo audio, the second interleaved channel is the agent (returned as Left) and the first is the customer (Right). Mono uses the shared Both channel and cannot provide per-speaker metrics.

The server sends text messages:

{ "type": "recognized", "message": "{\"Channel\":\"Left\",\"Segment\":{\"Text\":\"Thanks for calling.\",\"StartTime\":\"00:00:01.240\",\"Duration\":\"00:00:01.100\",\"ConfidenceLevel\":0.93,\"Language\":\"en\"}}" }
typeMeaning
sessionStartedThe recognizer is running.
recognizedA finalized segment. message is a JSON string with Channel and Segment (Text, StartTime, Duration, ConfidenceLevel, Language).
sessionStoppedThe recognizer stopped.
errorLive transcription failed; the socket closes afterwards.

Parse message as a second JSON document. Reassemble fragmented WebSocket frames before parsing.

Reference client

Speechlytics.RealTimeTranscriptionClient in the product repository is an end-to-end .NET example. It reads a 16-bit PCM WAV file, starts the session, streams the file from its first byte in chunks of 9,600 bytes per channel at real-time pace, retries 429 responses with backoff, prints recognition events and stops the session.

3. Stop and finalize​

curl --request POST "https://api.example.com/api/v1/live-speech/stop" \
--header "Authorization: Bearer $SPEECHLYTICS_TOKEN" \
--header "Content-Type: application/json" \
--data '{"id": 4821}'
{"isValid": true}

Stopping waits briefly for the last audio to be recognized, persists the recording and starts the enabled post-call pipeline: masking, keywords, summaries, analytics and custom questions. On accounts with polishing enabled (and without sensitive-content protection), the transcript is polished automatically first, and keywords and analytics follow once it is done. Closing the WebSocket also ends the session, and calls whose stream drops or goes idle are finalized automatically. An unknown session returns 404 Not Found.

The call's status becomes 2 (Processed) as soon as the session is finalized; keywords and analytics are added shortly after.

Retrieve the final result with GET /api/v1/calls/{id}/status.

Live intelligence and incremental audio​

When the account has the Events API, you can follow keyword detections, alerts, sentiment, coaching and other live intelligence while the call runs. See Live events.

GET /api/v1/calls/{id}/live-payload?fromByte=<offset> returns only the recorded audio after the supplied byte offset, as base64 WAV. Persist totalBytes and pass it as the next fromByte to keep each response small.

For what each live feature does, see Live transcription and intelligence.

Common failures​

SymptomResolution
Start or stop returns 403Live Transcription is not enabled for the account.
Start or stop returns 429You exceeded the rate limit. Back off and retry.
WebSocket returns 400Upgrade the request to WebSocket and use the exact returned URL.
Socket connects but no messages arriveCheck the Authorization header and that the session belongs to the token's account.
No transcript messagesStart the stream with a WAV header; verify 16-bit PCM, sample rate, channel count and real-time pacing.
An error message arrivesLive transcription is unavailable on the server; retry later or contact support.
Stereo speakers are reversedPut the agent on the second channel and the customer on the first.
Live events return 403The Events API is not enabled for the account.
Live payload returns 404The call belongs to another account or the session is no longer live.