Skip to main content

Python SDK

The official Audian SDK for Python.

Installation​

pip install audian-sdk

Or with Poetry:

poetry add audian-sdk

Quick Start​

from audian import AudianClient

client = AudianClient(api_key='YOUR_API_KEY')

# Search for phone numbers
numbers = client.numbers.search(location='US-CA-415', limit=10)

print(numbers)

Configuration​

Initialize Client​

from audian import AudianClient

client = AudianClient(
api_key='sk_live_...',
base_url='https://api.audian.com:8443/v2', # Optional
timeout=30, # Optional, seconds
max_retries=3, # Optional
backoff_factor=2 # Optional
)

Environment Variables​

export AUDIAN_API_KEY='sk_live_...'
import os
from audian import AudianClient

client = AudianClient(api_key=os.getenv('AUDIAN_API_KEY'))

Phone Numbers API​

Search Numbers​

response = client.numbers.search(
location='US-CA-415',
pattern='415*',
features=['sms', 'mms'],
limit=20,
offset=0
)

for number in response['data']['numbers']:
print(f"{number['number']} - ${number['price']['monthly']}/month")

List Your Numbers​

response = client.numbers.list(
limit=20,
offset=0,
status='active'
)

for number in response['data']['numbers']:
print(f"{number['number']}: {number['friendly_name']}")

Get Number Details​

number = client.numbers.get('num_abc123')
print(f"Status: {number['data']['status']}")

Purchase a Number​

purchased = client.numbers.purchase(
number='+14155551234',
friendly_name='Support Line'
)

print(f"Purchased: {purchased['data']['number']}")

Update Number Configuration​

updated = client.numbers.update_config(
number_id='num_abc123',
friendly_name='Support Line',
call_forwarding={
'enabled': True,
'forward_to': '+14155559999',
'rings_before_forward': 4
},
voicemail={
'enabled': True,
'transcription': True
}
)

Set Caller ID​

caller_id = client.numbers.set_caller_id(
number_id='num_abc123',
caller_id_number='+14155551234',
caller_id_name='Support'
)

Configure E911​

e911 = client.numbers.set_e911(
number_id='num_abc123',
address_line_1='123 Main Street',
address_line_2='Suite 100',
city='San Francisco',
state='CA',
postal_code='94102',
country='US',
customer_name='Acme Corp'
)

SMS API​

Send SMS​

response = client.sms.send(
to='+14155551234',
from_='+14155559999',
message='Hello, World!'
)

print(f"SMS ID: {response['data']['id']}")
print(f"Status: {response['data']['status']}")

Send Batch SMS​

response = client.sms.send_batch(
messages=[
{'to': '+14155551234', 'message': 'Hello 1'},
{'to': '+14155551235', 'message': 'Hello 2'},
{'to': '+14155551236', 'message': 'Hello 3'}
]
)

print(f"Sent {len(response['data']['messages'])} SMS")

Get SMS Details​

sms = client.sms.get('sms_abc123')
print(f"Status: {sms['data']['status']}")

List SMS Messages​

messages = client.sms.list(
limit=20,
offset=0,
status='delivered'
)

for message in messages['data']['messages']:
print(f"To: {message['to']} - Status: {message['status']}")

Voice API​

Make a Call​

call = client.voice.make_call(
to='+14155551234',
from_='+14155559999',
action='connect',
connect_to='+14155559999'
)

print(f"Call ID: {call['data']['id']}")

Get Call Details​

call = client.voice.get_call('call_abc123')
print(f"Duration: {call['data']['duration']}s")

List Calls​

calls = client.voice.list_calls(
limit=20,
status='completed'
)

Billing API​

Get Usage​

usage = client.billing.usage.get()

sms_cost = usage['data']['usage']['sms_messages']['cost']
voice_cost = usage['data']['usage']['voice_minutes']['cost']
phone_cost = usage['data']['usage']['phone_numbers']['monthly_cost']

print(f"SMS: ${sms_cost}")
print(f"Voice: ${voice_cost}")
print(f"Phone Numbers: ${phone_cost}")

Get Usage Breakdown​

breakdown = client.billing.usage.get_breakdown(
metric='sms',
granularity='day'
)

for item in breakdown['data']['breakdown']:
print(f"{item['date']}: {item['count']} SMS - ${item['cost']}")

List Invoices​

invoices = client.billing.invoices.list(
status='paid',
limit=20
)

for invoice in invoices['data']['invoices']:
print(f"{invoice['invoice_number']}: ${invoice['amount']}")

Get Invoice​

invoice = client.billing.invoices.get('inv_abc123')
print(f"Total: ${invoice['data']['total']}")

Download Invoice PDF​

pdf = client.billing.invoices.get_pdf('inv_abc123')

with open('invoice.pdf', 'wb') as f:
f.write(pdf)

Error Handling​

from audian import AudianError

try:
client.numbers.purchase(number='+14155551234')
except AudianError as e:
print(f"Error: {e.message}")
print(f"Code: {e.code}")
print(f"Status: {e.status}")
except Exception as e:
print(f"Unexpected error: {e}")

