For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
HomeGet API key
DocumentationIntegrationsAPI Reference
DocumentationIntegrationsAPI Reference
  • Get Started
    • Welcome
  • Guides
    • Agents
    • Phone Numbers
    • Conversations
    • Calls
    • Webhooks
    • Agent Webhooks
    • Usage & Billing
  • Reference
    • Pagination
    • Error Handling
    • Messaging Rate Limits
    • Testing
    • Best Practices
    • Code Examples
    • FAQ
  • SDKs
    • TypeScript / JavaScript
    • Python
LogoLogo
HomeGet API key
On this page
  • Installation
  • Quick start
  • Async usage
  • Resources
  • Agents
  • Per-agent webhooks
  • Numbers
  • Messages
  • Contacts
  • Conversations
  • Calls
  • Webhooks (project-level)
  • Usage
  • Error handling
  • Webhook verification
  • Flask example
  • Advanced
  • Context manager
  • Custom base URL and timeout
  • Links
SDKs

Python SDK

Was this page helpful?
Previous
Built with

The official AgentPhone Python library provides convenient access to the AgentPhone API with both synchronous and asynchronous clients.

PyPI

Installation

1pip install agentphone

For async support:

1pip install agentphone[async]

Quick start

1from agentphone import AgentPhone
2
3client = AgentPhone(api_key="YOUR_API_KEY")
4
5# Create an agent
6agent = client.agents.create(name="Support Bot")
7
8# Buy a number and attach it
9number = client.numbers.buy(country="US", agent_id=agent.id)
10
11# Make an AI-powered call
12call = client.calls.make(
13 agent_id=agent.id,
14 to_number="+15559876543",
15 system_prompt="You are a helpful support assistant.",
16 initial_greeting="Hi, this is Support Bot!",
17)

Async usage

1from agentphone import AsyncAgentPhone
2
3async with AsyncAgentPhone(api_key="YOUR_API_KEY") as client:
4 agents = await client.agents.list()
5 call = await client.calls.make(
6 agent_id=agents.data[0].id,
7 to_number="+15559876543",
8 system_prompt="You are a helpful assistant.",
9 )

Resources

Agents

1# List all agents
2agents = client.agents.list(limit=20, offset=0)
3
4# Create an agent with voice configuration
5agent = client.agents.create(
6 name="Support Bot",
7 description="Handles customer inquiries",
8 voice_mode="hosted", # "hosted" for built-in AI, "webhook" for custom
9 system_prompt="You are a friendly support agent.",
10 begin_message="Hi! How can I help?",
11 voice="11labs-Brian", # see list_voices()
12 transfer_number="+15551234567", # optional: transfer calls here
13 voicemail_message="Leave a message after the beep.",
14)
15
16# Get agent details
17agent = client.agents.get(agent_id="agt_abc123")
18
19# Update an agent
20agent = client.agents.update(
21 agent_id="agt_abc123",
22 name="Updated Bot",
23 system_prompt="New prompt here.",
24)
25
26# Delete an agent
27client.agents.delete(agent_id="agt_abc123")
28
29# Attach / detach a number
30client.agents.attach_number(agent_id="agt_abc123", number_id="num_xyz789")
31client.agents.detach_number(agent_id="agt_abc123", number_id="num_xyz789")
32
33# List calls and conversations for an agent
34calls = client.agents.list_calls(agent_id="agt_abc123", limit=20)
35convos = client.agents.list_conversations(agent_id="agt_abc123", limit=20)
36
37# List available voices
38voices = client.agents.list_voices()

Per-agent webhooks

1# Set a webhook for a specific agent (overrides project default)
2webhook = client.agents.set_webhook(
3 agent_id="agt_abc123",
4 url="https://your-server.com/agent-hook",
5 context_limit=10,
6 timeout=30,
7)
8
9# Get / delete an agent's webhook
10webhook = client.agents.get_webhook(agent_id="agt_abc123")
11client.agents.delete_webhook(agent_id="agt_abc123")
12
13# View deliveries and send a test event
14deliveries = client.agents.list_webhook_deliveries(agent_id="agt_abc123", limit=50)
15client.agents.test_webhook(agent_id="agt_abc123")

Numbers

1# List numbers
2numbers = client.numbers.list(limit=20, offset=0)
3
4# Buy a new number
5number = client.numbers.buy(
6 country="US",
7 area_code="415", # optional, US/CA only
8 agent_id="agt_abc123", # optional: attach immediately
9)
10
11# Get messages for a number
12messages = client.numbers.get_messages(number_id="num_xyz789", limit=50)
13
14# List calls for a number
15calls = client.numbers.list_calls(number_id="num_xyz789", limit=20)
16
17# Release a number (irreversible)
18client.numbers.release(number_id="num_xyz789")

Messages

1# Send an SMS or iMessage
2client.messages.send(
3 agent_id="agt_abc123",
4 to_number="+15559876543",
5 body="Hello from my agent!",
6 media_url="https://example.com/image.png", # optional (MMS/iMessage)
7 number_id="num_xyz789", # optional: send from specific number
8)
9
10# Send a tapback reaction (iMessage only)
11client.messages.react(
12 message_id="msg_abc123",
13 reaction="love", # love, like, dislike, laugh, emphasize, question
14)

Contacts

1# List contacts
2contacts = client.contacts.list(limit=50, search="Alice")
3
4# Create a contact
5contact = client.contacts.create(
6 phone_number="+15559876543",
7 name="Alice Smith",
8 email="alice@example.com",
9 notes="VIP customer",
10)
11
12# Get / update / delete
13contact = client.contacts.get(contact_id="ct_abc123")
14contact = client.contacts.update(contact_id="ct_abc123", name="Alice Johnson")
15client.contacts.delete(contact_id="ct_abc123")

