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.0.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.0.0
File Size Uploaded Provenance Actions
aiinbx-4.0.0.tar.gz 110.5 kB With provenance Details for aiinbx-4.0.0.tar.gz

Built distribution (wheel)

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

Total release size: 184.7 kB

Release files / aiinbx-4.0.0.tar.gz

Download URL aiinbx-4.0.0.tar.gz
Size 110.5 kB
Tags Source
SHA-256 checksum
How to use checksums
764b86d6ebd4bf621dd7d745dec4cc0e20c44ea367698d3d3e4ca84820b20baa
BLAKE2b-256 checksum
How to use checksums
65fbb83311d317a83fbad1f65ec0b7d434781e30d485b6f94be06645f8f8d6ad
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 4, 2026.

Transparency log

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

Download URL aiinbx-4.0.0-py3-none-any.whl
Size 74.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7577741c8c73ac4d9e6c19e4e55320c34a04e317787159ad77ee7c6f5fb1a72a
BLAKE2b-256 checksum
How to use checksums
c68f7c3a99b0363b78b91947126e8167edc49736143ddf1e675e6508bf2b5818
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 4, 2026.

Transparency log

Security for aiinbx 4.0.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.0.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 4, 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.0.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