Realtime API

Realtime medical transcription

Receive a fast draft, confirmed utterances and a closing session record, with optional speaker activity.

Regions & endpoints

Realtime works the same on all three hosts with the same API key. For US-only processing and the lowest latency from the Americas, connect to wss://api.us.omi.health/v1/stream; for EU-only, wss://api.eu.omi.health/v1/stream. api.omi.health routes each new connection to the nearest healthy EU or US region. Open sessions do not move between regions; if a connection drops, open a new one and it goes to a healthy region. Regions & endpoints

Available on every plan

The WebSocket endpoint is available to Builder, Pay as you go, and Enterprise projects. Live audio shares the 25-hour monthly allowance; after it, Pay as you go is $0.45 per audio-hour. Explicit language selection supports English, Spanish, Portuguese, French, German, Dutch, Arabic, and Hindi.

Understand the event tiers

Draft text appears quickly and may change. Every preview carries aturn_id, a strictly increasing sequence, and a revision identifier. Replace the previous preview for that turn; never append revisions as duplicate text. A confirmed event closes one utterance and is immutable. The closing final event assembles the complete authoritative record. It is not a separate batch re-decode.

Speaker activity is separate from transcript wording: it may revise provisional labels, but it cannot rewrite confirmed or final text. If optional speaker processing is unavailable, transcription continues without silently dropping audio.

Connect

Connect to wss://api.omi.health/v1/stream and send the API key in the first start message. Browsers cannot set a custom Authorization header during the WebSocket upgrade. Send binary PCM16 audio at 16 kHz mono after the server returnsready, then send {"type":"stop"}.

{
  "type": "start",
  "api_key": "$OMI_API_KEY",
  "session_id": "your-unique-id",
  "model": "omi-medical-1",
  "streaming_mode": "realtime",
  "event_schema": "omi-agent-v1",
  "audio_format": "pcm_s16le",
  "sample_rate_hz": 16000,
  "channels": 1,
  "language": "en",
  "diarization": {"enabled": false}
}

Set model to omi-medical-1 or omi-general-1. Before sending audio, verify ready.model.served matches your requested model. The ready.max_session_s field states the session limit; the general batch 60-second audio boundary does not apply to this WebSocket.

Vocabulary is a batch feature

Custom vocabulary and stored dictionaries do not apply to realtime sessions today. Use batch omi-medical-1 for vocabulary on/off tests. Adding a batch vocabulary field to the start message does not demonstrate that it was applied.

Turn and connection controls

When your application knows the speaker has finished, send{"type":"finalize","id":"end-1"} to close the current turn without ending the session. The server returnsfinalize_ack with the same id. Use stop to end the session and receive its record. An explicit end signal is different from measuring automatic speech-end detection.

{"type":"finalize","id":"end-1"}
{"type":"keep_alive","id":"ping-1"}
{"type":"update_configuration","endpointing":{"silence_ms":400}}

keep_alive returns keep_alive_ack. Configuration changes return configuration_updated. You may set endpointing.silence_ms at start or mid-session between 200 and 1100 ms. The ready event reports the active controls and endpointing window. Omit mode for standard operation;mode=min_latency trades accuracy for faster automatic turn closure and does not promise a 240 ms response.

Transcript events

{
  "type": "partial",
  "tier": "draft",
  "turn_id": "turn-3",
  "sequence": 18,
  "revision_id": "session-123:draft:r4",
  "replaces_revision_id": "session-123:draft:r3",
  "text": "Have you taken any pain…",
  "mutable": true,
  "provisional": true,
  "medical_record": false
}
{
  "type": "turn_final",
  "turn_id": "turn-3",
  "sequence": 19,
  "revision_id": "session-123:turn:r3",
  "start_s": 12.4,
  "end_s": 15.8,
  "text": "Have you taken any painkillers?",
  "mutable": false,
  "authoritative": true,
  "can_authorize_response": true,
  "medical_record": false
}
  • partial events are mutable previews. Key them by turn_id, ignore stale revisions, and replace the prior preview named by replaces_revision_id.
  • turn_end_candidate is only a visual hint. If turn_continuation follows, cancel work based on that candidate.
  • turn_final carries immutable turn text and is the only realtime text event that may authorize an agent response.
  • With omi-agent-v1, the closing canonical_record event contains final_transcript and record metadata. The legacy schema calls this event final. Keep it separate from your concatenated confirmed turns.
  • Every non-final event carries medical_record=false. Never promote a draft or a failed window silently.
  • For word timestamps and canonical speaker labels, upload the complete recording through the batch API.

Optional live speakers

Send "diarization":{"enabled":true} in the start message to request speaker activity. It is off by default and does no speaker work when omitted. speaker_update events are provisional, can revise a short recent tail, and never change transcript text. A client may display a whole confirmed utterance under the speaker with the strongest overlapping activity, but must keep the preview label revisable. Use batch diarization for the canonical speaker transcript.

Capacity and retries

Realtime sessions and live speaker labels are admitted from separate, bounded pools; live-speaker capacity is the smaller of the two. Builder projects can run 2 live sessions including 1 speaker room; Pay as you go projects can run 10 including 2 speaker rooms. When a pool is full, additional starts are rejected before audio with WebSocket close code1013: TOO_MANY_STREAMS means text capacity is full; SPEAKER_CAPACITY_FULL means text is available but the optional live-speaker pool is full. Reconnect without diarization or retry with exponential backoff and jitter. Limits are aggregated per project, not multiplied by API keys. Enterprise can contract for custom maximums and reserved capacity.

Pricing

/v1/stream audio and optional speaker labels use the project's pooled monthly allowance. After the included 25 hours, Pay as you go usage is $0.45 per audio-hour, measured from audio sent during the session. An active session is never cut off at the billing boundary; a blocked Builder reconnect receivesbilling_blocked before audio is accepted.