JoinInDocs
Baton
v2 (beta)
Get a key
Baton v2 Streaming (WebSocket) Beta

Stream

One speaker, highest accuracy. VAD, end of turn and barge-in.

WSS/v2/stream

One speaker, typically a voice agent's caller. It can use the conversation so far (messages) to judge whether an utterance is complete. No transcript is returned; use /v2/room when you need text.

English operating points on this tier:

profile mean latency false cut-offs
cutoff_10pct 350 ms 9.4 %
cutoff_5pct 577 ms 4.8 %
cutoff_2pct 875 ms 2.0 %

Session

Open, configure and close the session.

session.startyou sendThe first frame. Authenticates and configures a stream session.

Rejections close the socket with 1008 and one of these reasons: invalid api key, unknown mode '<mode>', a language error (bad language code(s) [...], language(s) not supported by this ASR: [...], unknown language mode ...), or an end-of-turn error (eot: give a profile or a latency_budget_ms, not both, unknown eot profile '<name>'; published: [...], eot.latency_budget_ms must be a positive number, got ...).

FieldTypeDescription
type required"session.start"
api_key requiredstring
mode"transactional_call" | "working_session" | "one_on_one" | "brainstorm" | "formal"

Default "transactional_call".

languageone of: Pinned, Allowed set, Automatic

Default {"pin": "en"}.

eotone of: By profile, By latency budget

Choose an end-of-turn operating point by name, or by the mean latency you can afford (the closest published point wins; ties go to the faster one). Give at most one; omit eot for cutoff_10pct.

Operating point Mean latency, /v2/stream Mean latency, /v2/room False cut-offs
cutoff_10pct 350 ms 439 ms about 10 %
cutoff_5pct 577 ms 726 ms about 5 %
cutoff_2pct 875 ms 1134 ms about 2 %

English figures; every language's points are at GET /v2/eot/profiles. Examples: {"profile": "cutoff_5pct"}, or {"latency_budget_ms": 600} for the point whose mean latency is closest to 600 ms.

signalsarray of "vad" | "eot" | "bargein"

VAD and end of turn are always on. Add bargein to receive barge-in events.

idle_timeout_snumber

Close after this many seconds without speech. 0 or less disables it. Default 600.

inference_intervalnumber

Scoring step in seconds. Event times fall on this grid. Default 0.1.

messagesarray of object

Conversation so far, used to judge whether an utterance is complete.

A voice agent that wants barge-in.

{
  "type": "session.start",
  "api_key": "baton_0123456789abcdef0123456789abcdef0123456789abcdef",
  "eot": {"profile": "cutoff_5pct"},
  "language": {"pin": "en"},
  "signals": ["vad", "eot", "bargein"]
}

Pick the operating point closest to a 600 ms mean latency.

{
  "type": "session.start",
  "api_key": "baton_0123456789abcdef0123456789abcdef0123456789abcdef",
  "eot": {"latency_budget_ms": 600}
}

session.startedyou receiveThe session is open. Start sending audio.

FieldTypeDescription
type required"session.started"
schema_version required2
session_id requiredstring
tier requiredstring

The scoring tier: full on /v2/stream.

eot requiredobject

The operating point this session uses.

modelsobject

Present when bargein was requested.

{
  "type": "session.started",
  "schema_version": 2,
  "session_id": "3f7c2a9e5b1d4c8e9a0b6d2f4e8c1a7b",
  "tier": "full",
  "eot": {
    "profile": "cutoff_5pct",
    "mean_latency_ms": 577,
    "cutoff_rate": 0.0482
  },
  "models": {"bargein": "v1"}
}

warning (idle_timeout)you receiveNo speech for a while. The session will close soon.

Sent before an idle close (idle_timeout_s, default 600 s). Speech resets the timer. The close is code 1000 with reason idle_timeout.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"warning"
code required"idle_timeout"
close_in_s requirednumber

Seconds until the idle close.

{
  "type": "warning",
  "seq": 40,
  "schema_version": 2,
  "code": "idle_timeout",
  "close_in_s": 30.0
}

session.endyou sendEnd the session. Baton replies with session.summary and closes with 1000.

FieldTypeDescription
type required"session.end"
{"type": "session.end"}

session.summaryyou receiveTotals for the session. Sent in reply to session.end.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"session.summary"
audio_s requirednumber

Seconds of audio received.

turns requiredinteger

Turn ends

{
  "type": "session.summary",
  "seq": 41,
  "schema_version": 2,
  "audio_s": 312.4,
  "turns": 18
}

Audio

16 kHz mono PCM16 in binary frames.

