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

# Python

# Python SDK

Official **Python** client for the Mailofly REST API.

**Package:** [`mailofly`](https://pypi.org/project/mailofly/) · **Requires:** Python 3.9+ · **Quickstart:** [Python](../getting-started/python.md)

***

## Install

```bash theme={null}
pip install mailofly
# or
uv add mailofly
```

***

## Initialize

```python theme={null}
import os
from mailofly import Mailofly, MailoflyError

client = Mailofly(
    os.environ["MAILOFLY_API_KEY"],
    # base_url="https://www.mailofly.com",  # optional override
)
```

Create an API key under **[API keys](https://www.mailofly.com/user/api-keys)** first.

***

## Send email

```python theme={null}
try:
    result = client.emails.send({
        "from": "Acme <onboarding@example.com>",
        "to": ["alex@example.com"],
        "subject": "Hello",
        "html": "<p>Thanks for signing up.</p>",
    })
    print("Sent:", result["id"])
except MailoflyError as e:
    print(e.status, e.error, e.detail_message)
    raise
```

### With a saved template

```python theme={null}
client.emails.send({
    "from": "Acme <onboarding@example.com>",
    "to": ["alex@example.com"],
    "template": {
        "id": "uuid-of-template",
        "variables": {"first_name": "Alex"},
    },
})
```

`client.compose.send` is deprecated and forwards to `/v1/emails`.

### Batch send (up to 100 emails)

```python theme={null}
result = client.batch.send([
    {
        "from": "Acme <onboarding@example.com>",
        "to": ["foo@example.com"],
        "subject": "hello world",
        "html": "<h1>it works!</h1>",
    },
    {
        "from": "Acme <onboarding@example.com>",
        "to": ["bar@example.com"],
        "subject": "world hello",
        "html": "<p>it works!</p>",
    },
])
print([row["id"] for row in result["data"]])
```

***

## Resources

| Namespace          | Methods                                                                 |
| ------------------ | ----------------------------------------------------------------------- |
| `client.accounts`  | `list`, `create`, `get`, `update`, `delete`                             |
| `client.contacts`  | `list`, `create`, `get`, `update`, `delete`                             |
| `client.templates` | `list`, `create`, `get`, `update`, `delete`                             |
| `client.segments`  | `list`, `create`, `get`, `update`, `delete`, `contacts.list/add/remove` |
| `client.campaigns` | `list`, `create`, `get`, `update`, `delete`, `runs`, `send`             |
| `client.emails`    | `list`, `get`, `send`                                                   |
| `client.batch`     | `send`                                                                  |
| `client.compose`   | `send` (deprecated)                                                     |
| `client.mail_logs` | `list`                                                                  |

### Examples

```python theme={null}
accounts = client.accounts.list()

client.contacts.create({
    "email": "alex@example.com",
    "first_name": "Alex",
    "custom_fields": {"plan": "pro"},
})

client.campaigns.send("campaign-uuid", {"send_now": True})

logs = client.mail_logs.list(status="failed", page=1, page_size=50)
```

***

## Discovery (no API key)

```python theme={null}
meta = Mailofly.discovery()
print(meta.get("resources"))
```

***

## Error handling

```python theme={null}
from mailofly import MailoflyError

try:
    client.accounts.list()
except MailoflyError as e:
    # e.status — HTTP status
    # e.error — error code string
    # e.detail_message — human-readable message
    pass
```

***

## Related

* [Python quickstart](../getting-started/python.md)
* [API: Emails](https://docs.mailofly.com/api/emails)


## Related topics

- [SDKs](/sdks/index.md)
- [Python](/getting-started/python.md)
- [Http](/getting-started/http.md)
- [Manage Emails](/sending/manage-emails.md)
- [Introduction](/sending/introduction.md)