Conversations

1# List all conversations
2convos = client.conversations.list(limit=20, offset=0)
3
4# Get a conversation with messages
5convo = client.conversations.get(
6 conversation_id="conv_abc123",
7 message_limit=50,
8)
9
10# Get messages with cursor pagination
11messages = client.conversations.get_messages(
12 conversation_id="conv_abc123",
13 limit=50,
14 before="msg_older", # cursor pagination
15 after="msg_newer",
16)
17
18# Update conversation metadata
19convo = client.conversations.update(
20 conversation_id="conv_abc123",
21 metadata={"priority": "high", "assigned_to": "team-a"},
22)

Calls

1# List calls with optional filters
2calls = client.calls.list(
3 limit=20,
4 status="completed", # optional filter
5 direction="outbound", # optional filter
6 type="conversation", # optional filter
7 search="+1415", # optional search
8)
9
10# Get a call with transcript
11call = client.calls.get(call_id="call_abc123")
12
13# Make an outbound call with built-in AI (no webhook needed)
14call = client.calls.make(
15 agent_id="agt_abc123",
16 to_number="+15559876543",
17 system_prompt="You are a support agent helping with order inquiries.",
18 initial_greeting="Hello! How can I help you today?",
19 from_number_id="num_xyz789", # optional: call from specific number
20 voice="11labs-Brian", # optional: override agent voice
21)
22
23# Make a webhook-based call (omit system_prompt, requires webhook configured)
24call = client.calls.make(
25 agent_id="agt_abc123",
26 to_number="+15559876543",
27 initial_greeting="Hello!",
28)
29
30# Create a web-based call (browser)
31web_call = client.calls.create_web_call(
32 agent_id="agt_abc123",
33 metadata={"source": "dashboard"},
34)
35
36# Get transcript separately
37transcript = client.calls.get_transcript(call_id="call_abc123")
38
39# Stream transcript via Server-Sent Events
40for event in client.calls.stream_transcript(call_id="call_abc123"):
41 if event["event"] == "turn":
42 print(f"[{event['data']['role']}] {event['data']['content']}")
43 elif event["event"] == "ended":
44 print(f"Call ended ({event['data']['durationSeconds']}s)")

Webhooks (project-level)

1# Get webhook config
2webhook = client.webhooks.get()
3
4# Set or update webhook
5webhook = client.webhooks.set(
6 url="https://your-server.com/webhook",
7 context_limit=10, # 0-50 recent messages in payloads
8 timeout=30, # response timeout in seconds (5-120)
9)
10print(webhook.secret) # save this!
11
12# View delivery history
13deliveries = client.webhooks.list_deliveries(limit=50)
14
15# Get delivery statistics
16stats = client.webhooks.get_delivery_stats(hours=24)
17print(f"Success rate: {stats.success_rate}%")
18
19all_time = client.webhooks.get_all_time_stats()
20
21# Test webhook
22client.webhooks.test(agent_id="agt_abc123") # optional: test for specific agent
23
24# Delete webhook
25client.webhooks.delete()

Usage

1# Get current usage summary (plan, limits, stats)
2usage = client.usage.get()
3print(f"Plan: {usage.plan.name}")
4print(f"Numbers: {usage.numbers.used}/{usage.numbers.limit}")
5print(f"Messages (30d): {usage.stats.messages_last_30d}")
6print(f"Calls (30d): {usage.stats.calls_last_30d}")
7
8# Daily breakdown
9daily = client.usage.get_daily(days=30)
10for day in daily.data:
11 print(f"{day.date}: {day.messages} msgs, {day.calls} calls")
12
13# Monthly breakdown
14monthly = client.usage.get_monthly(months=6)

Error handling

1from agentphone import (
2 AgentPhoneError,
3 AuthenticationError,
4 NotFoundError,
5 RateLimitError,
6)
7
8try:
9 agent = client.agents.get(agent_id="bad-id")
10except NotFoundError:
11 print("Agent not found")
12except AuthenticationError:
13 print("Invalid API key")
14except RateLimitError:
15 print("Too many requests")
16except AgentPhoneError as e:
17 print(f"API error {e.status}: {e.message}")

Webhook verification

Verify incoming webhook signatures and parse events:

1from agentphone import construct_event, verify_webhook, WebhookVerificationError
2
3# Option 1: Verify signature only
4try:
5 verify_webhook(payload, signature, secret)
6except WebhookVerificationError:
7 print("Invalid signature")
8
9# Option 2: Verify + parse into a typed event
10event = construct_event(payload, signature, secret)
11
12if event.event == "agent.message":
13 print(event.data.message)
14 print(event.data.from_number)
15 print(event.channel) # "sms", "imessage", or "voice"
16 for item in event.recent_history: # recent conversation context
17 print(f" [{item.direction}] {item.content}")
18 print(event.conversation_state) # custom metadata

Flask example

1from flask import Flask, request, jsonify
2from agentphone import construct_event
3
4app = Flask(__name__)
5
6@app.route("/webhook", methods=["POST"])
7def webhook():
8 event = construct_event(
9 payload=request.data,
10 signature=request.headers.get("X-Webhook-Signature", ""),
11 secret="your_webhook_secret",
12 )
13
14 # Respond to the caller
15 return jsonify({"response": f"Got your message: {event.data.message}"})

Advanced

Context manager

1with AgentPhone(api_key="YOUR_API_KEY") as client:
2 agents = client.agents.list()
3# session is automatically closed

Custom base URL and timeout

1client = AgentPhone(
2 api_key="YOUR_API_KEY",
3 base_url="https://api.agentphone.ai",
4 timeout=30.0,
5)

Links

  • PyPI package
  • GitHub organization