client.calls resource. Vobiz keeps the same call flow and gives each concern a dedicated, explicitly named resource — calls.make_call to place a call, live_calls to fetch/list/hang up in‑flight calls, and one purpose‑built resource per in‑call action (play_audio, speak_text, dtmf, record_calls). Migrating is mostly a tab‑swap: rename the method, pass your auth_id explicitly, and keep the same answer‑URL webhook.
Set credentials once:
AUTH_ID is your Vobiz Auth ID (MA_…) and AUTH_TOKEN is your Auth Token. In the Vobiz SDK, api_key is the Auth ID (sent as the X-Auth-ID header) and auth_token becomes X-Auth-Token. Every account‑scoped method takes that auth_id as its first argument. Base URL: https://api.vobiz.ai/api/v1.Twilio → Vobiz mapping
Twilio grounds every outbound call inclient.calls.create() and every live‑call change in client.calls(sid).update(). Vobiz splits those responsibilities into focused resources so each call is easy to read and test.
| Task | Twilio (twilio-python / twilio-node) | Vobiz SDK |
|---|---|---|
| Create client | Client(account_sid, auth_token) | Vobiz(api_key=AUTH_ID, auth_token=AUTH_TOKEN) |
| Place outbound call | client.calls.create(to=, from_=, url=, method=) | client.calls.make_call(auth_id, from_=, to=, answer_url=, answer_method=) |
| Answer webhook fetch | url + method on the call | answer_url + answer_method on the call |
| Inline instructions | twiml="<Response>…" | Serve VobizXML from answer_url (build with vobizxml) |
| Fetch one call | client.calls(sid).fetch() | Live: client.live_calls.get_live_call(auth_id, call_uuid, status='live') · History: client.cdr.get_cdr(auth_id, call_id) |
| List calls | client.calls.list(status=…) | Live: client.live_calls.list_live_calls(auth_id, status='live') · History: client.cdr.list_cdrs(auth_id, …) |
| Queued calls | client.calls.list(status='queued') | client.live_calls.list_queued_calls(auth_id) / get_queued_call |
| Redirect a live call | client.calls(sid).update(url=, method=) | Return <Redirect> from your answer flow, or drive the leg with the in‑call resources below |
| Play audio on live call | client.calls(sid).update(twiml="<Play>…") | client.play_audio.call(auth_id, call_uuid, urls=) |
| Speak text on live call | client.calls(sid).update(twiml="<Say>…") | client.speak_text.call(auth_id, call_uuid, text=, voice=, language=) |
| Send DTMF on live call | sendDigits at create time | client.dtmf.send_dtmf(auth_id, call_uuid, digits=) |
| Start / stop recording | client.calls(sid).recordings.create() | client.record_calls.start_recording(auth_id, call_uuid, …) / stop_recording |
| End a live call | client.calls(sid).update(status='completed') | client.live_calls.hangup_call(auth_id, call_uuid) |
| Recording resources | client.recordings.list()/fetch()/delete() | client.recordings.list_recordings/get_recording/delete_recording(auth_id, …) |
| Answer‑TwiML verbs | <Say> <Play> <Gather> <Dial> <Record> <Hangup> <Redirect> <Pause> | <Speak> <Play> <Gather> <Dial> <Record> <Hangup> <Redirect> <Wait> |
| Webhook auth | X-Twilio-Signature (HMAC‑SHA1) via RequestValidator | Signature validation on your answer_url with your Auth Token |
Place an outbound call
Twilio requires exactly one ofurl, twiml, or application_sid; the common case is url + method pointing at your answer webhook. Vobiz uses answer_url + answer_method for the identical purpose.
Answer the call with markup
When Vobiz rings the destination it fetches youranswer_url and executes the returned XML — the same request/response model as a Twilio webhook. TwiML’s <Say>/<Gather> become VobizXML’s <Speak>/<Gather>; the vobizxml builder mirrors the ergonomics you already use.
Vobiz
<Gather> uses inputType, executionTimeout, digitEndTimeout, numDigits, and finishOnKey. See /xml/gather for the full attribute list.Control a live call
This is the biggest shape change — and the one that makes Vobiz code clearer. Twilio funnels every mid‑call action back throughclient.calls(sid).update(...), either redirecting to fresh TwiML or setting status. Vobiz gives each action its own resource keyed by (auth_id, call_uuid), so the intent is on the method name.
Fetch and list calls
Twilio’sclient.calls.list() and client.calls(sid).fetch() return both live and completed calls from one resource, filtered by status. Vobiz separates the two lifecycles: live_calls for anything in flight (status='live', plus queued‑call helpers) and cdr for completed‑call history with rich filters.
Key differences
- The answer webhook maps 1:1. Twilio’s
url+methodbecome Vobiz’sanswer_url+answer_method, andanswer_methodis passed explicitly on everymake_call. Your web framework returns markup exactly as before — just VobizXML instead of TwiML. - Explicit
auth_idon every call. Twilio scopes requests to the account behind the client. Vobiz passes the Auth ID (MA_…) as the first argument of each account‑scoped method, which makes multi‑account and sub‑account code unambiguous at the call site. - In‑call actions are first‑class resources. Where Twilio re‑enters
client.calls(sid).update(...)for every mid‑call change, Vobiz exposesplay_audio.call,speak_text.call,dtmf.send_dtmf,record_calls.start_recording, andlive_calls.hangup_call. Each method name states the action, so live‑call logic reads top‑to‑bottom. - Live vs. completed are separate lenses. Vobiz
live_callscovers in‑flight and queued legs; the dedicatedcdrresource covers completed‑call history with filters likefrom_number,to_number,call_direction,hangup_cause, andbridge_uuid— purpose‑built for reporting. - Redirect the natural way. An imperative Twilio redirect (
update(url=…)) is expressed on Vobiz by returning<Redirect>from your answer flow, keeping call routing declarative and versionable alongside the rest of your XML. - Familiar verb set. TwiML’s core verbs have direct VobizXML counterparts —
<Say>→<Speak>,<Pause>→<Wait>, and<Play> <Gather> <Dial> <Record> <Hangup> <Redirect> <Conference> <Stream>keep their names — so answer documents port with minimal edits. - Signed webhooks. Both platforms sign inbound webhook requests with your Auth Token; validate the signature on your
answer_urlthe same way you validatedX-Twilio-Signaturewith Twilio’sRequestValidator.