CarlyEmail docs

1. Create an inbox and a key

Sign-up is unauthenticated. One call returns an organization, an inbox and an API key — which is what lets an agent bootstrap its own mailbox without a human opening a dashboard.

```bash cURL curl -X POST https://api.carlyemail.com/v0/agent/sign-up \ -H 'content-type: application/json' \ -d '{ "human_email": "you@yourcompany.com", "username": "support" }'

```python Python
import httpx

r = httpx.post(
    "https://api.carlyemail.com/v0/agent/sign-up",
    json={"human_email": "you@yourcompany.com", "username": "support"},
)
account = r.json()

```typescript TypeScript const res = await fetch("https://api.carlyemail.com/v0/agent/sign-up", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ human_email: "you@yourcompany.com", username: "support", }), }); const account = await res.json();

```json Response
{
  "organization_id": "org_00ms93lsavnm83rw519vzpgw",
  "inbox_id": "support@agents.carlyemail.com",
  "api_key": "ce_us_dvfstqsgs0k7f0o7kkxafozcitwrv46cpp9tas03"
}

Warning

The key is returned once and stored only as a hash. There is no endpoint that will show it to you again. Repeating sign-up for the same human_email rotates the key and revokes the previous one.

Sign-up is idempotent by human_email, so a retrying agent is never wedged — it gets a fresh key rather than an error.

2. Confirm the address

A six-digit code goes to the human_email you gave. Until it is confirmed the key can read and organize mail but cannot send — see limits.

curl -X POST https://api.carlyemail.com/v0/agent/verify \
  -H "Authorization: Bearer $CARLYEMAIL_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"otp_code": "307354"}'

Once verified, the inbox moves to the apex domain (carlyemail.com) for new inboxes, and sending is enabled.

3. Send

```bash cURL curl -X POST "https://api.carlyemail.com/v0/inboxes/$INBOX_ID/messages/send" \ -H "Authorization: Bearer $CARLYEMAIL_API_KEY" \ -H 'content-type: application/json' \ -d '{ "to": ["someone@example.org"], "subject": "Hello", "text": "Sent from an agent." }'

```python Python
httpx.post(
    f"https://api.carlyemail.com/v0/inboxes/{inbox_id}/messages/send",
    headers={"Authorization": f"Bearer {api_key}"},
    json={"to": ["someone@example.org"], "subject": "Hello", "text": "Sent from an agent."},
)

4. Read what comes back

curl "https://api.carlyemail.com/v0/inboxes/$INBOX_ID/messages" \
  -H "Authorization: Bearer $CARLYEMAIL_API_KEY"

Replies are threaded automatically — a reply to a message you sent arrives on the same thread_id. See threads.

Tip

Read extracted_text rather than text when reasoning over a thread. It has the quoted reply chain stripped, so a model sees the new message rather than the whole history repeated.

Next