Metadata-Version: 2.4
Name: carlyemail
Version: 0.1.0
Summary: Real email inboxes for AI agents — create one, then send, receive and reply.
Project-URL: Homepage, https://carlyemail.com
Project-URL: Documentation, https://docs.carlyemail.com
Project-URL: Source, https://github.com/shirschfield/carlyemail
Author: SWH Labs LLC
License-Expression: MIT
Keywords: agent,ai,email,inbox,mcp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Communications :: Email
Requires-Python: >=3.10
Requires-Dist: httpx>=0.24
Description-Content-Type: text/markdown

# carlyemail

Real email inboxes for AI agents. Create one with a call, then send, receive and
reply to real mail — from Gmail, Outlook, anywhere.

```bash
pip install carlyemail
```

## Getting a key

No dashboard step. Sign-up is one unauthenticated call, which is what lets an
agent create its own mailbox while it is running.

```python
from carlyemail import CarlyEmail

signup = CarlyEmail(api_key="none").agent.sign_up(
    {"human_email": "you@example.com", "username": "hello"}
)
print(signup["api_key"], signup["inbox_id"])
```

Confirm the six-digit code that arrives, and the account can send:

```python
carly = CarlyEmail(api_key=signup["api_key"])
carly.agent.verify({"otp_code": "123456"})
```

Or from a terminal: `npx carlyemail signup`.

## Using it

```python
from carlyemail import CarlyEmail

carly = CarlyEmail()          # reads CARLYEMAIL_API_KEY

inbox = carly.inboxes.create({"username": "hello"})

carly.messages.send(
    inbox["email"],
    {"to": ["you@example.com"], "subject": "Hello", "text": "From an agent."},
)

for message in carly.messages.list(inbox["email"])["messages"]:
    print(message["subject"], "from", message["from"])
```

Replying to a *message* keeps the conversation together — `In-Reply-To` and
`References` are set for you, so it threads in the recipient's client instead of
starting a second exchange.

```python
carly.messages.reply(inbox["email"], message["message_id"], {"text": "On it."})
```

## Errors

Every error carries the message, the thing that clears it, and a documentation
link. All three are on the exception.

```python
from carlyemail import CarlyEmailError

try:
    carly.inboxes.create({"username": "hello"})
except CarlyEmailError as error:
    print(error.status, error.code)   # 429 inbox_limit_reached
    print(error.fix)                  # Upgrade the plan, or delete an inbox…
    print(error.docs)
```

## Resources

`agent`, `auth`, `billing`, `inboxes`, `messages`, `threads`, `drafts`, `lists`,
`domains`, `api_keys`, `metrics`, `pods`, `organizations`, `inbox_events`,
`webhooks`.

Every method is generated from the [OpenAPI
spec](https://docs.carlyemail.com/openapi.json), so this client cannot describe
an endpoint the API does not serve.

## Also

- Docs — <https://docs.carlyemail.com>
- CLI — `npx carlyemail`
- MCP — `https://api.carlyemail.com/mcp`, for Claude and other clients

MIT.
