Twilio API client and TwiML generator for comprehensive telecommunications services
Fundamental telecommunications capabilities including SMS/MMS messaging, voice calls, phone number management, and basic account operations. These APIs form the core of Twilio's communication platform.
Send and manage text and multimedia messages. Supports bulk messaging, delivery status tracking, and media attachments.
class MessageInstance:
"""Represents a sent or received message"""
sid: str # Unique message identifier
account_sid: str # Account that sent the message
from_: str # Sender phone number
to: str # Recipient phone number
body: str # Message text content
media_url: list # URLs of attached media files
status: str # Message status
direction: str # 'inbound' or 'outbound'
date_created: datetime # When message was created
date_sent: datetime # When message was sent
date_updated: datetime # Last status update
price: str # Cost of the message
error_code: int # Error code if failed
error_message: str # Error description if failed
num_segments: int # Number of segments for long messages
messaging_service_sid: str # Service used to send
class MessageList:
def create(
self,
to: str,
from_: str = None,
messaging_service_sid: str = None,
body: str = None,
media_url: list = None,
status_callback: str = None,
application_sid: str = None,
max_price: str = None,
provide_feedback: bool = None,
attempt: int = None,
validity_period: int = None,
force_delivery: bool = None,
content_retention: str = None,
address_retention: str = None,
smart_encoded: bool = None,
persistent_action: list = None,
shorten_urls: bool = None,
schedule_type: str = None,
send_at: datetime = None,
send_as_mms: bool = None,
content_variables: dict = None
) -> MessageInstance:
"""
Send a new message.
Args:
to (str): Destination phone number
from_ (str): Sender phone number (or messaging service SID)
messaging_service_sid (str): Messaging service to use
body (str): Message text (up to 1600 characters)
media_url (list): URLs of media files to attach
status_callback (str): Webhook URL for delivery updates
application_sid (str): TwiML application for handling
max_price (str): Maximum price willing to pay
provide_feedback (bool): Enable delivery feedback
attempt (int): Number of send attempts
validity_period (int): Message expiration in seconds
force_delivery (bool): Attempt delivery even if risky
content_retention (str): Content retention policy
address_retention (str): Address retention policy
smart_encoded (bool): Enable smart encoding
persistent_action (list): Actions for message persistence
shorten_urls (bool): Automatically shorten URLs
schedule_type (str): Scheduling type for future messages
send_at (datetime): When to send the message
send_as_mms (bool): Force MMS even without media
content_variables (dict): Variables for content templates
Returns:
MessageInstance: Created message object
"""
def list(
self,
to: str = None,
from_: str = None,
date_sent_before: date = None,
date_sent: date = None,
date_sent_after: date = None,
limit: int = None,
page_size: int = None
) -> Iterator[MessageInstance]:
"""
List messages with optional filtering.
Args:
to (str): Filter by recipient
from_ (str): Filter by sender
date_sent_before (date): Messages sent before this date
date_sent (date): Messages sent on this date
date_sent_after (date): Messages sent after this date
limit (int): Maximum number of messages to return
page_size (int): Number of messages per page
Returns:
Iterator[MessageInstance]: Message list iterator
"""
def get(self, sid: str) -> MessageContext:
"""Get a specific message by SID for update/delete operations"""
def delete(self) -> bool:
"""Delete the message (returns True if successful)"""
def update(
self,
body: str = None,
status: str = None
) -> MessageInstance:
"""
Update message properties.
Args:
body (str): Updated message body
status (str): Updated status ('canceled' to cancel)
Returns:
MessageInstance: Updated message
"""SMS/MMS usage examples:
# Send basic SMS
message = client.messages.create(
body="Hello from Twilio!",
from_="+15551234567",
to="+15559876543"
)
print(f"Message SID: {message.sid}")
# Send MMS with image
message = client.messages.create(
body="Check out this image!",
from_="+15551234567",
to="+15559876543",
media_url=["https://example.com/image.jpg"]
)
# Send using messaging service
message = client.messages.create(
body="Service message",
messaging_service_sid="MGxxxxx",
to="+15559876543"
)
# Schedule message for later
from datetime import datetime, timedelta
send_time = datetime.now() + timedelta(hours=1)
message = client.messages.create(
body="Scheduled message",
from_="+15551234567",
to="+15559876543",
schedule_type="fixed",
send_at=send_time
)
# List recent messages
for message in client.messages.list(limit=20):
print(f"{message.from_} -> {message.to}: {message.body}")
# Get specific message
message = client.messages.get("SMxxxxx").fetch()
print(f"Status: {message.status}")
# Cancel scheduled message
client.messages.get("SMxxxxx").update(status="canceled")Make and manage voice calls with support for TwiML, call recording, conferencing, and real-time call control.
class CallInstance:
"""Represents a voice call"""
sid: str # Unique call identifier
account_sid: str # Account that initiated the call
from_: str # Caller's phone number
to: str # Called phone number
status: str # Call status
direction: str # 'inbound' or 'outbound'
duration: int # Call duration in seconds
price: str # Cost of the call
date_created: datetime # When call was initiated
date_updated: datetime # Last status update
start_time: datetime # When call started
end_time: datetime # When call ended
parent_call_sid: str # Parent call for transfers
phone_number_sid: str # Phone number used
forwarded_from: str # Original caller if forwarded
caller_name: str # Caller ID name
uri: str # API resource URI
class CallList:
def create(
self,
to: str,
from_: str,
url: str = None,
twiml: str = None,
application_sid: str = None,
method: str = None,
fallback_url: str = None,
fallback_method: str = None,
status_callback: str = None,
status_callback_event: list = None,
status_callback_method: str = None,
send_digits: str = None,
timeout: int = None,
record: bool = None,
recording_channels: str = None,
recording_status_callback: str = None,
recording_status_callback_method: str = None,
sip_auth_username: str = None,
sip_auth_password: str = None,
machine_detection: str = None,
machine_detection_timeout: int = None,
recording_status_callback_event: list = None,
trim: str = None,
caller_id: str = None,
machine_detection_speech_threshold: int = None,
machine_detection_speech_end_threshold: int = None,
machine_detection_silence_timeout: int = None,
async_amd: str = None,
async_amd_status_callback: str = None,
async_amd_status_callback_method: str = None,
byoc: str = None,
call_reason: str = None,
call_token: str = None,
recording_track: str = None,
time_limit: int = None
) -> CallInstance:
"""
Initiate a new voice call.
Args:
to (str): Destination phone number or SIP address
from_ (str): Caller phone number
url (str): TwiML URL to execute
twiml (str): TwiML instructions to execute
application_sid (str): TwiML application to use
method (str): HTTP method for URL ('GET' or 'POST')
fallback_url (str): Fallback URL if primary fails
fallback_method (str): HTTP method for fallback
status_callback (str): Webhook for call status updates
status_callback_event (list): Events to report
status_callback_method (str): HTTP method for status callback
send_digits (str): DTMF digits to send after connect
timeout (int): Ring timeout in seconds
record (bool): Record the call
recording_channels (str): 'mono' or 'dual'
recording_status_callback (str): Recording status webhook
machine_detection (str): 'Enable' answering machine detection
machine_detection_timeout (int): AMD timeout in seconds
trim (str): 'trim-silence' to remove silence
caller_id (str): Caller ID to display
time_limit (int): Maximum call duration in seconds
Returns:
CallInstance: Created call object
"""
def list(
self,
to: str = None,
from_: str = None,
parent_call_sid: str = None,
status: str = None,
start_time_before: datetime = None,
start_time: datetime = None,
start_time_after: datetime = None,
end_time_before: datetime = None,
end_time: datetime = None,
end_time_after: datetime = None,
limit: int = None,
page_size: int = None
) -> Iterator[CallInstance]:
"""List calls with optional filtering"""
def update(
self,
url: str = None,
method: str = None,
status: str = None,
fallback_url: str = None,
fallback_method: str = None,
status_callback: str = None,
status_callback_method: str = None,
twiml: str = None,
time_limit: int = None
) -> CallInstance:
"""
Update an in-progress call.
Args:
url (str): New TwiML URL to execute
method (str): HTTP method for URL
status (str): 'canceled' or 'completed' to end call
twiml (str): New TwiML to execute
time_limit (int): New maximum duration in seconds
Returns:
CallInstance: Updated call object
"""Voice call examples:
# Make basic call with TwiML URL
call = client.calls.create(
to="+15559876543",
from_="+15551234567",
url="http://demo.twilio.com/docs/voice.xml"
)
print(f"Call SID: {call.sid}")
# Make call with inline TwiML
call = client.calls.create(
to="+15559876543",
from_="+15551234567",
twiml='<Response><Say>Hello World</Say></Response>'
)
# Make call with recording
call = client.calls.create(
to="+15559876543",
from_="+15551234567",
url="http://example.com/twiml",
record=True,
recording_status_callback="http://example.com/recording"
)
# Make call with answering machine detection
call = client.calls.create(
to="+15559876543",
from_="+15551234567",
url="http://example.com/twiml",
machine_detection="Enable",
machine_detection_timeout=30
)
# List recent calls
for call in client.calls.list(limit=20):
print(f"{call.from_} -> {call.to}: {call.status} ({call.duration}s)")
# Update in-progress call
client.calls.get("CAxxxxx").update(
url="http://example.com/new-twiml"
)
# Hang up call
client.calls.get("CAxxxxx").update(status="completed")Manage phone numbers including purchasing available numbers, configuring incoming numbers, and handling caller ID verification.
class IncomingPhoneNumberInstance:
"""Represents a purchased phone number"""
sid: str # Phone number SID
account_sid: str # Owning account
phone_number: str # The phone number (+E.164 format)
friendly_name: str # Human-readable name
voice_url: str # Voice webhook URL
voice_method: str # Voice webhook HTTP method
voice_fallback_url: str # Voice fallback URL
voice_fallback_method: str # Voice fallback method
voice_caller_id_lookup: bool # Enable caller ID lookup
sms_url: str # SMS webhook URL
sms_method: str # SMS webhook HTTP method
sms_fallback_url: str # SMS fallback URL
sms_fallback_method: str # SMS fallback method
status_callback: str # Status callback URL
status_callback_method: str # Status callback method
voice_application_sid: str # Voice TwiML application
sms_application_sid: str # SMS TwiML application
trunk_sid: str # SIP trunk SID
emergency_status: str # E911 registration status
emergency_address_sid: str # E911 address SID
date_created: datetime # Purchase date
date_updated: datetime # Last update
class AvailablePhoneNumberInstance:
"""Represents an available phone number for purchase"""
phone_number: str # The available phone number
friendly_name: str # Human-readable name
locality: str # City/locality
region: str # State/region
postal_code: str # ZIP/postal code
iso_country: str # ISO country code
address_requirements: str # Address requirements
beta: bool # Is beta number
capabilities: dict # SMS/voice/MMS capabilities
rate_center: str # Telecom rate center
latitude: float # Geographic latitude
longitude: float # Geographic longitude
class IncomingPhoneNumberList:
def create(
self,
phone_number: str = None,
area_code: str = None,
friendly_name: str = None,
voice_url: str = None,
voice_method: str = None,
voice_fallback_url: str = None,
voice_fallback_method: str = None,
voice_caller_id_lookup: bool = None,
voice_application_sid: str = None,
sms_url: str = None,
sms_method: str = None,
sms_fallback_url: str = None,
sms_fallback_method: str = None,
sms_application_sid: str = None,
status_callback: str = None,
status_callback_method: str = None,
address_sid: str = None,
emergency_status: str = None,
emergency_address_sid: str = None,
trunk_sid: str = None,
identity_sid: str = None,
bundle_sid: str = None
) -> IncomingPhoneNumberInstance:
"""
Purchase and configure a phone number.
Args:
phone_number (str): Specific number to purchase
area_code (str): Desired area code if no specific number
friendly_name (str): Human-readable name
voice_url (str): Webhook URL for voice calls
voice_method (str): HTTP method for voice webhook
voice_application_sid (str): TwiML app for voice
sms_url (str): Webhook URL for SMS
sms_method (str): HTTP method for SMS webhook
sms_application_sid (str): TwiML app for SMS
emergency_address_sid (str): E911 address
Returns:
IncomingPhoneNumberInstance: Purchased phone number
"""
class AvailablePhoneNumberCountryList:
def local(self) -> LocalList:
"""Search local phone numbers"""
def toll_free(self) -> TollFreeList:
"""Search toll-free numbers"""
def mobile(self) -> MobileList:
"""Search mobile numbers"""
def list(
self,
area_code: str = None,
contains: str = None,
sms_enabled: bool = None,
mms_enabled: bool = None,
voice_enabled: bool = None,
exclude_all_address_required: bool = None,
exclude_local_address_required: bool = None,
exclude_foreign_address_required: bool = None,
beta: bool = None,
near_number: str = None,
near_lat_long: str = None,
distance: int = None,
in_postal_code: str = None,
in_locality: str = None,
in_region: str = None,
in_rate_center: str = None,
in_lata: str = None,
limit: int = None
) -> Iterator[AvailablePhoneNumberInstance]:
"""Search available phone numbers with filters"""Phone number management examples:
# Search for available local numbers
available_numbers = client.available_phone_numbers("US").local.list(
area_code="415",
sms_enabled=True,
voice_enabled=True,
limit=10
)
for number in available_numbers:
print(f"Available: {number.phone_number} in {number.locality}")
# Purchase a specific number
phone_number = client.incoming_phone_numbers.create(
phone_number="+14155551234",
voice_url="http://example.com/voice",
sms_url="http://example.com/sms"
)
print(f"Purchased: {phone_number.phone_number}")
# Purchase first available number with area code
available = client.available_phone_numbers("US").local.list(
area_code="213",
limit=1
)[0]
phone_number = client.incoming_phone_numbers.create(
phone_number=available.phone_number,
friendly_name="My Business Line"
)
# Configure existing number
client.incoming_phone_numbers.get("PNxxxxx").update(
voice_url="http://newurl.com/voice",
voice_method="POST",
sms_url="http://newurl.com/sms"
)
# List purchased numbers
for number in client.incoming_phone_numbers.list():
print(f"{number.friendly_name}: {number.phone_number}")
# Search toll-free numbers
toll_free = client.available_phone_numbers("US").toll_free.list(
contains="800",
limit=5
)Manage conference calls allowing multiple participants to join voice conversations.
class ConferenceInstance:
"""Represents a conference call"""
sid: str # Conference SID
account_sid: str # Account SID
friendly_name: str # Conference name
status: str # Conference status
date_created: datetime # Creation time
date_updated: datetime # Last update
participants_count: int # Number of participants
max_participants: int # Maximum participants
record: bool # Recording enabled
uri: str # API resource URI
class ConferenceList:
def list(
self,
date_created_before: date = None,
date_created: date = None,
date_created_after: date = None,
date_updated_before: date = None,
date_updated: date = None,
date_updated_after: date = None,
friendly_name: str = None,
status: str = None,
limit: int = None,
page_size: int = None
) -> Iterator[ConferenceInstance]:
"""List conferences with optional filtering"""
class ParticipantInstance:
"""Conference participant"""
call_sid: str # Participant's call SID
conference_sid: str # Conference SID
account_sid: str # Account SID
muted: bool # Is participant muted
hold: bool # Is participant on hold
start_conference_on_enter: bool # Start conference when joining
end_conference_on_exit: bool # End conference when leaving
coaching: bool # Is in coaching mode
call_sid_to_coach: str # Call being coached
date_created: datetime # Join time
date_updated: datetime # Last update
def create(
self,
from_: str,
to: str,
beep: str = None,
start_conference_on_enter: bool = None,
end_conference_on_exit: bool = None,
wait_url: str = None,
wait_method: str = None,
max_participants: int = None,
record: str = None,
muted: bool = None,
call_sid_to_coach: str = None,
coaching: bool = None,
jitter_buffer_size: str = None,
conference_status_callback: str = None,
conference_status_callback_method: str = None,
conference_status_callback_event: list = None,
recording_status_callback: str = None,
recording_status_callback_method: str = None,
conference_record: str = None,
sip_auth_username: str = None,
sip_auth_password: str = None,
region: str = None,
conference_trim: str = None,
recording_channels: str = None,
recording_status_callback_event: list = None,
conference_recording_status_callback: str = None,
conference_recording_status_callback_method: str = None,
recording_track: str = None,
time_limit: int = None,
machine_detection: str = None,
machine_detection_timeout: int = None,
machine_detection_speech_threshold: int = None,
machine_detection_speech_end_threshold: int = None,
machine_detection_silence_timeout: int = None,
amd_status_callback: str = None,
amd_status_callback_method: str = None,
trim: str = None,
caller_id: str = None,
call_reason: str = None,
call_token: str = None,
status_callback: str = None,
status_callback_method: str = None,
status_callback_event: list = None,
timeout: int = None,
byoc: str = None,
early_media: bool = None
) -> ParticipantInstance:
"""Add a participant to the conference"""
def update(
self,
muted: bool = None,
hold: bool = None,
hold_url: str = None,
hold_method: str = None,
announce_url: str = None,
announce_method: str = None,
wait_url: str = None,
wait_method: str = None,
beep_on_customer_entrance: bool = None,
end_conference_on_customer_exit: bool = None,
coaching: bool = None,
call_sid_to_coach: str = None
) -> ParticipantInstance:
"""Update participant settings"""Conference call examples:
# List active conferences
for conference in client.conferences.list(status="in-progress"):
print(f"Conference: {conference.friendly_name} ({conference.participants_count} participants)")
# Get specific conference
conference = client.conferences.get("CFxxxxx").fetch()
print(f"Conference status: {conference.status}")
# List participants in conference
participants = client.conferences.get("CFxxxxx").participants.list()
for participant in participants:
print(f"Participant: {participant.call_sid} (muted: {participant.muted})")
# Mute participant
client.conferences.get("CFxxxxx").participants.get("CAxxxxx").update(muted=True)
# Remove participant from conference
client.conferences.get("CFxxxxx").participants.get("CAxxxxx").delete()
# Conference participants are typically added via TwiML <Dial><Conference> during callManage call recordings including playback URLs, transcriptions, and deletion.
class RecordingInstance:
"""Represents a call recording"""
sid: str # Recording SID
account_sid: str # Account SID
call_sid: str # Associated call SID
conference_sid: str # Associated conference SID (if any)
status: str # Recording status
date_created: datetime # Recording creation time
date_updated: datetime # Last update
start_time: datetime # Recording start time
duration: int # Duration in seconds
channels: int # Number of audio channels
source: str # Recording source
error_code: int # Error code if failed
price: str # Cost of recording
price_unit: str # Price currency
uri: str # API resource URI
encryption_details: dict # Encryption information
class RecordingList:
def list(
self,
date_created_before: date = None,
date_created: date = None,
date_created_after: date = None,
call_sid: str = None,
conference_sid: str = None,
include_soft_deleted: bool = None,
limit: int = None,
page_size: int = None
) -> Iterator[RecordingInstance]:
"""List recordings with optional filtering"""
def delete(self) -> bool:
"""Delete the recording (returns True if successful)"""
def fetch(self) -> RecordingInstance:
"""Fetch current recording details"""Recording management examples:
# List recent recordings
for recording in client.recordings.list(limit=20):
print(f"Recording {recording.sid}: {recording.duration}s from call {recording.call_sid}")
# Get specific recording
recording = client.recordings.get("RExxxxx").fetch()
print(f"Recording status: {recording.status}")
print(f"Duration: {recording.duration} seconds")
print(f"Recording URL: https://api.twilio.com/2010-04-01/Accounts/{recording.account_sid}/Recordings/{recording.sid}")
# List recordings for specific call
call_recordings = client.recordings.list(call_sid="CAxxxxx")
for recording in call_recordings:
print(f"Call recording: {recording.sid}")
# Delete old recordings
from datetime import datetime, timedelta
cutoff_date = datetime.now() - timedelta(days=30)
old_recordings = client.recordings.list(date_created_before=cutoff_date)
for recording in old_recordings:
client.recordings.get(recording.sid).delete()
print(f"Deleted recording {recording.sid}")Install with Tessl CLI
npx tessl i tessl/pypi-twilio