Skip to main content
A live session lets you stream a consultation while it happens. You create the session with one REST call, receive a WebSocket URL, send audio as the clinician speaks, and receive the generated medical record when the consultation ends. Use this when you capture audio in real time. When you already hold a finished recording, use the Consultations flow instead.

How it works

  1. POST /v1/scribe-sessions/live returns a WebSocket URL.
  2. Connect to that URL and stream the audio as it is captured.
  3. Send stop_recording when the consultation ends.
  4. The scribe_session.completed webhook tells you the record is ready.
  5. Fetch the record from Medical Record Documents.

What the API key must carry

The key you use here needs all three of the following, or the call fails with 403:
  • The scribe:write permission, granted explicitly. A legacy key with no permissions claim works on some other endpoints but is refused here; regenerate the key to obtain one.
  • The doctor role.
  • A binding to an institution.

Creating a session

The request body carries the consultation context: which consultation this is, which template to fill, which patient it belongs to, and any written context you already hold.
Response:
Treat live.url as opaque and handle it as a secret. Connect to it exactly as returned, and do not build it yourself: the host, the path and the credential all change without notice. The credential is checked only when the socket opens. A connection established before expiresAt keeps streaming past it, and a connection attempted after it is refused, so request a new session rather than reusing an expired URL.

Request fields

Choosing the template

template accepts either an id or the template JSON itself. Send exactly one of them. Sending both, or neither, returns 400 with param set to template. The inline form:
The inline template is stored the first time you send it and reused afterwards: identical sections resolve to the same template by content hash, so sending it on every consultation creates no duplicates. The section format is the same one documented in Smart Templates, including nested objects, arrays and enums.

Identifying the patient

patient also accepts either an id or the identity inline. Send exactly one.
The inline form creates the patient when it does not exist yet, so you do not need to call the Patients API first.

Retrying the same consultation

Calling the endpoint again with the same consultation.id while the session is still recording returns the same session with a new URL. That is the supported way to recover from a dropped connection. Do not compare the two URLs for equality, and do not cache the first one. Once the recording has stopped, the same id returns 409.

Sending audio

Connect to live.url. The server sends a ready message when it is prepared to receive audio. Send audio as binary WebSocket frames. Two formats are accepted:
Raw PCM is not inspected. If you send a different sample rate or channel count, the audio is accepted and transcribed incorrectly, with no error. A WAV file is accepted the same way: its header is not parsed, so the first bytes become a short burst of noise and the rest transcribes normally. Send the samples only, without the header.
Send roughly 100 ms of audio per frame, at the pace it is captured. A PCM payload under 1024 bytes (about 32 ms) is kept in the recording, but it is not forwarded to the live recognizer, so very small frames delay the text you see rather than losing audio.

Keeping the connection alive

Send {"type": "ping", "data": {}} whenever you want to confirm the socket is healthy; the server replies with {"type": "pong", "data": {}}. Any inbound frame, audio included, counts as activity. A session that receives nothing for 15 minutes is closed by the server, so send audio continuously, or ping during long pauses.
One socket per session. Opening a second connection for the same session evicts the first: the older socket stops receiving transcripts. Reconnect after a drop, but never stream the same consultation from two places at once.

Messages you receive

Every message is JSON with a type and a data field. A correction supersedes what a transcript reported for the same segment. When you display text to a clinician, apply corrections as they arrive. reconnect carries two reasons. server_draining means the server is restarting: reconnect and continue streaming. resume_upload means the stop arrived before all the audio did: reconnect and send the audio that is missing.

Ending the session

Send this message when the consultation ends:
The server finishes processing the audio it holds, sends scribe_completed with data.status set to processing, and closes the connection.
stop_recording is the only thing that produces a record. If the socket simply closes without it, the audio is kept but nothing is generated, no webhook fires, and the consultation stays unfinished. Always send it, including when the clinician cancels.
The socket does not deliver the medical record. scribe_completed means generation started, not that it finished. Wait for the scribe_session.completed webhook, then fetch the record.

Receiving the record

The scribe_session.completed webhook carries consultationInternalId, the same consultation.id you sent. Fetch the record with it:
Completion usually arrives within a minute of stop_recording. Generation runs partly while the audio streams, so a longer consultation does not take proportionally longer to finish.
The webhook fires a few seconds before the document is queryable. If your first fetch returns an empty list, wait 5 seconds and fetch again.

Connection loss

Reconnecting is expected and safe.
  • The socket drops while recording. Call POST /v1/scribe-sessions/live again with the same consultation.id, then connect to the URL it returns. Audio already received is kept.
  • live.url reaches expiresAt. Request a new session with the same consultation.id. A socket already open is unaffected.
  • Close 1013. Retryable: the server is busy or restarting. Wait a moment and reconnect.
  • Close 1003. The audio could not be decoded. The session moves to an error state, so reconnecting does not save it. Fix the encoder and start a new consultation.
  • Close 1008. Terminal: the credential or the session is not valid. Do not reconnect; retrying returns the same result.

Errors

See Errors for the full response envelope.