Skip to main content
Twilio splits number management into two resources: AvailablePhoneNumber (search the carrier catalog) and IncomingPhoneNumber (provision and configure a number you own). Vobiz folds both into a single phone_numbers resource backed by an inventory model — you browse pre-provisioned stock, buy by E.164, then point inbound calls at a trunk or app. This page maps every Twilio number operation to its Vobiz equivalent, with copy-paste code.
Set your 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 every account-scoped method takes that auth_id explicitly — the counterpart to Twilio’s AccountSid in the URL path.

Twilio → Vobiz mapping

OperationTwilio (REST · twilio-python)Vobiz (REST · Vobiz Python)
Client initClient(account_sid, auth_token)Vobiz(api_key=AUTH_ID, auth_token=AUTH_TOKEN)
Search available local numbersGET /2010-04-01/Accounts/{Sid}/AvailablePhoneNumbers/US/Local.json · client.available_phone_numbers('US').local.list(area_code=, contains=, limit=)GET /api/v1/Account/{auth_id}/inventory/numbers · client.phone_numbers.list_inventory_numbers(auth_id, country=, search=)
Buy / provision a numberPOST /IncomingPhoneNumbers.json · client.incoming_phone_numbers.create(phone_number=)POST /api/v1/Account/{auth_id}/numbers/purchase-from-inventory · client.phone_numbers.purchase_from_inventory(auth_id, e164=)
List owned numbersGET /IncomingPhoneNumbers.json · client.incoming_phone_numbers.list(phone_number=, friendly_name=, limit=)GET /api/v1/Account/{auth_id}/numbers · client.phone_numbers.list_numbers(auth_id)
Route inbound to a voice app / trunkclient.incoming_phone_numbers(sid).update(voice_url=) or update(trunk_sid=) / update(voice_application_sid=)POST /api/v1/Account/{auth_id}/numbers/{number}/assign · client.phone_numbers.assign_number_to_trunk(auth_id, phone_number=, trunk_group_id=)
Change the answering URL for a numberupdate(voice_url=, voice_method=) on the numberSet the answer_url on the trunk/app the number is assigned to (Vobiz fetches your VobizXML from there)
Assign a number to a sub-accountupdate(sid, ...) on a subaccount-scoped clientPOST /api/v1/account/{auth_id}/numbers/{e164}/assign-subaccount · client.phone_numbers.assign_did_to_subaccount(auth_id, e164=, sub_account_id=)
Release / delete a numberDELETE /IncomingPhoneNumbers/{Sid}.json · client.incoming_phone_numbers(sid).delete()DELETE /api/v1/Account/{auth_id}/numbers/{e164} · client.phone_numbers.unrent_number(auth_id, e164=)
Number identityOpaque PNxxxx… SIDThe E.164 number itself (+14155551234) is the key
Webhook signing on inboundX-Twilio-Signature (HMAC-SHA1, Auth Token)X-Vobiz-Signature on the request to your answer_url

Before / after: search inventory and buy

Twilio searches the live carrier catalog with available_phone_numbers('US').local.list(...), reads .phone_number off each result, then provisions it with incoming_phone_numbers.create(phone_number=...). Vobiz browses inventory with list_inventory_numbers(...) and buys by E.164 with purchase_from_inventory(...) — a single, predictable two-step flow.
from twilio.rest import Client

client = Client(ACCOUNT_SID, AUTH_TOKEN)

# 1. Search the catalog for a local number
available = client.available_phone_numbers('US').local.list(
    area_code=415,
    sms_enabled=True,
    voice_enabled=True,
    limit=20,
)
number = available[0].phone_number   # e.g. '+14155551234'

# 2. Provision it onto your account
incoming = client.incoming_phone_numbers.create(phone_number=number)
print(incoming.sid, incoming.phone_number)

Before / after: route inbound calls

On Twilio you attach the answering logic to the number — set voice_url (a TwiML endpoint), or point the number at a Trunk (trunk_sid) or a TwiML App (voice_application_sid). On Vobiz, inbound routing is a first-class assignment to a trunk: assign_number_to_trunk(...) binds the DID to a trunk_group_id, and the trunk’s answer_url returns your VobizXML when a call arrives. This keeps routing config in one place and lets many numbers share one flow.
# Point the number's voice webhook at your TwiML endpoint
client.incoming_phone_numbers(NUMBER_SID).update(
    voice_url='https://example.com/answer',
    voice_method='POST',
)

# ...or hand inbound calls to an Elastic SIP Trunk
client.incoming_phone_numbers(NUMBER_SID).update(
    trunk_sid='TKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
)
When the call lands, Vobiz fetches the trunk’s answer_url and expects VobizXML back — the same request/response webhook pattern you used with Twilio’s voice_url, just returning <Response>…</Response> built with the vobizxml helper:
Vobiz · answer_url (Flask)
from flask import Flask, Response
from vobiz import vobizxml

app = Flask(__name__)

@app.post('/answer')
def answer():
    resp = vobizxml.ResponseElement()
    menu = resp.add_gather(action='https://example.com/menu', method='POST',
                           input_type='dtmf', num_digits=1)
    menu.add_speak('Press 1 for sales, 2 for support.')
    return Response(resp.to_string(), mimetype='application/xml')

Before / after: list, then release

Twilio lists provisioned numbers with incoming_phone_numbers.list(...) and releases one with .delete() on its SID. Vobiz lists owned numbers with list_numbers(...) and releases by E.164 with unrent_number(...).
# List owned numbers (optionally filtered)
for n in client.incoming_phone_numbers.list(limit=50):
    print(n.sid, n.phone_number, n.voice_url)

# Filter to one number
matches = client.incoming_phone_numbers.list(phone_number='+14155551234')

# Release it back to Twilio
client.incoming_phone_numbers(NUMBER_SID).delete()

Key differences

  • The E.164 number is the key. Twilio identifies a provisioned number by an opaque PNxxxx… SID; Vobiz uses the phone number itself (+14155551234). Store the E.164 and you can search, buy, route, and release without a lookup round-trip.
  • Inventory instead of a live catalog search. list_inventory_numbers returns Vobiz’s ready-to-buy stock, so search results are exactly what you can purchase_from_inventory in the next call — a deterministic two-step buy.
  • Routing lives on the trunk/app. Where Twilio sets voice_url per number, Vobiz assigns the DID to a trunk_group_id and the trunk carries the answer_url. Many numbers can share one flow, and re-pointing a whole product is a single trunk edit rather than an update per number. Twilio’s trunk_sid/voice_application_sid patterns map cleanly onto this model.
  • Same webhook contract. Vobiz fetches your answer_url and expects XML back — identical to Twilio’s voice_url request/response cycle. Swap the TwiML builder for vobizxml and the handler is a near tab-swap. Inbound requests carry an X-Vobiz-Signature you validate the same way you validated X-Twilio-Signature.
  • E.164 formatting is endpoint-specific. purchase_from_inventory takes the number with the leading + in the body; unrent_number takes it without the + in the path; assignment endpoints take it URL-encoded (%2B14155551234). The SDK handles this for you.
  • Sub-account DID assignment is first-class. assign_did_to_subaccount(auth_id, e164=, sub_account_id=) moves a DID to a child account in one call — handy for reseller and multi-tenant setups, alongside Vobiz’s India KYC tooling.
See the rest of the Twilio → Vobiz migration for calls, recordings, SIP trunking, and webhooks.