inboxili (Python)
Python client for the Inboxili transactional email API. No dependencies, Python 3.9+, type hints included.
pip install inboxili
Send an email
import os
from inboxili import Inboxili
client = Inboxili(os.environ["INBOXILI_API_KEY"])
result = client.emails.send(
to="ada@example.com",
from_email="hello@yourdomain.com", # must be a sender on a verified domain
from_name="Acme",
subject="Welcome, {{first_name}}",
html_body="<p>Hi {{first_name}}, your account is ready.</p>",
text_body="Hi Ada, your account is ready.",
template_data={"first_name": "Ada"},
)
print(result.status, result.message_id)
status == "sent" means the delivery provider accepted the message, not that it reached the inbox. Use webhooks for delivery events.
From a template
client.emails.send(
to="ada@example.com",
from_email="hello@yourdomain.com",
template_id="00000000-0000-0000-0000-000000000000",
template_data={"first_name": "Ada"},
)
Authentication
Create an API key in the dashboard under Settings, Developer, with the transactional:send scope. Load it from the environment or a secret manager. Never commit it.
Options
Inboxili(api_key, base_url="https://api.inboxili.com/api/v1", timeout=10.0, max_retries=2)
Error handling
from inboxili import InboxiliError, InboxiliConnectionError
try:
client.emails.send(...)
except InboxiliError as e:
print(e.status, e.code, e.message) # e.g. 422 sender_not_verified
except InboxiliConnectionError:
... # no response; the email may or may not have been sent
| Status | code |
Meaning |
|---|---|---|
| 401 | unauthorized |
Missing, invalid, revoked or expired key |
| 403 | forbidden |
Missing scope, or IP not allowed |
| 422 | validation_error, sender_not_verified, send_failed |
Bad request, unverified sender, or provider rejection |
| 429 | rate_limited |
Over 120 requests per minute for this key |
Retries. Only HTTP 429 is retried (max_retries, default 2), because the request was rejected before sending. Timeouts and 5xx are never retried: the API has no idempotency key, so a retry could send a duplicate.
Webhooks
from inboxili import verify_webhook_signature
ok = verify_webhook_signature(raw_body_bytes, request.headers["X-Inboxili-Signature"], os.environ["INBOXILI_WEBHOOK_SECRET"])
Pass the raw body bytes, not a re-serialised object.
Limits of the API
One recipient per request. No attachments, CC, BCC or reply-to fields. No scheduling. See the API reference.
Development
PYTHONPATH=src python -m unittest discover -s tests
Links
Documentation · Python guide · Report a vulnerability · MIT licensed
Metadata
Release files for inboxili 0.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 | |
|---|---|---|---|
| inboxili-0.1.0.tar.gz | 6.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| inboxili-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.7 kB
Release files / inboxili-0.1.0.tar.gz
| Download URL | inboxili-0.1.0.tar.gz |
|---|---|
| Size | 6.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5f4ca2b8be0f0f0be9c71e04827af765ba457764c6e36de4ed699bd0b29a5eb2
|
|
BLAKE2b-256 checksum How to use checksums |
9c9a537786ad850d4f2bc4bbfc0141eccb79fed82f6f57f37e5573de862e1075
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / inboxili-0.1.0-py3-none-any.whl
| Download URL | inboxili-0.1.0-py3-none-any.whl |
|---|---|
| Size | 6.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78e34eddab2dadab53926d8f20f79e4dbf98e064bd39d8be7c078fcb4d1d5fff
|
|
BLAKE2b-256 checksum How to use checksums |
63d1bc561da3ff22b7e78394aaf9ed46a948ea17fc12e317ef0f6b8a149a25e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|