Skip to main content

AI Inbx Python SDK

Website · Documentation

The official typed Python client for AI Inbx API v2. It supports synchronous and asynchronous applications, bounded retries, per-request timeouts, raw responses, idempotency keys, and signed webhook verification.

pip install aiinbx

Send an email

from aiinbx import AIInbx

with AIInbx() as client:  # reads AI_INBX_API_KEY
    email = client.emails.send(
        {
            "from_": {"name": "AI Inbx", "address": "hello@example.com"},
            "to": ["ada@example.com"],
            "subject": "Hello",
            "text": "Sent with AI Inbx",
        },
        idempotency_key="welcome-ada-v1",
    )
    print(email["id"])

The default base URL is https://api.aiinbx.com/api/v2. Use base_url= to point the client at a local or self-hosted API. Requests time out after 60 seconds. The client retries a 429 up to two times always, and network failures, HTTP 408 and 5xx when a retry cannot act twice — a GET, PUT or DELETE, or a send, reply or forward with an idempotency_key — honoring Retry-After. It never retries a 409 or other 4xx.

Async

from aiinbx import AsyncAIInbx

async with AsyncAIInbx() as client:
    page = await client.threads.list(limit=20)

AsyncAIInbx mirrors AIInbx method for method. Each API resource is an attribute of the client — client.emails, client.webhook_endpoints, client.pacing_rules — and every endpoint page in the API reference shows its Python call.

Every operation takes its request body as one dictionary — a TypedDict from aiinbx.models, named after the API's schema (SendEmailRequest, UpdateDomainRequest, …) — and its query filters as keyword arguments. The one spelling difference from the wire is from_, since from is a Python keyword; the SDK sends it as from. Resources, models and these method signatures are generated from the API contract, so a change to the API is a change here on the next release.

Reply and pagination

Replies infer the sender, recipients, subject, and RFC reply headers from the thread. Supply only the content for the common case:

reply = client.threads.reply(
    "thr_123",
    {"text": "Sounds good — see you Thursday."},
    idempotency_key="reply-thr-123-v1",
)

# `iter()` follows cursors lazily. Async resources support `async for`.
for email in client.emails.iter(direction="inbound"):
    print(email["subject"])

async for message in async_client.threads.iter_messages("thr_123"):
    print(message["snippet"])

Sends, replies and forwards take an idempotency_key; every call takes a timeout and works under with_raw_response.

Spaces

A space groups a customer's domains, mailboxes and mail. Pass space_id when creating a domain, mailbox, suppression or pacing rule; emails and threads inherit the space of the domain or mailbox they went through. Lists of those take a space= filter: pass a space ID for that space, "none" for only the workspace's own resources (space_id of None), or omit it for both the workspace and all spaces. API keys and webhook endpoints belong to the workspace: one key reaches every space, and one endpoint receives every space's events, each stamped with its space_id. Spaces are optional — a workspace that never creates one sees space_id of None everywhere.

external_id is your own id for the customer — unique per workspace, so a second create for the same customer fails with 409 external_id_taken — and spaces.list(external_id=...) finds the space by it.

space = client.spaces.create({"name": "Acme", "external_id": "cus_8812"})
# Later, from your side of the map:
same = client.spaces.list(external_id="cus_8812")["data"][0]
# One label under a wildcard you own (`*.mail.example.com`) is a subdomain: no DNS to publish.
client.domains.create({"name": "acme.mail.example.com", "space_id": space["id"]})
client.emails.send(
    {
        "from_": "Acme <hello@acme.mail.example.com>",
        "to": ["ada@example.com"],
        "subject": "Welcome",
        "text": "Sent from Acme's own subdomain.",
    }
)

Raw responses and request IDs

response = client.with_raw_response.emails.retrieve("eml_123")
print(response.status_code, response.request_id)
email = response.json()

# The most recently completed response is also exposed on the client.
print(client.last_request_id)

Non-success responses raise typed subclasses of APIStatusError. These include status_code, request_id, response headers, and the decoded body.

Verify webhooks

Always pass the unmodified request body. The verifier signs <unix_timestamp>.<payload> with HMAC-SHA256 and rejects payloads older than five minutes by default.

event = client.webhooks.verify(
    request_body,
    request.headers["AIInbx-Signature"],
    webhook_secret,
)

# `event` is the `aiinbx.WebhookEvent` union, generated from the API contract.
# Type checkers narrow `data` from the event type.
if event["type"] == "email.bounced":
    for recipient in event["data"]["recipients"]:
        print(recipient)

A bad signature, a malformed header, or a timestamp outside the window raises WebhookVerificationError. Override the replay window with tolerance= (seconds; 0 accepts only the same second) only when necessary.

Metadata

Release files for aiinbx 4.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aiinbx 4.4.0
File Size Uploaded Provenance Actions
aiinbx-4.4.0.tar.gz 113.0 kB With provenance Details for aiinbx-4.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for aiinbx 4.4.0
File Interpreter ABI Platform Actions
aiinbx-4.4.0-py3-none-any.whl Python 3 none any Details for aiinbx-4.4.0-py3-none-any.whl

Total release size: 189.8 kB

Release files / aiinbx-4.4.0.tar.gz

Download URL aiinbx-4.4.0.tar.gz
Size 113.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f3461660533e634cb3711c65fd874b1e31db28bfa99a3128f3da05ea5b5d9d69
BLAKE2b-256 checksum
How to use checksums
d9ae17c3a1c159e013e3a68fe8b54aa4e423945e5edf0b454fbbb73777747f4c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Release files / aiinbx-4.4.0-py3-none-any.whl

Download URL aiinbx-4.4.0-py3-none-any.whl
Size 76.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
664f66f9e4089503c44298c8687f3b29eb290d2bfcc5a8e32890dd7a5ae0c328
BLAKE2b-256 checksum
How to use checksums
765796ab55e34c7d9c5da4d2d870a19ddb5e5b055dea849fe900caf0f8166d73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Security for aiinbx 4.4.0

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for aiinbx-4.4.0.tar.gz

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 Nov 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

4.4.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page