Rate Limiting​

The SDK automatically handles rate limiting:

# Automatically retries with exponential backoff
numbers = client.numbers.search(location='US-CA-415')

Custom Retry Configuration​

client = AudianClient(
api_key='YOUR_API_KEY',
max_retries=5,
backoff_factor=2,
initial_retry_delay=0.1 # seconds
)

Monitor Rate Limit Headers​

response = client.numbers.list()

limit = response.get('_headers', {}).get('ratelimit-limit')
remaining = response.get('_headers', {}).get('ratelimit-remaining')
reset = response.get('_headers', {}).get('ratelimit-reset')

print(f"Limit: {limit}")
print(f"Remaining: {remaining}")

Async Support​

Use async/await for concurrent requests:

import asyncio
from audian.async_client import AudianAsyncClient

async def main():
async with AudianAsyncClient(api_key='YOUR_API_KEY') as client:
numbers = await client.numbers.search(location='US-CA-415')
print(numbers)

asyncio.run(main())

Concurrent Requests​

import asyncio

async def send_multiple_sms(phone_numbers):
async with AudianAsyncClient(api_key='YOUR_API_KEY') as client:
tasks = [
client.sms.send(to=number, message='Hello!')
for number in phone_numbers
]
results = await asyncio.gather(*tasks)
return results

numbers = ['+14155551234', '+14155551235', '+14155551236']
results = asyncio.run(send_multiple_sms(numbers))

Webhooks​

Verify Webhook Signature​

from audian.webhooks import WebhookVerifier

verifier = WebhookVerifier(signing_secret='whsec_...')

# Verify webhook from Flask
@app.route('/webhook', methods=['POST'])
def handle_webhook():
try:
event = verifier.verify(
request.get_data(as_text=True),
request.headers.get('X-Audian-Signature')
)
print(f"Event type: {event['type']}")
return {'success': True}, 200
except Exception as e:
return {'error': str(e)}, 401

Handle Webhook Events​

@app.route('/webhook', methods=['POST'])
def handle_webhook():
event = verifier.verify(
request.get_data(as_text=True),
request.headers.get('X-Audian-Signature')
)

if event['type'] == 'sms.received':
print(f"SMS from {event['data']['from']}: {event['data']['message']}")

elif event['type'] == 'call.completed':
print(f"Call duration: {event['data']['duration']}s")

elif event['type'] == 'number.ported':
print(f"Number {event['data']['number']} ported successfully")

return {'success': True}, 200

Type Hints​

The SDK includes full type hints:

from typing import List
from audian import AudianClient
from audian.types import SearchNumbersRequest

client = AudianClient(api_key='YOUR_API_KEY')

request: SearchNumbersRequest = {
'location': 'US-CA-415',
'limit': 10
}

numbers: List = client.numbers.search(**request)

Testing​

The SDK provides mock utilities:

from audian.testing import MockAudianClient

# Create mock client
mock_client = MockAudianClient()

# Set mock response
mock_client.set_mock_response('numbers.search', {
'success': True,
'data': {
'numbers': [
{'number': '+14155551234', 'available': True}
]
}
})

# Use mock client
numbers = mock_client.numbers.search(location='US-CA-415')

Examples​

Complete Example​

from audian import AudianClient
import os

def main():
client = AudianClient(api_key=os.getenv('AUDIAN_API_KEY'))

# Search for available numbers
available = client.numbers.search(
location='US-CA-415',
limit=5
)

print(f"Found {len(available['data']['numbers'])} available numbers")

# Purchase the first number
if available['data']['numbers']:
number = available['data']['numbers'][0]['number']

purchased = client.numbers.purchase(
number=number,
friendly_name='Demo Number'
)

print(f"Purchased: {purchased['data']['number']}")

# Send SMS from the number
sms = client.sms.send(
from_=purchased['data']['number'],
to='+14155559999',
message='Hello from Audian!'
)

print(f"SMS sent: {sms['data']['id']}")

if __name__ == '__main__':
main()

Production Example​

import logging
from audian import AudianClient, AudianError

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

client = AudianClient(
api_key=os.getenv('AUDIAN_API_KEY'),
max_retries=5,
backoff_factor=2
)

def send_sms_safely(to_number, message):
try:
response = client.sms.send(
to=to_number,
message=message
)
logger.info(f"SMS sent: {response['data']['id']}")
return response
except AudianError as e:
logger.error(f"Failed to send SMS: {e.message}")
raise

Troubleshooting​

API Key Not Set​

import os

api_key = os.getenv('AUDIAN_API_KEY')
if not api_key:
raise ValueError('AUDIAN_API_KEY environment variable not set')

client = AudianClient(api_key=api_key)

Timeout Issues​

client = AudianClient(
api_key='YOUR_API_KEY',
timeout=60 # Increase to 60 seconds
)

Debug Logging​

import logging

logging.basicConfig(level=logging.DEBUG)
client = AudianClient(api_key='YOUR_API_KEY')

Support​

Version History​

See changelog