Voice call
startCall opens a full WebRTC voice session. The SDK handles WebRTC gateway connection, SIP plugin attachment, ICE trickle, JSEP negotiation, and reconnect-after-reload.
This mirrors the WebRTCPhone.tsx example in the SDK's React examples app.
Prerequisites
- An endpoint ID that supports
voice_conversation. - A
<audio>element to render the remote audio (and optionally one for local mic monitoring). - Browser permission for
getUserMedia({ audio: true }).
Minimal example
const remoteAudioEl = document.querySelector<HTMLAudioElement>('#remote-audio')!;
const localAudioEl = document.querySelector<HTMLAudioElement>('#local-audio');
delphi.setRemoteAudioElement(remoteAudioEl);
delphi.setLocalAudioElement(localAudioEl); // optional
const session = await delphi.startCall({
endpointId: '24599c70-1e79-4e52-9819-e2d97acf45a5',
autoDial: true,
});
autoDial: true skips an intermediate "registered, ready to dial" state — the SDK places the call as soon as registration completes.
Mid-call operations
session.sendReadAloud('Important: your appointment is tomorrow.');
await delphi.sendDtmf('5');
await delphi.endCall();
sendReadAloud over a voice session pushes a TTS line over the same SIP leg the caller is on. Useful for notifications and interjections without reopening a separate audio_playback session.
Observe call state
const off = session.subscribe(() => {
const s = session.getState();
console.log(s.connected, s.lastMessage);
});
// Aggregated, client-level view:
delphi.subscribe(() => {
const s = delphi.getState();
console.log(s.voiceCall);
// { inCall, calling, registered, telproDomain, ... }
});
Cleanup
await delphi.endCall();
off();
endCall() tears down the SIP leg and the peer connection, and removes the voice_conversation session from the session map. The audio_playback session (if any) for the same endpoint is unaffected.
Reconnect after reload
Voice-call state is persisted to sessionStorage for about 20 seconds after disconnect, so a page reload during a call can resume cleanly. See Reconnect and persistence.
Common gotchas
- Audio elements must be attached before
startCallresolves. Otherwise the SDK's WebRTC track binding has nowhere to land. - Browsers will block
getUserMediaoutside a user gesture in some contexts; placestartCallinside a click handler. - If
iceServersare omitted, the SDK derives them fromtelproDomainreturned in the session-token response. Check that your backend includes it.
Next step
Browser actions — handle the AI-driven UI side-flows (navigate, show_alert, custom flows).