Sections

Streaming

Streaming protocol

Every message of the streaming WebSocket: config, audio frames and stop; ready, partial, final, ack, warning and stopped; how to reconnect, the close codes and the limits.

Connect

Open wss://stream.meetwave.io/v1/stream: a standard WebSocket over TLS. Authenticate the opening request one of two ways:

CredentialFormMeaning
AuthorizationBearer mwk_…Your API key, on the opening request. From a server only.
tokenquery stringFrom a browser: a token from POST /v1/stream/tokens. It opens one connection within 1 minute.

Name the language in the address to get the first text sooner: wss://stream.meetwave.io/v1/stream/ru. It is optional; without it the config’s language decides. When both are given they must match, or the connection closes with 4002.

Messages are not compressed: a client that offers compression gets a connection without it. Audio itself keeps the connection open. A client that can send WebSocket pings may send one every 20 to 30 seconds; a browser or Node’s built-in WebSocket cannot, and does not need to.

Send: config, audio, stop

The first message is the config, as JSON text:

{
  "type": "config",
  "tier": "text",
  "language": "en",
  "encoding": "pcm_s16le",
  "sample_rate": 16000
}
FieldValueMeaning
type"config"The first message, within 10 seconds of opening.
tiertext | speakers | namesWhat the transcript holds at stop, and the price.
languageen | a code | autoLive text in en, es, pt, ru, de, fr, it (de, fr, it as a preview). Any other language the Files API accepts, or auto, gets its text at stop.
encoding"pcm_s16le"The only encoding: signed 16-bit, little-endian.
sample_rate16000The only rate. Audio is mono.
resume{session_id, from_s, last_final_end}Only when reconnecting: the session, the audio second you resend from and, optionally, the end of the last final you showed.

After ready, send audio as binary messages: 16 kHz mono, signed 16-bit little-endian PCM, 20 ms to 1 s per message (640 to 32000 bytes, an even number). Audio recorded before ready may be sent all at once then.

When there is no more audio, send:

{"type": "stop"}

The server finishes the last phrase, answers stopped and closes with 1000. Fetch the transcript with GET /v1/transcriptions/{id} using the transcript_id, or wait for its webhook.

Receive

The server sends JSON text messages, each with a type. Times are seconds from the start of the session’s audio and run on across reconnects.

TypeFieldsMeaning
readysession_id, transcript_id, liveSend audio now. live is false when the language has no live text. On a resume it adds resumed_from_s.
partialtext, start, endThe phrase so far. The next partial of the same phrase replaces it.
finaltext, start, end, wordsA finished phrase, after 0.8 s of silence. words holds each word with its times.
ackaudio_sAudio up to here is stored: drop it from what you would resend. At least every 30 seconds.
warningcode, seconds_leftcode low_balance: your credits cover about seconds_left more seconds. Top up to keep going.
stoppedtranscript_id, status, audio_sThe answer to stop. status is completed, or processing while the transcript is built.
errorcode, messageSent right before the server closes with a 4xxx code.

A final:

{
  "type": "final",
  "text": "Budget first.",
  "start": 12.4,
  "end": 13.3,
  "words": [
    {
      "w": "Budget",
      "start": 12.4,
      "end": 12.9
    },
    {
      "w": "first.",
      "start": 12.9,
      "end": 13.3
    }
  ]
}

Reconnect without losing words

Keep the audio you sent after the last ack. When the connection drops with a code marked “reconnect” below, open a new one within 2 minutes and send the config with resume: the session_id and, as from_s, the last ack’s audio_s. Then resend the kept audio from there. Resent audio is not charged twice. Add last_final_end, the end of the last final you showed, and text before it is not sent again; without it, skip what you already showed yourself.

Close codes

CodeMeaning
1000Normal: after stopped, or the client closed.
1001Going away. Reconnect and resume.
1006The connection dropped. Reconnect and resume.
1011internal_error Internal error. Reconnect and resume.
1012Service restart. Reconnect and resume.
1013try_again Try again later: busy, or billing briefly unreachable. Reconnect and resume.
4001unauthorized Bad, inactive or expired key or token.
4002invalid_message Bad config (for example a language the Files API does not accept), bad frame, or audio too far ahead of real time.
4003forbidden Not connected through the MeetWave stream address.
4008idle No audio for 60 seconds.
4013session_limit The session reached 4 hours of audio.
4029too_many_sessions More than 10 sessions at once for this account.
4402insufficient_credits Not enough credits for the next 5 minutes; the current phrase is finished first.
4404session_not_found Session not found, or its 2-minute resume window passed.
4409session_in_use A newer connection resumed this session; this one is closed.

Limits

LimitValue
From opening to the config message10 seconds
Silence before the server closes (4008)1 minute
Audio ahead of real time, to resend a backlog2 minutes
Audio in one session, across reconnects4 hours
Sessions at once per account10
Time to reconnect to a dropped session2 minutes

Billing is per second of audio received, at the tier’s price. When your credits run low the server sends warning; when they cannot cover the next 5 minutes, it finishes the current phrase within 15 seconds and closes with 4402.