Vobiz Python SDK for voice, trunks, phone numbers, endpoints, and XML.
Project description
Vobiz Python SDK
The official Python SDK for the Vobiz voice & telephony platform.
Make outbound calls, manage SIP trunks, phone numbers, endpoints, and build dynamic call flows with VobizXML — all from Python.
Table of Contents
- Installation
- Authentication
- Making Your First Call
- Receiving Calls — Answer Server
- Local Development with ngrok
- Resources
- VobizXML — Call Flow Control
- Environment Variables
- Running Tests
- License
Installation
pip install vobiz
Or install from source:
git clone https://github.com/Piyush-sahoo/Vobiz-Python-SDK.git
cd Vobiz-Python-SDK
pip install -e .
Requires Python 3.7+
Authentication
Vobiz uses Auth ID + Auth Token for all REST API calls. Find yours in the Vobiz Console.
Recommended: store credentials in a .env file (never commit it to git):
cp .env.example .env
# Edit .env and fill in your real values
import vobiz
# Reads VOBIZ_AUTH_ID and VOBIZ_AUTH_TOKEN from .env automatically
client = vobiz.RestClient()
# Or pass explicitly
client = vobiz.RestClient(auth_id="MA_XXXXXXXXXX", auth_token="your_token")
Making Your First Call
import vobiz
client = vobiz.RestClient()
response = client.calls.create(
from_="+911234567890", # Your Vobiz DID number
to_="+919876543210", # Destination number
answer_url="https://your-server.com/answer", # Returns VobizXML
answer_method="GET",
)
print("Call UUID:", response.request_uuid)
When the call is answered, Vobiz makes an HTTP request to your answer_url. That URL must return VobizXML telling Vobiz what to do — speak text, play audio, record, collect digits, etc.
Receiving Calls — Answer Server
Create a simple Flask server that returns VobizXML:
# answer_server.py
from flask import Flask, request, Response
from vobiz import vobizxml
app = Flask(__name__)
@app.route('/answer', methods=['GET', 'POST'])
def answer():
# Vobiz sends call details as query/form params
call_uuid = request.values.get('CallUUID')
from_num = request.values.get('From')
to_num = request.values.get('To')
print(f"Incoming call {call_uuid}: {from_num} → {to_num}")
# Build XML response using the SDK
response = vobizxml.ResponseElement()
response.add_speak(
"Hello! You have reached our service. Thank you for calling.",
voice="WOMAN",
language="en-US",
)
response.add_hangup()
return Response(response.to_string(), status=200, mimetype='application/xml')
@app.route('/hangup', methods=['GET', 'POST'])
def hangup():
print("Call ended:", request.values.get('CallUUID'))
print("Duration:", request.values.get('Duration'), "seconds")
return Response('OK', status=200)
if __name__ == '__main__':
# NOTE: macOS users — port 5000 is reserved by AirPlay Receiver.
# Use port 5001 or higher.
app.run(port=5001)
Run it:
python answer_server.py
Local Development with ngrok
Your answer server must be reachable over the internet. Use ngrok to expose your local server:
# Install ngrok: https://ngrok.com/download
ngrok http 5001
ngrok will print a public HTTPS URL like:
Forwarding https://abc123.ngrok-free.app -> http://localhost:5001
Copy that URL and set it in your .env:
ANSWER_URL=https://abc123.ngrok-free.app/answer
Now trigger the call using client.calls.create(...) with the ngrok URL as your answer_url.
Full flow:
- Your code fires an outbound call via
client.calls.create(...) - The called phone rings
- When answered, Vobiz calls your
ANSWER_URL(via ngrok → your Flask server) - Your server returns VobizXML
- Vobiz executes the XML — speaks text, plays audio, etc.
- Call ends; Vobiz calls your
hangup_urlwith final call details
Resources
Account
# Get your account details
account = client.accounts.get()
print(account.auth_id, account.name)
# Get balance (currency: "INR", "USD", etc.)
balance = client.accounts.get_balance(auth_id="MA_XXXXXXXXXX", currency="INR")
print(f"Balance: {balance.available_balance} {balance.currency}")
# Get transaction history
txns = client.accounts.get_transactions(auth_id="MA_XXXXXXXXXX", limit=20, offset=0)
# Get current concurrent call usage
concurrency = client.accounts.get_concurrency(auth_id="MA_XXXXXXXXXX")
print(f"{concurrency.concurrent_calls} / {concurrency.max_concurrent} concurrent calls")
Calls
# Make an outbound call
resp = client.calls.create(
from_="+911234567890",
to_="+919876543210",
answer_url="https://your-server.com/answer",
answer_method="GET",
hangup_url="https://your-server.com/hangup",
hangup_method="GET",
)
call_uuid = resp.request_uuid
# List currently live calls
live = client.calls.list_live()
# List queued calls
queued = client.calls.list_queued()
# Transfer an active call to a new XML URL
client.calls.transfer(
call_uuid,
legs="aleg",
aleg_url="https://your-server.com/transfer",
aleg_method="GET",
)
# Send DTMF digits to an active call
client.calls.send_digits(call_uuid, digits="1", leg="aleg")
# Hang up a call
client.calls.hangup(call_uuid)
Applications
Applications define the default XML URL for inbound calls to a number.
# Create an application
app = client.applications.create(
name="Customer Support",
answer_url="https://your-server.com/answer",
hangup_url="https://your-server.com/hangup",
application_type="XML", # "XML" or "Siptrunk"
)
app_id = app.app_id
# List all applications
apps = client.applications.list()
# Get a specific application
app = client.applications.get(app_id)
# Update an application
client.applications.update(app_id, name="Support Line", answer_url="https://new-url.com/answer")
# Delete an application
client.applications.delete(app_id)
Phone Numbers
# Browse available numbers in inventory
inventory = client.phone_numbers.list_inventory(country="IN", page=1, per_page=20)
for num in inventory.items:
print(num['e164'], num['monthly_rate'])
# Purchase a number
client.phone_numbers.purchase_from_inventory(e164="+911234567890", currency="INR")
# Release a number back to inventory
client.phone_numbers.release(e164_number="+911234567890")
# Assign a number to a SIP trunk
client.phone_numbers.assign_to_trunk(e164_number="+911234567890", trunk_group_id="trunk-uuid")
# Unassign a number from its trunk
client.phone_numbers.unassign_from_trunk(e164_number="+911234567890")
SIP Endpoints
SIP endpoints are devices or softphones that register with Vobiz via SIP.
# Create an endpoint
ep = client.endpoints.create(
username="agent_jane",
password="SecurePass123!",
alias="Jane - Support Desk",
)
endpoint_id = ep.endpoint_id
print(f"SIP URI: sip:{ep.username}@sip.vobiz.ai")
# List all endpoints
endpoints = client.endpoints.list()
# Get a specific endpoint (includes registration status)
ep = client.endpoints.get(endpoint_id)
print("Registered:", ep.sip_registered)
# Update an endpoint
client.endpoints.update(endpoint_id, alias="Jane - Sales")
# Delete an endpoint
client.endpoints.delete(endpoint_id)
Connect your SIP client:
| Setting | Value |
|---|---|
| SIP Server | sip.vobiz.ai |
| Port | 5060 (UDP/TCP) / 5061 (TLS) |
| Username | your endpoint username |
| Password | your endpoint password |
SIP Trunks
# List all SIP trunks
trunks = client.sip_trunks.list()
for trunk in trunks.objects:
print(trunk.id, trunk.name)
# Get a specific trunk
trunk = client.sip_trunks.get("trunk-uuid")
print(trunk.cps_limit, trunk.concurrent_calls_limit)
Credentials
SIP digest credentials for outbound trunk authentication.
# List all credentials
creds = client.credentials.list()
for cred in creds.objects:
print(cred.username)
IP Access Control Lists
Whitelist IP addresses for inbound SIP traffic.
# Create an IP ACL entry
acl = client.ip_access_control_lists.create(
ip_address="203.0.113.10",
description="Office static IP",
)
acl_id = acl.id
# List all ACL entries
acls = client.ip_access_control_lists.list()
# Delete an ACL entry
client.ip_access_control_lists.delete(acl_id)
Origination URIs
Define where inbound SIP calls are sent.
# List all origination URIs
uris = client.origination_uris.list()
# List origination URIs for a specific trunk
uris = client.origination_uris.list(trunk_id="trunk-uuid")
for uri in uris.objects:
print(uri.uri, uri.priority)
Recordings
# List recordings (paginated)
recordings = client.recordings.list(limit=20, offset=0)
for rec in recordings.objects:
print(rec.recording_id, rec.recording_url)
# Filter by recording type
trunk_recs = client.recordings.list(recording_type="trunk")
# Get a specific recording
rec = client.recordings.get("recording-uuid")
print("Duration:", rec.recording_duration_ms)
print("URL:", rec.recording_url)
# Delete a recording
client.recordings.delete("recording-uuid")
CDRs (Call Detail Records)
# List CDRs (most recent first)
cdrs = client.cdrs.list()
# Filter by date range and paginate
cdrs = client.cdrs.list(
start_date="2026-01-01",
end_date="2026-01-31",
page=1,
per_page=20,
)
for cdr in cdrs.data:
print(cdr['call_id'], cdr['duration'], cdr['status'])
Subaccounts
Isolate resources per customer, department, or environment.
# Create a subaccount
result = client.subaccounts.create(
name="Support Team",
email="support@example.com",
rate_limit=500,
permissions={"calls": True, "cdr": True},
password="SecurePass123!",
)
sub_id = result.sub_account.id
sub_auth_id = result.auth_credentials.auth_id
sub_auth_token = result.auth_credentials.auth_token
# ⚠️ Save the auth_token — it is only returned once at creation
# List all subaccounts
subs = client.subaccounts.list(page=1, size=25)
# Get a specific subaccount
sub = client.subaccounts.get(sub_id)
# Update a subaccount
client.subaccounts.update(sub_id, description="Updated team", rate_limit=750)
# Delete a subaccount
client.subaccounts.delete(sub_id)
VobizXML — Call Flow Control
VobizXML is returned from your answer URL to tell Vobiz what to do with a call.
from vobiz import vobizxml
response = vobizxml.ResponseElement()
# Speak text (TTS)
response.add_speak("Welcome to Acme Corp.", voice="WOMAN", language="en-US")
# Play an audio file
response.add_play("https://your-server.com/audio/hold-music.mp3")
# Collect DTMF digits (IVR menu)
get_digits = response.add_get_digits(
action="https://your-server.com/menu",
method="GET",
num_digits=1,
timeout=5,
)
get_digits.add_speak("Press 1 for sales. Press 2 for support.")
# Record the call
response.add_record(
action="https://your-server.com/recording",
max_length=300,
play_beep=True,
)
# Dial / transfer to another number
dial = response.add_dial(timeout=30, caller_id="+911234567890")
dial.add_number("+919876543210")
# Wait / hold
response.add_wait(length=5)
# Redirect to another URL
response.add_redirect("https://your-server.com/next-step")
# Hang up
response.add_hangup()
# Render to string
xml_string = response.to_string(pretty=True)
print(xml_string)
Example output:
<Response>
<Speak voice="WOMAN" language="en-US">Welcome to Acme Corp.</Speak>
<Hangup/>
</Response>
Environment Variables
Copy .env.example to .env and fill in your values:
cp .env.example .env
| Variable | Required | Description |
|---|---|---|
VOBIZ_AUTH_ID |
Yes | Your account Auth ID (e.g. MA_XXXXXXXXXX) |
VOBIZ_AUTH_TOKEN |
Yes | Your account Auth Token |
FROM_PHONE_NUMBER |
For call demos | Your Vobiz DID in E.164 format (e.g. +911234567890) |
TO_PHONE_NUMBER |
For call demos | Destination number in E.164 format |
ANSWER_URL |
For call demos | Public HTTPS URL for the answer webhook |
Security:
.envis in.gitignore. Never commit real credentials to git. Use.env.exampleas the template for your team.
Running Tests
End-to-end live API tests (requires valid credentials in .env):
python testing.py
Expected output: 40 PASS, 1 SKIP across 11 sections:
- Account (get, balance, transactions, concurrency)
- Calls (list live, list queued)
- Applications (create, list, get, update, delete)
- Phone Numbers (list inventory)
- SIP Endpoints (create, list, get, update, delete)
- SIP Trunks (list, get)
- Credentials (list)
- IP ACLs (create, list, delete)
- Origination URIs (list)
- Recordings (list)
- CDRs (list)
Unit tests:
pip install pytest
pytest -q
License
MIT — see LICENSE.txt
Support
- Documentation: https://vobiz.ai/docs
- Console: https://console.vobiz.ai
- Email: support@vobiz.ai
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vobiz_python-0.1.0.tar.gz.
File metadata
- Download URL: vobiz_python-0.1.0.tar.gz
- Upload date:
- Size: 44.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ca8c9bf58d14a03deb4f48cb8bc6b18af2eecb7ba061f1384ed2af7152f04d3
|
|
| MD5 |
0dcba0478e9d22e915d70ae34b2d0c79
|
|
| BLAKE2b-256 |
07fc58ad7218dc1684ad9ec63edab45cdbf72862918c76501c8e73528fb86d66
|
Provenance
The following attestation bundles were made for vobiz_python-0.1.0.tar.gz:
Publisher:
publish.yml on Piyush-sahoo/Vobiz-Python-SDK
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vobiz_python-0.1.0.tar.gz -
Subject digest:
3ca8c9bf58d14a03deb4f48cb8bc6b18af2eecb7ba061f1384ed2af7152f04d3 - Sigstore transparency entry: 1116991816
- Sigstore integration time:
-
Permalink:
Piyush-sahoo/Vobiz-Python-SDK@2b082ad4732cba7beb2479fbeed1def0d4c432f3 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Piyush-sahoo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2b082ad4732cba7beb2479fbeed1def0d4c432f3 -
Trigger Event:
release
-
Statement type:
File details
Details for the file vobiz_python-0.1.0-py3-none-any.whl.
File metadata
- Download URL: vobiz_python-0.1.0-py3-none-any.whl
- Upload date:
- Size: 62.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6dd2a5b72711d6bd0a834c5ea3495e7772a2dda1e9cf7992ae1694b76368d9e5
|
|
| MD5 |
5f4b04dcb112c02c1a4274f5ed36c566
|
|
| BLAKE2b-256 |
440529090c83f9a86d591657188293c69a08d3766f91cf5865a1c8ea053196a0
|
Provenance
The following attestation bundles were made for vobiz_python-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Piyush-sahoo/Vobiz-Python-SDK
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vobiz_python-0.1.0-py3-none-any.whl -
Subject digest:
6dd2a5b72711d6bd0a834c5ea3495e7772a2dda1e9cf7992ae1694b76368d9e5 - Sigstore transparency entry: 1116991838
- Sigstore integration time:
-
Permalink:
Piyush-sahoo/Vobiz-Python-SDK@2b082ad4732cba7beb2479fbeed1def0d4c432f3 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Piyush-sahoo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2b082ad4732cba7beb2479fbeed1def0d4c432f3 -
Trigger Event:
release
-
Statement type: