SpeechRelay Docs

Quickstart

The shortest path to a first transcript: one WebSocket connection in multi-talker mode.

API access is not open yet. It is opening gradually; join the waitlist.

Steps

  1. Open a WebSocket connection to /v1/stream with the subprotocol dicon.v1. When a credential is configured, send it in the Authorization header.
  2. Send a session.create message.
  3. Wait for session.accepted, which carries stable session and request IDs and the initial lifecycle state.
  4. Send {"type":"stream.start"}.
  5. Send audio as binary messages: little-endian signed 16-bit mono PCM at 16 kHz. Any chunk boundary that falls on complete samples is accepted.
  6. Receive transcript.partial events as speech is transcribed, then transcript.final with each speaker's complete text.
  7. Send {"type":"stream.end"}. The session flushes and ends with exactly one terminal event.
{"type":"session.create","protocol_version":"1.0","mode":"mt_asr","expected_num_speakers":"auto"}

mode is mt_asr for multi-talker sessions and ts_asr to follow one enrolled speaker; expected_num_speakers is "auto" or an integer 1 to 4.

Reading partial transcripts

Partials are append-only deltas, not the transcript so far. Keep the committed words you hold; when a partial arrives, check stable_prefix_words against your count, append appended, and replace your in-flight word with open_word (an empty string means there is none).

{"type":"transcript.partial","speaker":"speaker_0","revision":7,
 "stable_prefix_words":42,"appended":["quick","brown"],"open_word":"fo",
 "audio_end_s":12.4}

Final text never revises. If your committed count does not equal stable_prefix_words, you missed a partial under backpressure: render a gap and wait for transcript.final, which is never dropped.

Target-speaker mode adds one step before stream.start: an enrollment.submit message carrying the voice to follow. The streaming page covers the full protocol.