Skip to main content

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 startCall resolves. Otherwise the SDK's WebRTC track binding has nowhere to land.
  • Browsers will block getUserMedia outside a user gesture in some contexts; place startCall inside a click handler.
  • If iceServers are omitted, the SDK derives them from telproDomain returned 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).