Metadata-Version: 2.4
Name: mailsai
Version: 0.2.0
Summary: Email API for AI agents — Python SDK. Per-agent email addresses on your domain, per-agent reputation, and prompt-injection scanning on every inbound. Send, receive structured inbound replies, and identify agents via REST. Intent + entity extraction is opt-in.
Author-email: "Mails.ai" <support@mails.ai>
License: MIT
Project-URL: Homepage, https://mails.ai
Project-URL: Documentation, https://mails.ai/docs
Project-URL: Source, https://github.com/RolloutsAI/mailsai
Project-URL: Issues, https://github.com/RolloutsAI/mailsai/issues
Keywords: email,ai,agent,mcp,mails.ai,agent-identity,sender-reputation,agent-email,prompt-injection,transactional-email
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24.0
Dynamic: license-file

# mailsai

Email API for AI agents — Python SDK.

Per-agent email addresses on your domain, per-agent reputation, and prompt-injection scanning on every inbound. Your agent reads the reply and decides what to say — intent + entity extraction is opt-in.

```bash
pip install mailsai
```

## Quick start

Create the agent once (this mints its inbox address), then send from it. Skipping the
create step is the most common first-run error — `agent("sarah")` only *references* an
agent, it does not create one, so sending returns `404 agent_not_found`.

```python
from mailsai import Client, agent

# Reads MAILS_API_KEY from env (or pass api_key=... explicitly)
client = Client()

# One-time setup: create the agent. It gets sarah@<your-workspace>.mails.ai
client.create_agent("sarah")

sarah = agent("sarah")

# mails.ai is transactional-only: mail the recipient asked for. Cold outreach and bulk
# marketing are refused with 422 cold_email_prohibited — that is deliberate, and it is
# what keeps the sending reputation clean for everyone on the platform.
sarah.send(
    to="you@example.com",
    subject="Your verification code is 481902",
    body="Your verification code is 481902. It expires in 15 minutes.",
)

@sarah.on_reply
def handle(reply):
    # Always present — the delivery + security + identity layer:
    # reply["injection_score"]   -> 0.02   # six-category prompt-injection scan
    # reply["sender_reputation"] -> 0.91   # per-agent reputation
    #
    # Present only when classification is enabled (opt-in, +$0.003/inbound):
    # reply["intent"]            -> "schedule_demo" | "ask_question" | …
    # reply["entities"]          -> {"date": "...", "time": "..."}
    # reply["urgency"]           -> 0.8
    #
    # Your agent reads the reply and decides what to send next.
    print(reply["injection_score"], reply["sender_reputation"])

sarah.start_listening()  # blocks; opens SSE stream and dispatches replies
```

For non-blocking, pass `blocking=False` to `start_listening()` — it returns a daemon thread.

## Lower-level client

```python
from mailsai import create_client

c = create_client()  # reads MAILS_API_KEY

# Send via any agent
c.send("sarah", to="lead@example.com", subject="Demo", body_text="…")

# Resources
threads = c.list_threads(agent_id="agent_abc123")
usage = c.usage()
rep = c.get_reputation(agent_id="agent_abc123")

# Drafts
draft = c.create_draft(agent="sarah", to="lead@example.com", subject="Demo", body_text="…")
c.send_draft(draft["id"])
```

## Webhook verification

```python
from mailsai import verify_webhook

# In your webhook handler:
event = verify_webhook(
    body=request.body.decode(),
    signature=request.headers["X-Mails-Signature"],
    secret=os.environ["MAILS_WEBHOOK_SECRET"],
)
if event is None:
    return Response(status=400)
# event is the verified inbound event dict
```

## Errors

```python
from mailsai import MailsError

try:
    sarah.send(to="blocked@example.com", subject="…", body="…")
except MailsError as e:
    print(e.type, e.code, e.message, e.status, e.request_id)
```

## Configuration

| Param / env var | Default |
|---|---|
| `api_key` / `MAILS_API_KEY` | (required) |
| `base_url` / `MAILS_BASE_URL` | `https://api.mails.ai` |

## Documentation

- Full docs: [mails.ai/docs](https://mails.ai/docs)
- Source: [github.com/RolloutsAI/mailsai](https://github.com/RolloutsAI/mailsai/tree/main/packages/sdk-py)

## License

MIT
