Raw WebSocket
The framework-agnostic recipe. If your agent, telephony provider, or pipeline can hand you raw audio frames, you can add a Voxtar diagnostic layer — no SDK required. Every named framework recipe is a thin wrapper over exactly this.
The endpoint is /analyze/stream. Open it once per call, send a start frame, forward audio, and read events.
Audio requirements
Send pcm_s16le (16-bit signed little-endian PCM), mono, 16kHz or higher — the same format most telephony media streams already emit. If your source is Opus or µ-law, decode/expand to PCM first, or set encoding accordingly (opus, mulaw). Frames of 20–100ms are ideal.
Minimal client
import { WebSocket } from "ws";export function attachVoxtar(patientId, audioSource) {const vox = new WebSocket("wss://api.voxtar.hallelx2.com/v1/analyze/stream",);vox.on("open", () => {vox.send(JSON.stringify({type: "start",api_key: process.env.VOXTAR_API_KEY,patient_id: patientId,encoding: "pcm_s16le",sample_rate: 16000,panels: ["respiratory", "neurological"],write_to_ehr: true,}));// Forward raw PCM frames from whatever produces the patient's audioaudioSource.on("frame", (pcm) => vox.send(pcm));audioSource.on("end", () => vox.send(JSON.stringify({ type: "stop" })));});vox.on("message", (raw) => {const evt = JSON.parse(raw.toString());if (evt.type === "partial") {// live readings every ~1s — optional to use}if (evt.type === "complete" && evt.flags.length) {notifyCareTeam(patientId, evt.flags);}});return vox;}
Events
You'll receive partial readings every ~1s and one complete event when you send stop (or close the socket), carrying the same shape as POST /analyze. The completed analysis is persisted and retrievable via GET /analyses/{id}.
Adapting to your stack
The only per-framework difference is where you get audioSource: LiveKit gives you an rtc.AudioStream, Twilio a Media Streams WebSocket, Vapi/Retell a call audio hook, Pipecat a frame processor. Wire any of those into the client above and you're done.