zoxaAI
Homepage
API ReferenceExamples

Choosing a transport

When to use phone (outbound / inbound) vs WebSocket vs WebRTC. Trade-offs, latency, and what your client actually needs.

The same agent works across four transports. Picking the right one is a question of where the audio comes from and where it goes.

The four options

TransportThe audio source/sinkWhen to use
Phone outboundA real phone number — dialled from your Twilio/Vobiz number to a customer's number.You're calling customers (sales, reminders, surveys).
Phone inboundA real phone number — customers dial your registered DID.You're running a hotline / IVR / receptionist.
WebSocketYour own server. You send and receive raw PCM frames over a WS.Server-to-server pipelines, SIP-bridge integrations, audio-file replay bots, custom mobile apps with their own audio engine.
WebRTCA browser (or any WebRTC-capable client) over zoxaAI's built-in SmallWebRTC transport.Browser-embedded voice agents — chatbots in your dashboard, embedded support, anything where the end-user is on a web page.

Decision tree

Is the audio on a phone call (PSTN / SIP)?
├── Yes — outbound (you dial)               → POST /call type=outbound       (Phone outbound)
├── Yes — inbound (customer dials you)      → POST /call type=inbound        (Phone inbound)
└── No, the audio is on the web side

    Is the end-user in a browser?
    ├── Yes                                  → POST /call transport=webrtc   (WebRTC)
    └── No, my server controls the audio     → POST /call transport=websocket (WebSocket)
                                                + connect to /ws/audio/{callId}

Trade-offs in detail

Phone — outbound / inbound

ProCon
Works with the world's most-used audio device — a phone.Telephony costs (your provider bills you).
No SDK required on the user's side.Provider sandbox / number provisioning needed up-front.
Built-in call status events (busy, no-answer, etc.).Sample rate is fixed at 8 kHz mulaw — narrowband only.

Use this for: outbound campaigns, customer-facing hotlines, anything where the end-user has only a phone.

WebRTC

ProCon
Standard RTCPeerConnection — no third-party client SDK required.You complete the SDP offer/answer handshake yourself (POST/PATCH to offerUrl).
Sub-second connect, high audio quality; codec negotiated via SDP.Hard 610-second default cap (configurable via maxCallDurationS).
Works on every modern browser without extra setup.The audio stays on the WebRTC peer connection — your server doesn't directly see raw frames.

Use this for: dashboards, in-app voice agents, marketing widgets, anywhere the user is already on a web page.

WebSocket

ProCon
You see and send raw PCM frames — full control over the audio pipeline.You do everything: capture, encode, jitter buffer, echo cancellation.
Negotiable sample rate (16000 for HD or 8000 for telephony bridges).No built-in browser-friendly client — you'd need to build one.
Easy to bridge to a SIP trunk, audio file, or custom hardware.If your client buffers audio, you'll feel the latency tax.

Use this for: server-side bots, SIP trunks, automated audio testing, custom voice surfaces that aren't phones or browsers.

Common combinations

ScenarioCombo
Voice agent embedded in your customer dashboardWebRTC (browser-flow)
Sales bot calling a list of prospectsPhone outbound + a campaign
Support hotlinePhone inbound binding (inbound-flow)
Voice IVR replacing your existing Asterisk PBXWebSocket (websocket-flow) with mulaw 8 kHz to bridge SIP audio
Twilio inbound passed to a zoxaAI agentPhone inbound — register the Twilio number once, all future calls bridge to your agent

Same agent, any transport

The agent config is transport-agnostic. The same saved agent can be invoked over phone, WebSocket, or WebRTC — only the POST /call body changes.

What stays the same across transports

  • The agentId / agent selection rules
  • contextVariables substitution
  • agent.webhook lifecycle events
  • The GET /calls/{callId} response shape
  • Transcript, recordings, and cost accounting

What changes between transports

ThingPhoneWebRTCWebSocket
Body field that selects this transporttype: "outbound" / "inbound"transport: "webrtc"transport: "websocket" (or omit)
ReturnscallIdcallId, offerUrlcallId, audioUrl
Audio is viaProvider (Twilio/Vobiz)SmallWebRTC peer connection (SDP offer/answer at offerUrl)Your WS
Sample rate / codec8 kHz mulaw (provider-fixed)Negotiated via SDPFixed: 16 kHz PCM in, 24 kHz PCM out
Default max durationProvider's account default610 sec (maxCallDurationS)Unlimited until WS closes (maxCallDurationS still caps the agent)

On this page