audioyou sendOne binary frame of audio.

A binary WebSocket frame: one leading byte (send 0; it identifies the source and is reserved for multi-source sessions), then signed 16-bit little-endian PCM, mono, 16 000 Hz. Any whole number of samples per frame; 80–100 ms (1280–1600 samples) is typical. Resample on the client: other rates are not accepted.

Binary frame. [u8 source = 0][PCM16LE mono 16 kHz samples...]

Speech and turns

When people speak, pause and finish.

vad.startyou receiveThe user started speaking.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"vad.start"
t requirednumber

Audio time in seconds since the session's first sample.

speaker required"user"
{
  "type": "vad.start",
  "seq": 1,
  "schema_version": 2,
  "t": 0.1,
  "speaker": "user"
}

vad.endyou receiveThe user stopped making speech sound. Not yet a turn end.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"vad.end"
t requirednumber

Audio time in seconds since the session's first sample.

speaker required"user"
duration requirednumber

Seconds since vad.start.

{
  "type": "vad.end",
  "seq": 2,
  "schema_version": 2,
  "t": 2.3,
  "speaker": "user",
  "duration": 2.2
}

turn.endyou receiveThe user has finished their turn. Your agent may respond.

Fired after the speaker goes quiet, either because Baton is confident the turn is complete (by: score) or because the silence has gone on long enough (by: timeout). latency_ms is the silence between vad.end and this event.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"turn.end"
t requirednumber

Audio time in seconds since the session's first sample.

speaker required"user"
p_eot requirednumber

End-of-turn score at this step.

latency_ms requiredinteger

Silence between vad.end and this event.

by required"score" | "timeout"
profile requiredstring
{
  "type": "turn.end",
  "seq": 3,
  "schema_version": 2,
  "t": 3.0,
  "speaker": "user",
  "p_eot": 0.81,
  "latency_ms": 700,
  "by": "score",
  "profile": "cutoff_5pct"
}

turn.resumedyou receiveThe user started speaking again within 2 s of turn.end. Treat that turn end as cancelled.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"turn.resumed"
t requirednumber

Audio time in seconds since the session's first sample.

speaker required"user"
after_ms requiredinteger

Milliseconds since the cancelled turn.end.

{
  "type": "turn.resumed",
  "seq": 5,
  "schema_version": 2,
  "t": 3.9,
  "speaker": "user",
  "after_ms": 900
}

Barge-in

Speech over your agent: a real interruption, or a backchannel.

agent.speechyou sendTell Baton when your agent starts and stops talking.

Needed for barge-in. While the agent is speaking, a user speech onset becomes a bargein.onset and is then classified. Sending phase: end drops an onset that has not been classified yet. Timestamped on arrival against the audio received so far. Ignored unless the session subscribed to bargein.

FieldTypeDescription
type required"agent.speech"
phase required"start" | "end"
utterance_idstring

Your id for the agent utterance. Echoed on barge-in events.

{
  "type": "agent.speech",
  "phase": "start",
  "utterance_id": "sp_1"
}
{
  "type": "agent.speech",
  "phase": "end",
  "utterance_id": "sp_1"
}

bargein.onsetyou receiveThe user started speaking while your agent was talking.

Sent at the speech onset. Classification follows in bargein.class.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"bargein.onset"
t requirednumber

Audio time in seconds since the session's first sample.

agent_speaking requiredtrue
utterance_idstring
{
  "type": "bargein.onset",
  "seq": 7,
  "schema_version": 2,
  "t": 12.1,
  "agent_speaking": true,
  "utterance_id": "sp_1"
}

bargein.classyou receiveWhether the interruption claims the floor or is a backchannel.

claim means the user wants to talk: stop or yield. backchannel ("mm-hm", "right") means keep talking. Decided as soon as Baton is confident, typically a few hundred milliseconds into the interruption. p_claim is null when the user stopped too soon to judge; that case is reported as a backchannel.

FieldTypeDescription
seq requiredinteger

Event sequence number. Starts at 1 and increases by one per event.

schema_version required2
type required"bargein.class"
t requirednumber

Audio time in seconds since the session's first sample.

class required"claim" | "backchannel"
p_claim requirednumber or null
decided_after_ms requiredinteger

Milliseconds from the onset to this decision.

utterance_idstring
{
  "type": "bargein.class",
  "seq": 8,
  "schema_version": 2,
  "t": 12.4,
  "class": "claim",
  "p_claim": 0.9,
  "decided_after_ms": 300,
  "utterance_id": "sp_1"
}
© 2026 JoinIn AI, Inc. All rights reserved.joinin.ai