AgentPhone Python SDK
Official Python SDK for AgentPhone — give your AI agents real phone numbers, SMS, and voice calls.
Installation
pip install agentphone
For async support:
pip install agentphone[async]
Quickstart
import os
from agentphone import AgentPhone
client = AgentPhone(api_key=os.environ["AGENTPHONE_API_KEY"])
# Create an agent with hosted voice
agent = client.agents.create(
name="My Agent",
voice_mode="hosted",
system_prompt="Schedule appointments for a dentist office.",
voice="alloy",
)
# Buy a number and attach it
number = client.numbers.buy(country="US", agent_id=agent.id)
# Make an AI conversation call — no webhook needed
call = client.calls.make(
agent_id=agent.id,
to_number="+14155551234",
system_prompt="Schedule a dentist appointment for next Tuesday at 2pm",
initial_greeting="Hi, I'm calling to schedule an appointment.",
)
print(call.status)
Async
import os
from agentphone import AsyncAgentPhone
async with AsyncAgentPhone(api_key=os.environ["AGENTPHONE_API_KEY"]) as client:
numbers = await client.numbers.list()
call = await client.calls.make(
agent_id="agent_123",
to_number="+14155551234",
system_prompt="Ask about their return policy",
)
Resources
| Resource | Methods |
|---|---|
client.numbers |
list(), buy(), release(), get(), get_messages(), list_calls(), get_contact_card(), set_contact_card(), delete_contact_card() |
client.contacts |
list(), create(), get(), update(), delete() |
client.agents |
list(), create(), get(), update(), delete(), attach_number(), detach_number(), list_calls(), list_conversations(), list_voices(), set_webhook(), get_webhook(), delete_webhook(), list_webhook_deliveries(), test_webhook() |
client.calls |
list(), get(), make(), end(), create_web_call(), get_recording(), get_transcript(), stream_transcript() |
client.messages |
send(), react() |
client.conversations |
list(), get(), update(), get_messages(), send_typing(), set_background(), delete_background() |
client.webhooks |
get(), set(), delete(), list_deliveries(), test(), get_delivery_stats(), get_all_time_stats() |
client.usage |
get(), get_daily(), get_monthly(), get_by_number(), get_by_agent() |
client.registration |
register() |
client.sub_accounts |
list(), create(), update(), delete() |
client.location |
get(), refresh() |
Contacts
# Create a contact
contact = client.contacts.create(
phone_number="+14155551234",
name="Jane Doe",
email="jane@example.com",
notes="VIP customer",
)
# List contacts with search
contacts = client.contacts.list(search="Jane")
# Get, update, delete
contact = client.contacts.get("contact_123")
client.contacts.update("contact_123", name="Jane Smith")
client.contacts.delete("contact_123")
Agents
# Create with full voice config
agent = client.agents.create(
name="Support Bot",
description="Handles customer support",
voice_mode="hosted",
model_tier="balanced", # "turbo", "balanced", or "max"
system_prompt="Handle customer support inquiries.",
begin_message="Hello, how can I help you today?",
voice="alloy",
stt_mode="fast", # "fast" or "accurate"
)
# Update
client.agents.update(agent.id, name="Updated Bot", voice="nova")
# Delete
client.agents.delete(agent.id)
# Attach / detach numbers
client.agents.attach_number(agent.id, number_id="num_123")
client.agents.detach_number(agent.id, number_id="num_123")
# List available voices
voices = client.agents.list_voices()
for v in voices:
print(v["name"])
# Agent-specific webhooks
client.agents.set_webhook(agent.id, url="https://my-server.com/hook")
client.agents.get_webhook(agent.id)
client.agents.delete_webhook(agent.id)
client.agents.list_webhook_deliveries(agent.id)
client.agents.test_webhook(agent.id)
# List agent's calls and conversations
calls = client.agents.list_calls(agent.id)
convos = client.agents.list_conversations(agent.id)
Calls
# Webhook-based call (your server handles the conversation)
call = client.calls.make(
agent_id=agent.id,
to_number="+14155551234",
from_number_id="num_123", # optional: pick which number to call from
voice="alloy", # optional: override voice
)
# AI conversation call (no webhook needed) — pass system_prompt
call = client.calls.make(
agent_id=agent.id,
to_number="+14155551234",
system_prompt="Ask about their return policy",
initial_greeting="Hi, I'm calling about a recent order.",
from_number_id="num_123",
voice="alloy",
)
# List calls with filters
calls = client.calls.list(status="completed", direction="outbound", limit=10)
# Get call details and transcript
call = client.calls.get("call_123")
for t in call.transcripts:
print(f"[{t.created_at}] {t.transcript}")
# Dedicated transcript endpoint
transcript = client.calls.get_transcript("call_123")
# Stream transcript in real time (SSE)
for event in client.calls.stream_transcript("call_123"):
if event["event"] == "turn":
print(f"[{event['data']['role']}] {event['data']['content']}")
elif event["event"] == "ended":
print(f"Call ended — {event['data']['durationSeconds']}s")
Sending Messages
# Send an outbound SMS
client.messages.send(
agent_id="agent_123",
to_number="+14155551234",
body="Your appointment is confirmed for Tuesday at 2pm.",
)
# Send with media
client.messages.send(
agent_id="agent_123",
to_number="+14155551234",
body="Here's your receipt",
media_url="https://example.com/receipt.pdf",
)
# React to a message (iMessage only)
client.messages.react("msg_123", reaction="love")
Conversations & SMS
# List conversations
convos = client.conversations.list()
# Get conversation with messages
convo = client.conversations.get("conv_123", message_limit=100)
for msg in convo.messages:
print(f"{msg.from_number}: {msg.body}")
# Paginated messages
messages = client.conversations.get_messages("conv_123", limit=50, before="msg_456")
# Update conversation metadata
client.conversations.update("conv_123", metadata={"tag": "vip"})
Usage
# Current usage summary
usage = client.usage.get()
print(f"Plan: {usage.plan.name}")
print(f"Numbers: {usage.numbers.used}/{usage.numbers.limit}")
print(f"Calls (30d): {usage.stats.calls_last_30d}")
# Daily and monthly breakdowns
daily = client.usage.get_daily(days=7)
monthly = client.usage.get_monthly(months=3)
Webhooks
# Project-level webhook
webhook = client.webhooks.set(url="https://my-server.com/hook", context_limit=10)
client.webhooks.get()
client.webhooks.delete()
# Delivery monitoring
deliveries = client.webhooks.list_deliveries(limit=50)
stats = client.webhooks.get_delivery_stats(hours=24)
print(f"Success rate: {stats.success_rate}%")
Webhook Verification
from agentphone import construct_event, WebhookVerificationError
@app.post("/webhook")
async def handle(request: Request):
body = await request.body()
sig = request.headers["X-Webhook-Signature"]
try:
event = construct_event(body, sig, secret=os.environ["WEBHOOK_SECRET"])
except WebhookVerificationError:
return Response(status_code=403)
if event.event == "agent.message":
print(f"SMS from {event.data.from_number}: {event.data.message}")
Error Handling
from agentphone import AgentPhoneError, AuthenticationError, NotFoundError, RateLimitError
try:
call = client.calls.get("bad-id")
except NotFoundError:
print("Call not found")
except RateLimitError:
print("Rate limited — back off and retry")
except AuthenticationError:
print("Invalid API key")
except AgentPhoneError as e:
print(f"API error {e.status}: {e.message}")
Requirements
- Python 3.9+
requests(sync client)httpx(async client, optional)
Links
Metadata
Release files for agentphone 0.19.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agentphone-0.19.0.tar.gz | 25.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agentphone-0.19.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 53.5 kB
Release files / agentphone-0.19.0.tar.gz
| Download URL | agentphone-0.19.0.tar.gz |
|---|---|
| Size | 25.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3d0bb8f6705157a38f3a70e8f426adc58b3c61f536c5f1fba6d2ef13cf1471d5
|
|
BLAKE2b-256 checksum How to use checksums |
f59570786db959e87c47805ca1f8d5c66658a84e01cadca0f88675251057c593
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / agentphone-0.19.0-py3-none-any.whl
| Download URL | agentphone-0.19.0-py3-none-any.whl |
|---|---|
| Size | 27.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1676a8e6eb2c6b40bb37d9ef1dd5349c34b4356cea0671b76fc116c956f57418
|
|
BLAKE2b-256 checksum How to use checksums |
de85d03110422f7e495cf450da5375d2bced6b90117ff168ce92bf33ffc55cfb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|