Browser Calls (WebRTC)

Voicebip supports browser-based voice calls via WebRTC using pion/webrtc. This enables two use cases:

  1. Dashboard test calls - Test your agent from the dashboard without a phone
  2. Shareable links - Let anyone call your agent from a browser (see Shareable Links)

WebRTC Signaling (Public Endpoint)

The public endpoint handles WebRTC signaling for shareable agent links. No authentication required.

curl -X POST "https://api.voicebip.com/v1/public/try/{agent_id}/offer" \
-H "Content-Type: application/json" \
-d '{
"sdp": "v=0\r\no=- 1234567890 2 IN IP4 127.0.0.1\r\n...",
"agent_id": "agt_PAEZ_njcfm2kycpjs"
}'

Response:

{
"sdp": "v=0\r\no=- 9876543210 2 IN IP4 ...\r\n...",
"type": "answer",
"call_id": "call_webrtc_abc123"
}

Browser Implementation

Here is a minimal JavaScript example for establishing a WebRTC call:

async function callAgent(agentId) {
// 1. Get microphone access
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
// 2. Create peer connection
const pc = new RTCPeerConnection({
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
});
// 3. Add audio track
stream.getTracks().forEach((track) => pc.addTrack(track, stream));
// 4. Handle remote audio
const remoteAudio = new Audio();
remoteAudio.autoplay = true;
pc.ontrack = (event) => {
remoteAudio.srcObject = event.streams[0];
};
// 5. Create and send offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const response = await fetch(
`https://api.voicebip.com/v1/public/try/${agentId}/offer`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ sdp: offer.sdp, agent_id: agentId }),
}
);
const { sdp, call_id } = await response.json();
// 6. Set remote description
await pc.setRemoteDescription({ type: "answer", sdp });
// Call is now active. The agent will greet the caller via TTS.
console.log("Call started:", call_id);
// 7. Hang up
return {
hangup: () => {
pc.close();
stream.getTracks().forEach((track) => track.stop());
},
callId: call_id,
};
}

Audio Visualization

The dashboard includes real-time audio level visualization during calls. To implement this in your own UI:

const audioContext = new AudioContext();
const analyser = audioContext.createAnalyser();
const source = audioContext.createMediaStreamSource(stream);
source.connect(analyser);
analyser.fftSize = 256;
const dataArray = new Uint8Array(analyser.frequencyBinCount);
function draw() {
analyser.getByteFrequencyData(dataArray);
const average = dataArray.reduce((a, b) => a + b) / dataArray.length;
// Use `average` to drive a visual indicator (0-255)
requestAnimationFrame(draw);
}
draw();

Live Transcript

During a WebRTC call, you can stream the live transcript via Server-Sent Events (SSE). Pass your API key as a ?token= query parameter since browsers cannot set Authorization headers on EventSource connections.

const es = new EventSource(
`https://api.voicebip.com/v1/calls/${callId}/transcript/stream?token=${apiKey}`
);
es.onmessage = (event) => {
const data = JSON.parse(event.data);
// Each frame: { role, text, is_final, turn_id, ts }
// role is "user" (caller) or "agent"
console.log(`[${data.role}] ${data.text}`);
};
// Close when done
es.close();

Requirements

  • Modern browser with WebRTC support (Chrome, Firefox, Safari, Edge)
  • Microphone access permission
  • Agent must have shareable: true for public endpoint access

Current Limitations

Barge-in is not yet supported on WebRTC calls. When the agent is speaking and the user interrupts, the WebRTC path lets the current TTS audio finish before processing the next turn. Barge-in (interrupting mid-response) works on regular phone calls placed and received via the API (ESL and SIP transports), but is not yet wired into the WebRTC peer connection path.

Error Handling

HTTP StatusMeaning
200SDP answer returned, call established
404Agent not found or shareable is false
503Agent busy — concurrent limit (10 simultaneous calls) or daily limit (50 calls/day) exceeded
400Invalid SDP offer