Capture from Vapi
Vapi records caller and assistant on separate channels already. Give capture the call id and your API key: it pulls that stereo recording and scores it offline, or hand it a WAV you already downloaded.
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.
| Stack | Automatic pull | Separate channels | Contract-grade default | Network use |
|---|---|---|---|---|
| Vapi | Yes: capture fetches by call id | Yes, out of the box | Yes | One call: fetch the recording |
| Twilio | Yes: capture fetches by recording SID | No by default: must request RecordingChannels=dual at creation | No, opt-in | One call: fetch the recording |
| Retell | Yes: capture fetches by call id | Yes, once call recording is turned on | Opt-in: enable recording first | One call: fetch the recording |
| LiveKit | No: egress runs in your own infra | Yes, if egress records both tracks | Opt-in: configure egress for two tracks | None from Hotato |
| Pipecat | No: the setup recorder runs in your pipeline | Yes, the scaffold writes caller ch0 / agent ch1 | Yes, once the recorder is added | None: 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.
Enable dual-channel recording
- Vapi’s recorded calls are stereo by default: once call recording is on for the assistant,
artifact.recording.stereoUrlis a two-channel WAV already, customer on channel 0, assistant on channel 1. No separate dual-channel switch to find, unlike Twilio or LiveKit. - Recording off for this assistant? Turn it on; the stereo file is what you already get, no further config.
Score it: auto-pull
Set VAPI_API_KEY + call ID: capture pulls it (only network call: that download), scores offline. --stack vapi = fix knobs; --expect yield/hold = interruption vs. backchannel.
export VAPI_API_KEY=... uvx hotato capture --stack vapi --call-id <id> # no key? prove the capture→score loop on a bundled call uvx hotato capture --stack vapi --demo
Or score a WAV you already have
Downloaded it? Confirm two-channel (e.g. ffprobe): caller on channel 0, assistant on channel 1.
uvx hotato run --stereo call.wav --stack vapi --expect yieldSingle mixed track? --stereo and --caller/--agent need real per-party audio; a mono file there is a hard error. The opt-in [diarize] extra scores mono anyway by separating it first: run --mono call.wav --diarize runs a local diarizer, then gates on confidence. High separability scores as diarized-mono; low is stamped indicative only; a non-separable file still exits 2. Never equivalent to a true dual-channel recording. --allow-mono lives on capture, but doesn’t reach Vapi: its capture path only pulls the verified stereo artifact. Turn on dual-channel recording upstream (above) instead.
Pulling more than one call?
hotato connect vapi --api-key <key> stores the key once, locally (0600). hotato pull --stack vapi --since 7d bulk-fetches recent recordings via Vapi’s GET /call list endpoint; hotato sweep pulls, then ranks the worst turn-taking moments across all of them in one offline dashboard. Same stereo artifact, same offline scoring, just more calls at once. Every stack’s pull support →
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.