Official Python SDK for Inbounter
Multi-channel agent platform: contacts, conversations, email, SMS, phones, and smart routing.
Inbounter Python SDK
What is Inbounter?
Inbounter is a multi-channel agent platform. It gives AI agents their own contacts, conversations, inboxes, email addresses, phone numbers, and SMS, with built-in security, smart routing, and webhooks.
- Contacts, Create, search, and manage contacts with multi-channel identities
- Conversations, Track and manage conversations across all channels
- Messages, Unified multi-channel send and reply
- Emails, Create email addresses, send and receive email, manage threads
- Phones, Provision phone numbers for your agents
- SMS, Send and receive text messages
- Wait, Pause and wait for incoming emails (OTPs, magic links, replies)
- Routes, Filter, transform, and deliver inbound messages to any destination
- Webhooks, Real-time event notifications
- Credits, Usage-based billing with auto-replenish
Installation
pip install inbounter
Requires Python 3.10+.
Quick Start
from inbounter import Inbounter
client = Inbounter("your-api-key")
# Create a contact
client.contacts.set_workspace_id("wks_123")
contact = client.contacts.create({
"name": "Alice",
"email": "alice@example.com",
"tags": ["lead"],
})
# Send a multi-channel message
client.messages.set_workspace_id("wks_123")
msg = client.messages.send(
channel="email",
to="alice@example.com",
from_="hello@myworkspace.inbounter.to",
body="Welcome to Inbounter!",
subject="Hello",
)
# Reply to a message
client.messages.reply_to(msg["id"], body="Thanks for reaching out!")
# List conversations in a workspace
client.conversations.set_workspace_id("wks_123")
convos = client.conversations.list_by_workspace(limit=20)
# Create an email address
email = client.emails.create(username="hello", domain="myworkspace.inbounter.to")
print(email["address"]) # "hello@myworkspace.inbounter.to"
# Send an email
client.emails.send(
from_="hello@myworkspace.inbounter.to",
to="user@example.com",
subject="Hello",
markdown="# Welcome!",
)
# Send SMS
client.sms.send(
from_="+14155551234",
to="+14155555678",
body="Hello from Inbounter",
)
# Wait for incoming email
result = client.wait.create(
email="hello@myworkspace.inbounter.to",
type="OTP",
)
Feature Support
| Feature | Supported |
|---|---|
contacts.create / list / get / update / delete |
Yes |
contacts.search / add_identity |
Yes |
conversations.list_by_workspace / list_by_contact |
Yes |
conversations.get / update_status / update_metadata / update_starred |
Yes |
messages.send / reply_to / list / get |
Yes |
emails.create / list / get / delete |
Yes |
emails.send / reply / send_batch |
Yes |
emails.messages.list / get / search |
Yes |
emails.threads.list / get |
Yes |
phones.create / list / get / delete |
Yes |
sms.send |
Yes |
sms.messages.list / get |
Yes |
webhooks |
Yes |
wait (email polling) |
Yes |
credits |
Yes |
routes |
Yes |
Contacts
Create and manage contacts with multi-channel identities.
Create a contact
client.contacts.set_workspace_id("wks_123")
contact = client.contacts.create(
name="Alice Smith",
channel="EMAIL",
value="alice@example.com",
)
Get, list, search, and delete
contact = client.contacts.get("ct_abc123")
page = client.contacts.list(limit=20)
contacts = page["items"]
results = client.contacts.search("alice", limit=20)
client.contacts.delete("ct_abc123")
Add an identity
identity = client.contacts.add_identity(
"ct_abc123",
channel="email",
value="alice.work@example.com",
primary=True,
)
Conversations
Track and manage conversations across all channels.
client.conversations.set_workspace_id("wks_123")
# List conversations in the workspace
convos = client.conversations.list_by_workspace(status="OPEN", limit=20)
# List conversations for a contact
convos = client.conversations.list_by_contact("ct_abc123")
# Get a conversation
convo = client.conversations.get("conv_789")
# Update status
client.conversations.update_status("conv_789", "CLOSED")
# Update metadata
client.conversations.update_metadata("conv_789", {"priority": "high"})
# Star/unstar a conversation
client.conversations.update_starred("conv_789", True)
Messages (Multi-Channel)
Send and receive messages on any channel through a unified API.
Send a message
client.messages.set_workspace_id("wks_123")
# Send via email
msg = client.messages.send(
channel="EMAIL",
to="alice@example.com",
from_="support@myworkspace.inbounter.net",
body="<p>Your order has shipped.</p>",
subject="Order Update",
content_type="HTML",
)
# Send via SMS
msg = client.messages.send(
channel="SMS",
to="+14155555678",
from_="+14155551234",
body="Your code is 123456",
)
Reply to a message
client.messages.reply_to("msg_456", body="Thanks for reaching out!")
List and get messages
# List messages in a conversation
messages = client.messages.list("conv_789", limit=20)
# Get a single message
message = client.messages.get("msg_456")
Emails
Create and manage email addresses for your AI agents.
Create an email address
email = client.emails.create(
username="support",
domain="myworkspace.inbounter.to",
)
Get, list, and delete
email = client.emails.get("support@myworkspace.inbounter.to")
emails = client.emails.list()
client.emails.delete("support@myworkspace.inbounter.to")
Send email
# Note: use from_ (with trailing underscore) because "from" is a Python keyword
message = client.emails.send(
from_="support@myworkspace.inbounter.to",
to="customer@example.com",
subject="Your order has shipped",
markdown="Hi! Your order #1234 is on the way.",
)
Reply to a thread
client.emails.reply(
"thread_123",
from_="support@myworkspace.inbounter.to",
markdown="Thanks for reaching out!",
)
Send batch emails
messages = client.emails.send_batch(
from_="updates@myworkspace.inbounter.to",
messages=[
{
"to": "alice@example.com",
"subject": "Welcome!",
"text": "Thanks for signing up.",
},
{
"to": "bob@example.com",
"subject": "Welcome!",
"text": "Thanks for signing up.",
},
],
)
Messages, search, and threads
# List messages for an email address (returns { items, hasMore })
page = client.emails.messages.list(
"support@myworkspace.inbounter.to",
limit=20,
)
messages = page["items"]
# Get a single message (returns { message, routeRuns, deliveries })
details = client.emails.messages.get("msg_456")
# Search messages
results = client.emails.messages.search(q="invoice", email="support@myworkspace.inbounter.to")
# List threads
threads = client.emails.threads.list("support@myworkspace.inbounter.to", limit=20)
# Get a full thread
thread = client.emails.threads.get("support@myworkspace.inbounter.to", "thread_789")
Phones
Provision and manage phone numbers for your AI agents.
# Provision a phone number
phone = client.phones.create(country="US")
# List all phone numbers
phones = client.phones.list()
# Get a specific phone number
phone = client.phones.get("+14155551234")
# Delete a phone number
client.phones.delete("+14155551234")
SMS
Send and receive text messages from your agent's phone numbers.
# Send an SMS (use from_ because "from" is a Python keyword)
sent = client.sms.send(
from_="+14155551234",
to="+14155555678",
body="Your verification code is 123456",
)
# List SMS messages for a phone number (returns { items, hasMore })
page = client.sms.messages.list("+14155551234", limit=20)
messages = page["items"]
# Get a single SMS message (returns { message, routeRuns, deliveries })
details = client.sms.messages.get("msg_456")
Wait (Email Polling)
Wait for a specific inbound email, perfect for OTP codes, magic links, or reply emails.
# Create a wait request for an OTP code
waiter = client.wait.create(
email="agent@myworkspace.inbounter.to",
type="OTP",
timeout=120,
)
# Poll for the result (long-polling)
result = client.wait.poll(waiter["id"], timeout=30)
Routes (Smart Routing)
Routes let you filter inbound messages, apply AI transformations, and deliver to destinations.
Scoping
Routes are scoped to an inbox or a source:
inbox_scope = client.routes.scope_for_inbox("inbox_xyz789")
source_scope = client.routes.scope_for_source("src_abc123")
Create a route
scope = client.routes.scope_for_inbox("inbox_xyz789")
route = client.routes.create(scope, {
"name": "Lead route",
"enabled": True,
})
Filters, transformations, and destinations
# Add a filter
client.routes.create_filter(route["id"], {
"field": "subject",
"operator": "contains",
"value": "pricing",
})
# Add AI extraction
client.routes.create_transformation(route["id"], {
"type": "AI_EXTRACT",
"outputKey": "lead",
"config": {
"fields": [
{"name": "company", "description": "Company name", "type": "string"},
{"name": "budget", "description": "Budget amount", "type": "number"},
]
},
})
# Deliver to a webhook
client.routes.create_destination(scope, route["id"], {
"type": "WEBHOOK",
"name": "Agent webhook",
"config": {"url": "https://example.com/webhook"},
})
List, update, delete, and reorder
routes = client.routes.list(scope)
client.routes.update(scope, "rte_abc123", {"name": "Updated route"})
client.routes.delete(scope, "rte_abc123")
client.routes.reorder(scope, ["rte_first", "rte_second", "rte_third"])
Webhooks
Receive real-time event notifications.
from inbounter import WebhookEvent
# Create a webhook
webhook = client.webhooks.create({
"url": "https://example.com/webhooks/inbounter",
"events": [WebhookEvent.MESSAGE_RECEIVED, WebhookEvent.MESSAGE_SENT],
})
# List webhooks
webhooks = client.webhooks.list()
# Get, update, delete
webhook = client.webhooks.get("whk_abc123")
client.webhooks.update("whk_abc123", {"events": [WebhookEvent.MESSAGE_RECEIVED]})
client.webhooks.delete("whk_abc123")
# Pause and resume
client.webhooks.pause("whk_abc123", reason="Maintenance window")
client.webhooks.resume("whk_abc123")
# Test a webhook
client.webhooks.test("whk_abc123")
Credits
View and configure usage-based credits for your workspace.
# Get current credit balance and recent ledger entries
credits = client.credits.get(ledger_limit=10)
print(credits)
# Update auto-replenish settings
client.credits.update({
"autoReplenishEnabled": True,
"autoReplenishThreshold": 100.0,
"autoReplenishAmount": 500.0,
})
Configuration
from inbounter import Inbounter
client = Inbounter("your-api-key", options={
"base_url": "https://api.inbounter.com", # Custom API base URL
"timeout": 30, # Request timeout in seconds (default: 30)
"max_retries": 3, # Max retries on 429/5xx (default: 3)
"api_version": "v1", # API version (default: "v1")
})
# Set workspace context (required for contacts, conversations, messages, routes, and credits)
client.set_workspace_id("wks_123")
# Enable debug mode to log requests and responses
client.set_debug_mode(True)
# Set custom headers
client.set_header("X-Custom-Header", "value")
client.set_headers({"X-Foo": "bar", "X-Baz": "qux"})
Error Handling
All errors extend InbounterError and include structured metadata:
from inbounter import (
InbounterError,
APIError,
AuthenticationError,
RateLimitError,
NetworkError,
TimeoutError,
ValidationError,
)
try:
client.emails.send(from_="", to="", subject="", text="")
except AuthenticationError as e:
print(f"Auth failed: {e}, code={e.code}")
except RateLimitError as e:
print(f"Rate limited: {e}, status={e.status_code}")
except TimeoutError as e:
print(f"Request timed out: {e}")
except NetworkError as e:
print(f"Network error: {e}")
except ValidationError as e:
print(f"Validation error: {e}, data={e.data}")
except APIError as e:
print(f"API error: {e}, status={e.status_code}, request_id={e.request_id}")
except InbounterError as e:
print(f"General error: {e}")
| Exception | Trigger |
|---|---|
InbounterError |
Base class for all SDK errors |
APIError |
Non-2xx response from the API |
AuthenticationError |
Invalid or missing API key (401) |
RateLimitError |
Too many requests (429), after retries |
NetworkError |
Connection or DNS failure |
TimeoutError |
Request exceeded timeout |
ValidationError |
Invalid input parameters |
Documentation
Full API reference and guides: inbounter.com/docs
Other SDKs
| Language | Package | Install |
|---|---|---|
| Node.js / TypeScript | @inbounter/node |
npm install @inbounter/node |
| Go | inbounter-go |
go get github.com/inbounter/inbounter-go |
| Rust | inbounter |
cargo add inbounter |
| CLI | @inbounter/cli |
npm install -g @inbounter/cli |
Contributing
We welcome contributions!
- Fork the repo and create your branch:
git checkout -b feat/awesome - Add tests and update documentation as needed
- Open a PR against
main
License
Release files for inbounter 1.1.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 | |
|---|---|---|---|
| inbounter-1.1.0.tar.gz | 17.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| inbounter-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.4 kB
Release files / inbounter-1.1.0.tar.gz
| Download URL | inbounter-1.1.0.tar.gz |
|---|---|
| Size | 17.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a7835cf0a256e92a4450cea37fe324275b4dc627bc4920034f650e4886ad8f0b
|
|
BLAKE2b-256 checksum How to use checksums |
04ef3b29149c26fb244b97a68157e413040b3da6de90782b023f1f0e2e290fbf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 27, 2026.
Transparency logRelease files / inbounter-1.1.0-py3-none-any.whl
| Download URL | inbounter-1.1.0-py3-none-any.whl |
|---|---|
| Size | 23.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3cb153fff9be88f551d7524cfe3f0ffbd9b31bb3857ae04fc7958a5d3d77925a
|
|
BLAKE2b-256 checksum How to use checksums |
cf77772ac3f0d58be97547a2751ee127e2b43aa4dc1199cc259642e22fa9358e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 27, 2026.
Transparency log