> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wazobiamail.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Install wazobiamail from PyPI for typed, zero-dependency transactional email in Django, FastAPI, Flask, scripts and workers.

`wazobiamail` is the official Python SDK: a synchronous, fully typed client with **zero runtime dependencies** (standard library only). It is a good fit for Django, FastAPI, Flask, background workers and one-off scripts.

> [card] [PyPI package](https://pypi.org/project/wazobiamail/)
>
> `wazobiamail` — version 0.1.0

> [card] [Source](https://github.com/WazobiaMail/wazobiamail-python)
>
> WazobiaMail/wazobiamail-python

## At a glance

| | |
| - | - |
| Runtime | Python 3.9+ |
| Package | `wazobiamail` |
| Install | `pip install wazobiamail` |
| Dependencies | None at runtime |
| Types | PEP 561 (`py.typed`), dataclass models |
| Source | [github.com/WazobiaMail/wazobiamail-python](https://github.com/WazobiaMail/wazobiamail-python) |

## Install

```bash theme={null}
pip install wazobiamail
```

## Configure

```python theme={null}
from wazobiamail import WazobiaMail

client = WazobiaMail(api_key="wzbm_live_...")
# or read WAZOBIA_API_KEY / WAZOBIAMAIL_API_KEY from the environment:
client = WazobiaMail()
```

## Send your first email

```python theme={null}
from wazobiamail import WazobiaMail

client = WazobiaMail(api_key="wzbm_live_...")

receipt = client.messages.send(
    to="customer@example.com",
    sender="Acme <hello@mail.example.com>",
    subject="Your order shipped",
    html="<p>Your order is on its way.</p>",
    text="Your order is on its way.",
    idempotency_key="order-1042-shipped",
)
print(receipt.data.tracking_id)
```

## What you can do

* `client.messages` — send, multipart attachments, spam check, tracking, email logs.
* `client.domains` — create/list/verify domains, DNS records, Cloudflare sync.
* `client.mailboxes` — provision mailboxes, credentials, storage, headless inbox.
* `client.templates`, `client.tracking`, `client.webhooks` — templates and verification.
* `client.billing`, `client.units`, `client.plans`, `client.api_keys`, `client.smtp_relays`, `client.smtp_access`, `client.support`, `client.status`.

## Django

Use the client from sync views, forms signals or Celery/RQ tasks. A single module-level client is fine because each request uses a short-lived connection.

```python theme={null}
# email_service.py
from functools import lru_cache
from django.conf import settings
from wazobiamail import WazobiaMail

@lru_cache
def get_client() -> WazobiaMail:
    return WazobiaMail(api_key=settings.WAZOBIA_API_KEY)

def send_welcome(user):
    return get_client().messages.send(
        to=user.email,
        subject="Welcome",
        html="<p>Your account is ready.</p>",
        sender="Acme <hello@mail.example.com>",
        idempotency_key=f"welcome-{user.pk}",
    )
```

In an `async def` Django view:

```python theme={null}
from asgiref.sync import sync_to_async
await sync_to_async(send_welcome)(user)
```

## FastAPI

The SDK is synchronous. Use a normal `def` endpoint (FastAPI runs it in a threadpool) or `run_in_threadpool` from an async endpoint:

```python theme={null}
from fastapi import FastAPI, HTTPException
from fastapi.concurrency import run_in_threadpool
from wazobiamail import WazobiaMail, WazobiaError

app = FastAPI()
client = WazobiaMail()

@app.post("/send")
async def send_email():
    try:
        return await run_in_threadpool(
            client.messages.send,
            to="customer@example.com",
            subject="Hello",
            html="<p>Hi there.</p>",
            sender="Acme <hello@mail.example.com>",
        )
    except WazobiaError as exc:
        raise HTTPException(status_code=502, detail=str(exc)) from exc
```

## Webhooks

Verify the raw request body before parsing JSON.

Django:

```python theme={null}
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def wazobia_webhook(request):
    event = get_client().webhooks.construct_event(
        request.body,
        request.headers.get("X-Wazobia-Signature", ""),
        settings.WAZOBIA_WEBHOOK_SECRET,
    )
    return JsonResponse({"received": True})
```

FastAPI:

```python theme={null}
from fastapi import Request

@app.post("/webhooks/wazobia")
async def wazobia_webhook(request: Request):
    body = await request.body()
    event = client.webhooks.construct_event(
        body,
        request.headers.get("X-Wazobia-Signature", ""),
        WEBHOOK_SECRET,
    )
    return {"received": True}
```

## Errors

Catch `WazobiaError` for all SDK exceptions, or specific classes such as `WazobiaAuthenticationError`, `WazobiaValidationError`, `WazobiaRateLimitError`, `WazobiaTimeoutError`, `WazobiaConnectionError` and `WazobiaServerError`. Webhook verification raises `WazobiaWebhookError`.

## Links

* [PyPI](https://pypi.org/project/wazobiamail/)
* [GitHub](https://github.com/WazobiaMail/wazobiamail-python)
* [Full README](https://github.com/WazobiaMail/wazobiamail-python#readme)
* [All official SDKs](https://docs.wazobiamail.com/docs/guides/sdks.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.