Skip to main content

Frequently Asked Questions

Common questions from developers building voice AI bots, IVR systems, and live transcription pipelines on SFVoPI's audio streaming.

Does SFVoPI support bidirectional, full-duplex audio streaming?

Yes. A single WebSocket connection carries audio in both directions at once — Superfone streams caller audio to you via media events while independently accepting your playAudio commands on the same socket. Neither direction blocks the other.

If you only need one direction, set direction: "INBOUND" or "OUTBOUND" in your Stream JSON to cut bandwidth — see Stream Directions.

When the caller starts speaking, do I keep receiving live inbound audio while my outbound audio is still playing?

Yes. Inbound media events keep streaming to you continuously and are never paused or blocked by your own outbound playAudio traffic — there's no server-side gate that stalls inbound delivery while a queued response is playing out. This is what makes barge-in possible: your audio processor can detect the caller speaking mid-playback and react immediately (typically by calling clearAudio) instead of waiting for your current audio to finish.

See the media event and clearAudio command.

What command clears audio that's already buffered for playback?

Send a clearAudio command. It immediately stops playback and discards every queued playAudio message — it does not wait for the current chunk to finish.

{ "event": "clearAudio", "sequenceNumber": 42 }

Full spec: clearAudio command.

Is there an acknowledgement that the buffer was actually cleared?

Yes. clearAudio requires a sequenceNumber. Once the buffer is cleared, Superfone sends back a clearedAudio event carrying that same sequenceNumber — treat this as your confirmation, analogous to a "mark" event, and don't assume the clear happened until you receive it.

{ "event": "clearedAudio", "streamId": "SFV_STRM_IN_...", "sequenceNumber": 42 }

Don't confuse this with the separate checkpoint / playedStream pair, which confirms that previously-queued audio finished playing (e.g. "the greeting is done, start listening") rather than that a buffer was cleared. See clearedAudio event and checkpoint command.

What codecs, sample rate, frame size, and buffer limits does SFVoPI use?

Detail
CodecsPCMA (recommended — native, zero transcoding), PCMU, L16
Sample rate8000 Hz (matches the telephony trunk — use this); L16 also accepts 16000–48000 Hz, but SFVoPI is still upsampling/downsampling from an 8 kHz source, so higher rates add CPU cost with no real quality gain
Frame size~20 ms chunks — 160 bytes/frame for PCMA/PCMU @ 8 kHz, 320 bytes/frame for L16 @ 8 kHz
Max playAudio payload~1.5 MB (1,500,000 base64 chars) per message — frames over this are silently dropped; stream small chunks (20–200 ms), don't buffer large blocks
Max pending checkpoints100 per stream — queue more without draining via playedStream acks and the newest ones are silently dropped

Full detail: Supported Codecs and Sample Rates.

Can I programmatically transfer or escalate a call to a human agent, with context preserved?

Not yet as a public SFVoPI API or WebSocket command. There is currently no transfer event, REST endpoint, or Stream JSON action that a third-party developer app can call to hand an in-progress call to a human agent while preserving the call and conversation context.

If your use case needs this, email hello@superfone.in with your requirements — handoff-to-human is available for select integrations and can be discussed for your app.

In the meantime, the closest DIY pattern is: end your AI leg via your own logic, then use the Initiate Call API to place a fresh call to the human agent — note this creates a new call rather than a true warm transfer, so the original call's context isn't automatically carried over; you'd need to pass it yourself (e.g. via your own webhook state).

What reconnect, timeout, and call-ended events does the WebSocket provide?

  • Reconnect: if your WebSocket server drops the connection, Superfone retries 3 times with exponential backoff (1s, 2s, 4s). On success it re-sends the start event with the same streamId — your handler must treat this as a resume, not a new stream. See Reconnection Handling.
  • Timeout: set via stream_timeout in your Stream JSON response (max 24 hours). When it fires, the stream is torn down — there's no dedicated "timeout" event sent first, so don't rely on one; track your own elapsed time if you need a warning before cutoff. See Stream Object Fields.
  • Call-ended: there's no in-band callEnded/stop message on the media WebSocket itself — the socket simply closes. The authoritative "the call is over" signal is the separate Hangup Webhook (hangup_url), which carries call_status and hangup cause. Don't try to infer final call status from the WebSocket closing alone — wait for the hangup webhook.

Next Steps