Home/Docs/Twilio

Capture from Twilio

Twilio splits caller and agent onto separate channels only if you ask for it. Request dual-channel when the recording is made, then give capture the recording SID: it pulls and scores offline, or score a WAV you already have directly.

The recording you capture feeds a five-dimension conversation-test: separated caller and agent channels are what the Conversation (turn-taking) and Speech (timing) dimensions read, and the same file drops into hotato test run beside a transcript and trace for the Outcome and Policy checks.

StackAutomatic pullSeparate channelsContract-grade defaultNetwork use
VapiYes: capture fetches by call idYes, out of the boxYesOne call: fetch the recording
TwilioYes: capture fetches by recording SIDNo by default: must request RecordingChannels=dual at creationNo, opt-inOne call: fetch the recording
RetellYes: capture fetches by call idYes, once call recording is turned onOpt-in: enable recording firstOne call: fetch the recording
LiveKitNo: egress runs in your own infraYes, if egress records both tracksOpt-in: configure egress for two tracksNone from Hotato
PipecatNo: the setup recorder runs in your pipelineYes, the scaffold writes caller ch0 / agent ch1Yes, once the recorder is addedNone: local recorder, no network call

Automatic pull: does hotato capture fetch it for you. Separate channels: is caller/agent separation what you get. Contract-grade default: is that separation on without extra setup. Network use: what capture calls out to, not your infrastructure.

Record dual-channel

  • Ask for it when the recording is created: RecordingChannels=dual (REST), <Record recordingChannels="dual">, or <Dial record="record-from-answer-dual"> (TwiML). Caller and agent legs land on separate channels.
dual-channel RequestedChannels=2 caller ch 0 agent ch 1 overlap: attributable mono mix --allow-mono, degraded caller + agent collapsed onto one track who talked over whom? not attributable time
Diagram of the input format, not scored data. Dual-channel: caller and agent on separate tracks; the overlap has an owner. Mono mix (the --allow-mono fallback): both voices collapse onto one track; overlap is visible but not attributable.

Score it: auto-pull

Twilio credentials + recording SID: capture fetches the recording (only network call: that download), scores offline. --expect yield/hold = interruption vs. backchannel.

bash
export TWILIO_ACCOUNT_SID=...
export TWILIO_AUTH_TOKEN=...
uvx hotato capture --stack twilio --recording-sid RE...

# no credentials yet? prove the capture→score loop on a bundled call
uvx hotato capture --stack twilio --demo

capture requests the dual-channel file explicitly (?RequestedChannels=2); mono-only recordings get a 400 and a plain stop message.

--allow-mono scores mono anyway, degraded: indicative only; no contract-grade talk-over attribution.

Or score a WAV you already have

Fetched it? Point Hotato at the file: caller on channel 0, agent on channel 1.

bash
uvx hotato run --stereo call.wav --stack twilio --expect yield

Caller on channel 1 instead? Pass --caller-channel 1 --agent-channel 0.

Pulling more than one call?

hotato connect twilio --account-sid AC... --auth-token ... stores credentials once, locally (0600). hotato pull --stack twilio --since 7d bulk-fetches recordings via the same Recordings.json list endpoint; hotato sweep pulls, then ranks the worst turn-taking moments across all of them in one offline dashboard. Mono-only recordings in the batch still need --allow-mono and score degraded. Every stack’s pull support →

Conference recordings

Conference channel order follows join order, not roles. Verify which channel holds the caller before trusting attribution.

--dump-frames shows activity per channel; --caller-channel/--agent-channel remap a flipped order.

The dual-channel gate

Separated caller and agent audio is what makes overlap attributable; speech activity comes from exposed VAD thresholds, frame-inspectable. The scorer takes one two-channel WAV or two aligned mono WAVs.