Skip to main content

AgentPhone Python SDK — give your AI agents phone numbers, SMS, and voice calls

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentphone-0.12.0.tar.gz (16.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentphone-0.12.0-py3-none-any.whl (21.5 kB view details)

Uploaded Python 3

File details

Details for the file agentphone-0.12.0.tar.gz.

File metadata

  • Download URL: agentphone-0.12.0.tar.gz
  • Upload date:
  • Size: 16.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for agentphone-0.12.0.tar.gz
Algorithm Hash digest
SHA256 ee00b8d1e5937633164ae6bfa4b77d93a84c47947e68e80d110cf557ec4b0af1
MD5 d17442861a1bd3ccd842c6ba3269a6aa
BLAKE2b-256 ad25c31ec56464ecbb87e4750d9979c3572366219190766b988a9cc4c73ff3ff

See more details on using hashes here.

File details

Details for the file agentphone-0.12.0-py3-none-any.whl.

File metadata

  • Download URL: agentphone-0.12.0-py3-none-any.whl
  • Upload date:
  • Size: 21.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for agentphone-0.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4b07ca9c2882bcc6c9d36ac1cc186ea279a854b53e2fcb3392b19d7dea6b9b62
MD5 a8fd74674cbc539ae948f7cdf1d5aa87
BLAKE2b-256 d8a68dfe84b0b04bf27b95c57f33178477489d97624fdc64b5e0bf3de7be00d1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page