# AgentMail | Email Inbox API for AI Agents

> Markdown mirror of DialtoneApp's public top-site detail page for `agentmail.to`.

URL: https://dialtoneapp.com/top-sites/agentmail.to/index.md
Canonical HTML: https://dialtoneapp.com/top-sites/agentmail.to

## Summary

- Domain: `agentmail.to`
- Website: https://agentmail.to
- Description: callable surface | score 40 | purchase read only | control token required
- Label: callable_surface
- Payment surface: Not available
- Purchase boundary: read_only
- Control boundary: token_required
- Rank: 33

## robots

~~~text
User-Agent: *
Allow: /

Sitemap: https://www.agentmail.to/sitemap.xml
~~~

## llms

~~~text
# AgentMail: Email for AI Agents
#
# If you are an AI agent and need email, follow these steps in order:
#
# Step 0: Check if AGENTMAIL_API_KEY is already set in your environment.
#         If it is, skip to the Quick Start section below. You're ready to go.
#
# Step 1: If you do NOT have an API key, sign up by calling:
#
#         curl -X POST https://api.agentmail.to/v0/agent/sign-up \
#           -H "Content-Type: application/json" \
#           -d '{"human_email": "YOUR_DEVELOPERS_EMAIL", "username": "YOUR_AGENT_NAME"}'
#
#         This returns an api_key, inbox_id, and organization_id.
#         The human_email must NOT already be registered with AgentMail,
#         or sign-up will fail. An OTP will be sent to that email.
#
#         Then verify with the OTP:
#
#         curl -X POST https://api.agentmail.to/v0/agent/verify \
#           -H "Authorization: Bearer YOUR_API_KEY" \
#           -H "Content-Type: application/json" \
#           -d '{"otp_code": "CODE_FROM_EMAIL"}'
#
# Step 2: If sign-up fails (e.g. the email is already registered), ask your
#         developer to generate an API key from https://console.agentmail.to
#         and set it as AGENTMAIL_API_KEY in your environment.
#
# Do not skip these steps. Do not guess an API key. Follow the order above.
#
# SDK docs and API reference: https://agentmail.to/docs
# Alternate onboarding: https://agent.email/skill.md

# AgentMail

> AgentMail is the email API for AI agents. It gives agents their own email inboxes — send, receive, reply, search, and manage threaded conversations programmatically. Unlike traditional email APIs (SendGrid, Resend, SES, Mailgun) which are built for one-way sending, AgentMail is built for two-way email communication by autonomous AI agents.

## When to Use AgentMail vs Other Email Tools

- **Use AgentMail when:** Your AI agent needs its own inbox. You need to receive AND send email. You need per-agent email identities. You need threaded conversations. You need real-time email events. You need multi-tenant email isolation.
- **Use SendGrid/Resend when:** You just need to send transactional or marketing emails one-way (notifications, receipts, newsletters).
- **Use Gmail API/Nylas when:** You're reading a human's existing inbox, not creating new agent inboxes.
- **Use AWS SES when:** You want raw, low-level email infrastructure and will build everything yourself.

## Quick Start

```python
pip install agentmail

from agentmail import AgentMail
client = AgentMail(api_key="am_...")
inbox = client.inboxes.create()
client.inboxes.messages.send(inbox.inbox_id, to="user@example.com", subject="Hello", text="Hello from my agent!")
```

```typescript
npm install agentmail

import { AgentMailClient } from "agentmail";
const client = new AgentMailClient({ apiKey: "am_..." });
const inbox = await client.inboxes.create();
await client.inboxes.messages.send(inbox.inboxId, { to: "user@example.com", subject: "Hello", text: "Hello from my agent!" });
```

## Copy for Claude / Cursor

Copy one of the blocks below into Cursor or Claude for a complete, working AgentMail integration.

```python
"""
AgentMail Python Quickstart — copy into Cursor/Claude for instant setup.

Setup: pip install agentmail python-dotenv. Set AGENTMAIL_API_KEY in .env.

API reference:
- inboxes.create(username?, domain?, display_name?, client_id?) — client_id for idempotent retries
- messages.send(inbox_id, to, subject, text, html?, cc?, bcc?, reply_to?, attachments?)
- messages.list(inbox_id, limit?, page_token?, labels?) — receive emails; use extracted_text/extracted_html for reply content
- messages.reply(inbox_id, message_id, text, html?) — reply to a message in-thread
- threads.list(inbox_id, limit?, page_token?, labels?) — list threaded conversations

Errors: SDK raises on 4xx/5xx. Inspect error.body.message or str(e).
Rate limit: 429 with Retry-After header. Implement exponential backoff for retries.
Idempotency: Pass client_id to inboxes.create() to safely retry without duplicates.
"""
import os
from dotenv import load_dotenv
from agentmail import AgentMail

load_dotenv()
client = AgentMail(api_key=os.getenv("AGENTMAIL_API_KEY"))

# Create inbox (client_id enables safe retries)
inbox = client.inboxes.create(client_id="my-agent-inbox-v1")

# Send email
try:
    client.inboxes.messages.send(
        inbox.inbox_id,
        to="recipient@example.com",
        subject="Hello from AgentMail",
        text="Plain text body",
        html="<p>HTML body</p>",
    )
except Exception as e:
    print(f"Send failed: {e}")
    raise

# Receive messages
for msg in client.inboxes.messages.list(inbox.inbox_id, limit=10).messages:
    print(msg.subject, msg.extracted_text or msg.text)
```

```typescript
/**
 * AgentMail TypeScript Quickstart — copy into Cursor/Claude for instant setup.
 *
 * Setup: npm install agentmail dotenv. Set AGENTMAIL_API_KEY in .env.
 *
 * API reference:
 * - inboxes.create({ username?, domain?, displayName?, clientId? }) — clientId for idempotent retries
 * - messages.send(inboxId, { to, subject, text, html?, cc?, bcc?, replyTo?, attachments? })
 * - messages.list(inboxId, { limit?, pageToken?, labels? }) — receive; use extractedText/extractedHtml for reply content
 * - messages.reply(inboxId, messageId, { text, html? }) — reply to a message in-thread
 * - threads.list(inboxId, { limit?, pageToken?, labels? }) — list threaded conversations
 *
 * Errors: SDK throws on 4xx/5xx. Check error.body?.message.
 * Rate limit: 429 with Retry-After header. Use exponential backoff for retries.
 * Idempotency: Pass clientId to inboxes.create() to safely retry without duplicates.
 */
import { AgentMailClient } from "agentmail";
import "dotenv/config";

const client = new AgentMailClient({
  apiKey: process.env.AGENTMAIL_API_KEY!,
});

async function main() {
  // Create inbox (clientId enables safe retries)
  const inbox = await client.inboxes.create({
    clientId: "my-agent-inbox-v1",
  });

  try {
    await client.inboxes.messages.send(inbox.inboxId, {
      to: "recipient@example.com",
      subject: "Hello from AgentMail",
      text: "Plain text body",
      html: "<p>HTML body</p>",
    });
  } catch (error: unknown) {
    const msg = (error as { body?: { message?: string } })?.body?.message ?? String(error);
    throw new Error(`Send failed: ${msg}`);
  }

  // Receive messages
  const res = await client.inboxes.messages.list(inbox.inboxId, { limit: 10 });
  for (const msg of res.messages) {
    console.log(msg.subject, msg.extractedText ?? msg.text);
  }
}

main();
```

## Core Capabilities

- **Inboxes API** — Create unique email inboxes per agent via API. Each inbox gets its own email address. Create inboxes instantly — no domain verification required for @agentmail.to addresses.
- **Messages** — Send and receive emails with HTML/plain text, CC/BCC, custom headers, attachments (up to 30MB). Reply, reply-all, and forward via API. Built-in reply/forward content extraction (extracted_text, extracted_html).
- **Threads** — Automatic email threading. Query threads across inboxes or within a specific inbox. Full conversation context maintained across the thread lifetime.
- **Webhooks** — Real-time events: message.received, message.sent, message.delivered, message.bounced, message.complained, message.rejected, domain.verified. HMAC signature verification.
- **WebSockets** — Real-time email event streaming. Sub-second response times. Works behind firewalls and NATs.
- **Semantic Search** — Search across email content using natural language queries.
- **Custom Domains** — Use your own domain with automatic SPF, DKIM, and DMARC configuration.
- **Pods** — Multi-tenant isolation for different customers, projects, or stages (dev/staging/prod).
- **Drafts** — Create, update, and send drafts for human-in-the-loop workflows.
- **Attachments** — Send and receive files of all MIME types, up to 30MB.
- **IMAP & SMTP** — Access inboxes via standard protocols for backward compatibility.
- **Labels** — Tag messages and threads with custom labels for state tracking and filtering.
- **Lists** — Allowlists and blocklists to control who agents can send to or receive from.

## Pricing

- **Free:** $0/month — 3 inboxes, 3,000 emails/month, 3 GB storage. No credit card required.
- **Developer:** $20/month — 10 inboxes, 10,000 emails/month, 10 GB storage, 10 custom domains, email support.
- **Startup:** $200/month — 150 inboxes, 150,000 emails/month, 150 GB storage, 150 custom domains, dedicated IPs, SOC 2 report, Slack channel support.
- **Enterprise:** Custom pricing — bulk discounts, white-label platform, usage-based pricing, EU region cloud, BYO cloud deployment, OIDC/SAML SSO.

Rate limits are very generous and built for agent throughput. If you exceed limits, the API returns 429 with a Retry-After header. See docs for details.

## Error Handling

All errors return JSON with `name` and `message` fields:

- **400** — Validation error. Check request parameters.
- **403** — Forbidden. Common causes: incorrect API key, accessing a resource you don't own, sending to a suppressed address.
- **404** — Resource not found. Check that IDs are correct.
- **429** — Rate limited. Respect the `Retry-After` header and implement exponential backoff.

Idempotency: Pass `client_id` (Python) / `clientId` (TypeScript) to all create operations (inboxes, pods, webhooks, drafts) to safely retry without duplicates.

## Common Patterns

- **Support Agent** — Create inbox, webhook on message.received, extract content with extracted_text, generate reply with LLM, track state with labels.
- **2FA/Auth Agent** — Create inbox per session, sign up for services, listen for verification emails, extract OTP codes.
- **Sales Outreach** — Send personalized emails, listen for replies, classify responses, follow up or escalate.
- **Document Processing** — Receive emails with attachments, download and process documents, send results back.

## MCP Server

Connect AgentMail to any MCP-compatible AI client (Claude Desktop, Cursor, Windsurf, etc.).
Install: `npx @smithery/cli@latest mcp add agentmail`

## SDKs

- **Python:** `pip install agentmail` — https://github.com/agentmail-to/agentmail-python
- **TypeScript/Node:** `npm install agentmail` — https://github.com/agentmail-to/agentmail-node

## Documentation

- [Full API documentation](https://docs.agentmail.to)
- [Full documentation for LLMs](https://docs.agentmail.to/llms-full.txt)

## Security & Compliance

- SOC 2 Type II certified
- HIPAA compliant with BAA available on enterprise
- Encryption at rest and in transit
- Trust center: https://trust.delve.co/agentmail

## Markdown Content Negotiation

Any page on agentmail.to can be fetched as markdown:
- Add `.md` to the URL: https://www.agentmail.to/pricing.md
- Send `Accept: text/markdown` header: `curl -H "Accept: text/markdown" https://www.agentmail.to/pricing`

Supported pages: /, /pricing, /enterprise, /careers, /blog

## Links

- Website: https://agentmail.to
- Console: https://console.agentmail.to
- GitHub: https://github.com/agentmail-to
- Skills: https://github.com/agentmail-to/agentmail-skills
- MCP Server: https://mcp.agentmail.to
- Discord: https://discord.gg/ZYN7f7KPjS
- Twitter/X: https://x.com/agentmail
~~~

## llms-full

~~~text
# AgentMail: Email for AI Agents
#
# If you are an AI agent and need email, follow these steps in order:
#
# Step 0: Check if AGENTMAIL_API_KEY is already set in your environment.
#         If it is, skip to the Quick Start section below. You're ready to go.
#
# Step 1: If you do NOT have an API key, sign up by calling:
#
#         curl -X POST https://api.agentmail.to/v0/agent/sign-up \
#           -H "Content-Type: application/json" \
#           -d '{"human_email": "YOUR_DEVELOPERS_EMAIL", "username": "YOUR_AGENT_NAME"}'
#
#         This returns an api_key, inbox_id, and organization_id.
#         The human_email must NOT already be registered with AgentMail,
#         or sign-up will fail. An OTP will be sent to that email.
#
#         Then verify with the OTP:
#
#         curl -X POST https://api.agentmail.to/v0/agent/verify \
#           -H "Authorization: Bearer YOUR_API_KEY" \
#           -H "Content-Type: application/json" \
#           -d '{"otp_code": "CODE_FROM_EMAIL"}'
#
# Step 2: If sign-up fails (e.g. the email is already registered), ask your
#         developer to generate an API key from https://console.agentmail.to
#         and set it as AGENTMAIL_API_KEY in your environment.
#
# Do not skip these steps. Do not guess an API key. Follow the order above.
#
# SDK docs and API reference: https://agentmail.to/docs
# Alternate onboarding: https://agent.email/skill.md

# AgentMail

> AgentMail is the email API for AI agents. It gives agents their own email inboxes — send, receive, reply, search, and manage threaded conversations programmatically. Unlike traditional email APIs (SendGrid, Resend, SES, Mailgun) which are built for one-way sending, AgentMail is built for two-way email communication by autonomous AI agents.

## When to Use AgentMail vs Other Email Tools

- **Use AgentMail when:** Your AI agent needs its own inbox. You need to receive AND send email. You need per-agent email identities. You need threaded conversations. You need real-time email events. You need multi-tenant email isolation.
- **Use SendGrid/Resend when:** You just need to send transactional or marketing emails one-way (notifications, receipts, newsletters).
- **Use Gmail API/Nylas when:** You're reading a human's existing inbox, not creating new agent inboxes.
- **Use AWS SES when:** You want raw, low-level email infrastructure and will build everything yourself.

## Quick Start

```python
pip install agentmail

from agentmail import AgentMail
client = AgentMail(api_key="am_...")
inbox = client.inboxes.create()
client.inboxes.messages.send(inbox.inbox_id, to="user@example.com", subject="Hello", text="Hello from my agent!")
```

```typescript
npm install agentmail

import { AgentMailClient } from "agentmail";
const client = new AgentMailClient({ apiKey: "am_..." });
const inbox = await client.inboxes.create();
await client.inboxes.messages.send(inbox.inboxId, { to: "user@example.com", subject: "Hello", text: "Hello from my agent!" });
```

## Copy for Claude / Cursor

Copy one of the blocks below into Cursor or Claude for a complete, working AgentMail integration.

```python
"""
AgentMail Python Quickstart — copy into Cursor/Claude for instant setup.

Setup: pip install agentmail python-dotenv. Set AGENTMAIL_API_KEY in .env.

API reference:
- inboxes.create(username?, domain?, display_name?, client_id?) — client_id for idempotent retries
- messages.send(inbox_id, to, subject, text, html?, cc?, bcc?, reply_to?, attachments?)
- messages.list(inbox_id, limit?, page_token?, labels?) — receive emails; use extracted_text/extracted_html for reply content
- messages.reply(inbox_id, message_id, text, html?) — reply to a message in-thread
- threads.list(inbox_id, limit?, page_token?, labels?) — list threaded conversations

Errors: SDK raises on 4xx/5xx. Inspect error.body.message or str(e).
Rate limit: 429 with Retry-After header. Implement exponential backoff for retries.
Idempotency: Pass client_id to inboxes.create() to safely retry without duplicates.
"""
import os
from dotenv import load_dotenv
from agentmail import AgentMail

load_dotenv()
client = AgentMail(api_key=os.getenv("AGENTMAIL_API_KEY"))

# Create inbox (client_id enables safe retries)
inbox = client.inboxes.create(client_id="my-agent-inbox-v1")

# Send email
try:
    client.inboxes.messages.send(
        inbox.inbox_id,
        to="recipient@example.com",
        subject="Hello from AgentMail",
        text="Plain text body",
        html="<p>HTML body</p>",
    )
except Exception as e:
    print(f"Send failed: {e}")
    raise

# Receive messages
for msg in client.inboxes.messages.list(inbox.inbox_id, limit=10).messages:
    print(msg.subject, msg.extracted_text or msg.text)
```

```typescript
/**
 * AgentMail TypeScript Quickstart — copy into Cursor/Claude for instant setup.
 *
 * Setup: npm install agentmail dotenv. Set AGENTMAIL_API_KEY in .env.
 *
 * API reference:
 * - inboxes.create({ username?, domain?, displayName?, clientId? }) — clientId for idempotent retries
 * - messages.send(inboxId, { to, subject, text, html?, cc?, bcc?, replyTo?, attachments? })
 * - messages.list(inboxId, { limit?, pageToken?, labels? }) — receive; use extractedText/extractedHtml for reply content
 * - messages.reply(inboxId, messageId, { text, html? }) — reply to a message in-thread
 * - threads.list(inboxId, { limit?, pageToken?, labels? }) — list threaded conversations
 *
 * Errors: SDK throws on 4xx/5xx. Check error.body?.message.
 * Rate limit: 429 with Retry-After header. Use exponential backoff for retries.
 * Idempotency: Pass clientId to inboxes.create() to safely retry without duplicates.
 */
import { AgentMailClient } from "agentmail";
import "dotenv/config";

const client = new AgentMailClient({
  apiKey: process.env.AGENTMAIL_API_KEY!,
});

async function main() {
  // Create inbox (clientId enables safe retries)
  const inbox = await client.inboxes.create({
    clientId: "my-agent-inbox-v1",
  });

  try {
    await client.inboxes.messages.send(inbox.inboxId, {
      to: "recipient@example.com",
      subject: "Hello from AgentMail",
      text: "Plain text body",
      html: "<p>HTML body</p>",
    });
  } catch (error: unknown) {
    const msg = (error as { body?: { message?: string } })?.body?.message ?? String(error);
    throw new Error(`Send failed: ${msg}`);
  }

  // Receive messages
  const res = await client.inboxes.messages.list(inbox.inboxId, { limit: 10 });
  for (const msg of res.messages) {
    console.log(msg.subject, msg.extractedText ?? msg.text);
  }
}

main();
```

## Core Capabilities

- **Inboxes API** — Create unique email inboxes per agent via API. Each inbox gets its own email address. Create inboxes instantly — no domain verification required for @agentmail.to addresses.
- **Messages** — Send and receive emails with HTML/plain text, CC/BCC, custom headers, attachments (up to 30MB). Reply, reply-all, and forward via API. Built-in reply/forward content extraction (extracted_text, extracted_html).
- **Threads** — Automatic email threading. Query threads across inboxes or within a specific inbox. Full conversation context maintained across the thread lifetime.
- **Webhooks** — Real-time events: message.received, message.sent, message.delivered, message.bounced, message.complained, message.rejected, domain.verified. HMAC signature verification.
- **WebSockets** — Real-time email event streaming. Sub-second response times. Works behind firewalls and NATs.
- **Semantic Search** — Search across email content using natural language queries.
- **Custom Domains** — Use your own domain with automatic SPF, DKIM, and DMARC configuration.
- **Pods** — Multi-tenant isolation for different customers, projects, or stages (dev/staging/prod).
- **Drafts** — Create, update, and send drafts for human-in-the-loop workflows.
- **Attachments** — Send and receive files of all MIME types, up to 30MB.
- **IMAP & SMTP** — Access inboxes via standard protocols for backward compatibility.
- **Labels** — Tag messages and threads with custom labels for state tracking and filtering.
- **Lists** — Allowlists and blocklists to control who agents can send to or receive from.

## Pricing

- **Free:** $0/month — 3 inboxes, 3,000 emails/month, 3 GB storage. No credit card required.
- **Developer:** $20/month — 10 inboxes, 10,000 emails/month, 10 GB storage, 10 custom domains, email support.
- **Startup:** $200/month — 150 inboxes, 150,000 emails/month, 150 GB storage, 150 custom domains, dedicated IPs, SOC 2 report, Slack channel support.
- **Enterprise:** Custom pricing — bulk discounts, white-label platform, usage-based pricing, EU region cloud, BYO cloud deployment, OIDC/SAML SSO.

Rate limits are very generous and built for agent throughput. If you exceed limits, the API returns 429 with a Retry-After header. See docs for details.

## Error Handling

All errors return JSON with `name` and `message` fields:

- **400** — Validation error. Check request parameters.
- **403** — Forbidden. Common causes: incorrect API key, accessing a resource you don't own, sending to a suppressed address.
- **404** — Resource not found. Check that IDs are correct.
- **429** — Rate limited. Respect the `Retry-After` header and implement exponential backoff.

Idempotency: Pass `client_id` (Python) / `clientId` (TypeScript) to all create operations (inboxes, pods, webhooks, drafts) to safely retry without duplicates.

## Common Patterns

- **Support Agent** — Create inbox, webhook on message.received, extract content with extracted_text, generate reply with LLM, track state with labels.
- **2FA/Auth Agent** — Create inbox per session, sign up for services, listen for verification emails, extract OTP codes.
- **Sales Outreach** — Send personalized emails, listen for replies, classify responses, follow up or escalate.
- **Document Processing** — Receive emails with attachments, download and process documents, send results back.

## MCP Server

Connect AgentMail to any MCP-compatible AI client (Claude Desktop, Cursor, Windsurf, etc.).
Install: `npx @smithery/cli@latest mcp add agentmail`

## SDKs

- **Python:** `pip install agentmail` — https://github.com/agentmail-to/agentmail-python
- **TypeScript/Node:** `npm install agentmail` — https://github.com/agentmail-to/agentmail-node

## Documentation

- [Full API documentation](https://docs.agentmail.to)
- [Full documentation for LLMs](https://docs.agentmail.to/llms-full.txt)

## Security & Compliance

- SOC 2 Type II certified
- HIPAA compliant with BAA available on enterprise
- Encryption at rest and in transit
- Trust center: https://trust.delve.co/agentmail

## Links

- Website: https://agentmail.to
- Console: https://console.agentmail.to
- GitHub: https://github.com/agentmail-to
- Skills: https://github.com/agentmail-to/agentmail-skills
- MCP Server: https://mcp.agentmail.to
- Discord: https://discord.gg/ZYN7f7KPjS
- Twitter/X: https://x.com/agentmail

---

# Full API Reference

Base URL: `https://api.agentmail.to/v0/`

Authentication: Pass your API key in the Authorization header as `Bearer am_...`

All `inbox_id` values are email addresses (e.g., `user@agentmail.to`). All `message_id` values are RFC 822 message IDs wrapped in angle brackets. All other IDs are UUIDs.


## ApiKeys

### GET /v0/api-keys
**List API Keys**

Query parameters:
- `limit`: 
- `page_token`: 

Returns: ListApiKeysResponse

### POST /v0/api-keys
**Create API Key**

Request body:
- `name` (required) (string): Name of api key.

Returns: CreateApiKeyResponse

### DELETE /v0/api-keys/{api_key}
**Delete API Key**

Path parameters:
- `api_key` (required): 



## Domains

### GET /v0/domains
**List Domains**

Query parameters:
- `limit`: 
- `page_token`: 

Returns: ListDomainsResponse

### POST /v0/domains
**Create Domain**

Request body:
- `domain` (required) (string): The name of the domain. (e.g., "example.com")
- `feedback_enabled` (required) (boolean): Bounce and complaint notifications are sent to your inboxes.

Returns: Domain

### GET /v0/domains/{domain_id}
**Get Domain**

Path parameters:
- `domain_id` (required): 

Returns: Domain

### DELETE /v0/domains/{domain_id}
**Delete Domain**

Path parameters:
- `domain_id` (required): 


### POST /v0/domains/{domain_id}/verify
**Verify Domain**

Path parameters:
- `domain_id` (required): 


### GET /v0/domains/{domain_id}/zone-file
**Get Zone File**

Path parameters:
- `domain_id` (required): 



## Drafts

### GET /v0/drafts
**List Drafts**

Query parameters:
- `limit`: 
- `page_token`: 
- `labels`: 
- `before`: 
- `after`: 
- `ascending`: 

Returns: ListDraftsResponse

### GET /v0/drafts/{draft_id}
**Get Draft**

Path parameters:
- `draft_id` (required): 

Returns: Draft


## Inboxes

### GET /v0/inboxes
**List Inboxes**

Query parameters:
- `limit`: 
- `page_token`: 

Returns: inboxesListInboxesResponse

### POST /v0/inboxes
**Create Inbox**

Request body:
- `username` (string): Username of address. Randomly generated if not specified.
- `domain` (string): Domain of address. Must be verified domain. Defaults to `agentmail.to`.
- `display_name` (string): Display name: `Display Name <username@domain.com>`.
- `client_id` (string): Client ID of inbox.

Returns: inboxesInbox

### GET /v0/inboxes/{inbox_id}
**Get Inbox**

Path parameters:
- `inbox_id` (required): 

Returns: inboxesInbox

### PATCH /v0/inboxes/{inbox_id}
**Update Inbox**

Path parameters:
- `inbox_id` (required): 

Request body:
- `display_name` (required) (string): Display name: `Display Name <username@domain.com>`.

Returns: inboxesInbox

### DELETE /v0/inboxes/{inbox_id}
**Delete Inbox**

Path parameters:
- `inbox_id` (required): 



## InboxesDrafts

### GET /v0/inboxes/{inbox_id}/drafts
**List Drafts**

Path parameters:
- `inbox_id` (required): 

Query parameters:
- `limit`: 
- `page_token`: 
- `labels`: 
- `before`: 
- `after`: 
- `ascending`: 

Returns: ListDraftsResponse

### POST /v0/inboxes/{inbox_id}/drafts
**Create Draft**

Path parameters:
- `inbox_id` (required): 

Request body:
- `labels` (array): Labels of draft.
- `reply_to` (array): Reply-to addresses. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `to` (array): Addresses of recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `cc` (array): Addresses of CC recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `bcc` (array): Addresses of BCC recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `subject` (string): Subject of draft.
- `text` (string): Plain text body of draft.
- `html` (string): HTML body of draft.
- `in_reply_to` (string): ID of message being replied to.
- `send_at` (string): Time at which to schedule send draft.
- `client_id` (string): Client ID of draft.

Returns: Draft

### GET /v0/inboxes/{inbox_id}/drafts/{draft_id}
**Get Draft**

Path parameters:
- `inbox_id` (required): 
- `draft_id` (required): 

Returns: Draft

### PATCH /v0/inboxes/{inbox_id}/drafts/{draft_id}
**Update Draft**

Path parameters:
- `inbox_id` (required): 
- `draft_id` (required): 

Request body:
- `reply_to` (array): Reply-to addresses. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `to` (array): Addresses of recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `cc` (array): Addresses of CC recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `bcc` (array): Addresses of BCC recipients. In format `username@domain.com` or `Display Name <username@domain.com>`.
- `subject` (string): Subject of draft.
- `text` (string): Plain text body of draft.
- `html` (string): HTML body of draft.
- `send_at` (string): Time at which to schedule send draft.

Returns: Draft

### DELETE /v0/inboxes/{inbox_id}/drafts/{draft_id}
**Delete Draft**

Path parameters:
- `inbox_id` (required): 
- `draft_id` (required): 


### POST /v0/inboxes/{inbox_id}/drafts/{draft_id}/send
**Send Draft**

Path parameters:
- `inbox_id` (required): 
- `draft_id` (required): 

Request body:
- `add_labels` (array of string): Labels to add to message.
- `remove_labels` (array of string): Labels to remove from message.

Returns: SendMessageResponse


## InboxesMessages

### GET /v0/inboxes/{inbox_id}/messages
**List Messages**

Path parameters:
- `inbox_id` (required): 

Query parameters:
- `limit`: 
- `page_token`: 
- `labels`: 
- `before`: 
- `after`: 
- `ascending`: 
- `include_spam`: 

Returns: ListMessagesResponse

### POST /v0/inboxes/{inbox_id}/messages/send
**Send Message**

Path parameters:
- `inbox_id` (required): 

Request body:
- `labels` (array): Labels of message.
- `reply_to` (SendMessageReplyTo): Reply-to address or addresses.
- `to` (SendMessageTo): Recipient address or addresses.
- `cc` (SendMessageCc): CC recipient address or addresses.
- `bcc` (SendMessageBcc): BCC recipient address or addresses.
- `subject` (string): Subject of message.
- `text` (string): Plain text body of message.
- `html` (string): HTML body of message.
- `attachments` (array): Attachments to include in message.
- `headers` (object): Headers to include in message.

Returns: SendMessageResponse

### GET /v0/inboxes/{inbox_id}/messages/{message_id}
**Get Message**

Path parameters:
- `inbox_id` (required): 
- `message_id` (required): 

Returns: Message

### PATCH /v0/inboxes/{inbox_id}/messages/{message_id}
**Update Message**

Path parameters:
- `inbox_id` (required): 
- `message_id` (required): 

Request body:
- `add_labels` (array of string): Labels to add to message.
- `remove_labels` (array of string): Labels to remove from message.

Returns: Message

### GET /v0/inboxes/{inbox_id}/messages/{message_id}/attachments/{attachment_id}
**Get Attachment**

Path parameters:
- `inbox_id` (required): 
- `message_id` (required): 
- `attachment_id` (required): 

Returns: AttachmentResponse

### POST /v0/inboxes/{inbox_id}/messages/{message_id}/forward
**Forward Message**

Path parameters:
- `inbox_id` (required): 
- `message_id` (required): 

Request body:
- `labels` (array): Labels of message.
- `reply_to` (SendMessageReplyTo): Reply-to address or addresses.
- `to` (SendMessageTo): Recipient address or addresses.
- `cc` (SendMessageCc): CC recipient address or addresses.
- `bcc` (SendMessageBcc): BCC recipient address or addresses.
- `subject` (string): Subject of message.
- `text` (string): Plain text body of message.
- `html` (string): HTML body of message.
- `attachments` (array): Attachments to include in message.
- `headers` (object): Headers to include in message.

Returns: SendMessageResponse

### GET /v0/inboxes/{inbox_id}/messages/{message_id}/raw
**Get Raw Message**

Path parameters:
- `inbox_id` (required): 
- `message_id` (required): 

Returns: RawMessageResponse

### POST /v0/inboxes/{inbox_id}/messages/{message_id}/reply
**Reply To Message**

Path parameters:
- `inbox_id` (required): 
- `message_id` (required): 

Request body:
- `labels` (array): Labels of message.
- `reply_to` (SendMessageReplyTo): Reply-to address or addresses.
- `to` (SendMessageTo): Recipient address or addresses.
- `cc` (SendMessageCc): CC recipient address or addresses.
- `bcc` (SendMessageBcc): BCC recipient address or addresses.
- `reply_all` (boolean): Reply to all recipients of the original message.
- `text` (string): Plain text body of message.
- `html` (string): HTML body of message.
- `attachments` (array): Attachments to include in message.
- `headers` (object): Headers to include in message.

Returns: SendMessageResponse

### POST /v0/inboxes/{inbox_id}/messages/{message_id}/reply-all
**Reply All Message**

Path parameters:
- `inbox_id` (required): 
- `message_id` (required): 

Request body:
- `labels` (array): Labels of message.
- `reply_to` (SendMessageReplyTo): Reply-to address or addresses.
- `text` (string): Plain text body of message.
- `html` (string): HTML body of message.
- `attachments` (array): Attachments to include in message.
- `headers` (object): Headers to include in message.

Returns: SendMessageResponse


## InboxesMetrics

### GET /v0/inboxes/{inbox_id}/metrics
**List Metrics**

Path parameters:
- `inbox_id` (required): 

Query parameters:
- `event_types`: 
- `start_timestamp` (required): 
- `end_timestamp` (required): 

Returns: ListMetricsResponse


## InboxesThreads

### GET /v0/inboxes/{inbox_id}/threads
**List Threads**

Path parameters:
- `inbox_id` (required): 

Query parameters:
- `limit`: 
- `page_token`: 
- `labels`: 
- `before`: 
- `after`: 
- `ascending`: 
- `include_spam`: 

Returns: ListThreadsResponse

### GET /v0/inboxes/{inbox_id}/threads/{thread_id}
**Get Thread**

Path parameters:
- `inbox_id` (required): 
- `thread_id` (required): 

Returns: Thread

### DELETE /v0/inboxes/{inbox_id}/threads/{thread_id}
**Delete Thread**

Path parameters:
- `inbox_id` (required): 
- `thread_id` (required): 


### GET /v0/inboxes/{inbox_id}/threads/{thread_id}/attachments/{attachment_id}
**Get Attachment**

Path parameters:
- `inbox_id` (required): 
- `thread_id` (required): 
- `attachment_id` (required): 

Returns: AttachmentResponse


## Metrics

### GET /v0/metrics
**List Metrics**

Query parameters:
- `event_types`: 
- `start_timestamp` (required): 
- `end_timestamp` (required): 

Returns: ListMetricsResponse


## Organizations

### GET /v0/organizations
**Get Organization**
Get the current organization.

Returns: Organization


## Pods

### GET /v0/pods
**List Pods**

Query parameters:
- `limit`: 
- `page_token`: 

Returns: podsListPodsResponse

### POST /v0/pods
**Create Pod**

Request body:
- `name` (string): Name of pod.
- `client_id` (string): Client ID of pod.

Returns: podsPod

### GET /v0/pods/{pod_id}
**Get Pod**

Path parameters:
- `pod_id` (required): 

Returns: podsPod

### DELETE /v0/pods/{pod_id}
**Delete Pod**

Path parameters:
- `pod_id` (required): 



## PodsDomains

### GET /v0/pods/{pod_id}/domains
**List Domains**

Path parameters:
- `pod_id` (required): 

Query parameters:
- `limit`: 
- `page_token`: 

Returns: ListDomainsResponse

### POST /v0/pods/{pod_id}/domains
**Create Domain**

Path parameters:
- `pod_id` (required): 

Request body:
- `domain` (required) (string): The name of the domain. (e.g., "example.com")
- `feedback_enabled` (required) (boolean): Bounce and complaint notifications are sent to your inboxes.

Returns: Domain

### DELETE /v0/pods/{pod_id}/domains/{domain_id}
**Delete Domain**

Path parameters:
- `pod_id` (required): 
- `domain_id` (required): 



## PodsDrafts

### GET /v0/pods/{pod_id}/drafts
**List Drafts**

Path parameters:
- `pod_id` (required): 

Query parameters:
- `limit`: 
- `page_token`: 
- `labels`: 
- `before`: 
- `after`: 
- `ascending`: 

Returns: ListDraftsResponse

### GET /v0/pods/{pod_id}/drafts/{draft_id}
**Get Draft**

Path parameters:
- `pod_id` (required): 
- `draft_id` (required): 

Returns: Draft


## PodsInboxes

### GET /v0/pods/{pod_id}/inboxes
**List Inboxes**

Path parameters:
- `pod_id` (required): 

Query parameters:
- `limit`: 
- `page_token`: 

Returns: inboxesListInboxesResponse

### POST /v0/pods/{pod_id}/inboxes
**Create Inbox**

Path parameters:
- `pod_id` (required): 

Request body:
- `username` (string): Username of address. Randomly generated if not specified.
- `domain` (string): Domain of address. Must be verified domain. Defaults to `agentmail.to`.
- `display_name` (string): Display name: `Display Name <username@domain.com>`.
- `client_id` (string): Client ID of inbox.

Returns: inboxesInbox

### GET /v0/pods/{pod_id}/inboxes/{inbox_id}
**Get Inbox**

Path parameters:
- `pod_id` (required): 
- `inbox_id` (required): 

Returns: inboxesInbox

### DELETE /v0/pods/{pod_id}/inboxes/{inbox_id}
**Delete Inbox**

Path parameters:
- `pod_id` (required): 
- `inbox_id` (required): 



## PodsThreads

### GET /v0/pods/{pod_id}/threads
**List Threads**

Path parameters:
- `pod_id` (required): 

Query parameters:
- `limit`: 
- `page_token`: 
- `labels`: 
- `before`: 
- `after`: 
- `ascending`: 
- `include_spam`: 

Returns: ListThreadsResponse

### GET /v0/pods/{pod_id}/threads/{thread_id}
**Get Thread**

Path parameters:
- `pod_id` (required): 
- `thread_id` (required): 

Returns: Thread

### GET /v0/pods/{pod_id}/threads/{thread_id}/attachments/{attachment_id}
**Get Attachment**

Path parameters:
- `pod_id` (required): 
- `thread_id` (required): 
- `attachment_id` (required): 

Returns: AttachmentResponse


## Threads

### GET /v0/threads
**List Threads**

Query parameters:
- `limit`: 
- `page_token`: 
- `labels`: 
- `before`: 
- `after`: 
- `ascending`: 
- `include_spam`: 

Returns: ListThreadsResponse

### GET /v0/threads/{thread_id}
**Get Thread**

Path parameters:
- `thread_id` (required): 

Returns: Thread

### GET /v0/threads/{thread_id}/attachments/{attachment_id}
**Get Attachment**

Path parameters:
- `thread_id` (required): 
- `attachment_id` (required): 

Returns: AttachmentResponse


## Webhooks

### GET /v0/webhooks
**List Webhooks**

Query parameters:
- `limit`: 
- `page_token`: 

Returns: webhooksListWebhooksResponse

### POST /v0/webhooks
**Create Webhook**

Request body:
- `url` (required) (string): URL of webhook endpoint.
- `event_types` (required) (array): Event types for which to send events.
- `pod_ids` (array): Pods for which to send events. Maximum 10 per webhook.
- `inbox_ids` (array): Inboxes for which to send events. Maximum 10 per webhook.
- `client_id` (string): Client ID of webhook.

Returns: webhooksWebhook

### GET /v0/webhooks/{webhook_id}
**Get Webhook**

Path parameters:
- `webhook_id` (required): 

Returns: webhooksWebhook

### PATCH /v0/webhooks/{webhook_id}
**Update Webhook**

Path parameters:
- `webhook_id` (required): 

Request body:
- `add_inbox_ids` (array): Inbox IDs to subscribe to the webhook.
- `remove_inbox_ids` (array): Inbox IDs to unsubscribe from the webhook.
- `add_pod_ids` (array): Pod IDs to subscribe to the webhook.
- `remove_pod_ids` (array): Pod IDs to unsubscribe from the webhook.

Returns: webhooksWebhook

### DELETE /v0/webhooks/{webhook_id}
**Delete Webhook**

Path parameters:
- `webhook_id` (required): 


---

# Webhook Events

Subscribe to webhook events to receive real-time notifications about email activity.

## Creating a Webhook

```python
webhook = client.webhooks.create(
    url="https://your-domain.com/webhooks",
    events=["message.received", "message.sent", "message.bounced"],
    client_id="my-webhook-v1"  # idempotent
)
```

```typescript
const webhook = await client.webhooks.create({
  url: "https://your-domain.com/webhooks",
  events: ["message.received", "message.sent", "message.bounced"],
  clientId: "my-webhook-v1",
});
```

## Event Types

- **message.received** — An email was received by an inbox.
- **message.sent** — An email was sent from an inbox.
- **message.delivered** — A sent email was successfully delivered to the recipient's mail server.
- **message.bounced** — A sent email bounced. Includes bounce type (Permanent or Transient) and affected recipients.
- **message.complained** — A recipient marked an email as spam.
- **message.rejected** — An email was rejected before delivery.
- **domain.verified** — A custom domain's DNS records were verified successfully.

## Webhook Payload Structure

All webhook payloads include:
- `event_type` — The event type string (e.g., "message.received")
- `timestamp` — ISO 8601 timestamp
- Event-specific data (message object, bounce details, etc.)

## Webhook Verification

Webhooks include an HMAC signature for verification. Verify the signature to ensure the webhook was sent by AgentMail and not spoofed.

---

# WebSockets

Real-time email event streaming without webhooks or polling. Sub-second latency. Works behind firewalls and NATs.

## Connecting

```python
from agentmail import AgentMail

client = AgentMail(api_key="am_...")

# Connect to WebSocket for real-time events
ws = client.websockets.connect()
for event in ws:
    if event.event_type == "message.received":
        print(f"New email: {event.message.subject}")
```

```typescript
import { AgentMailClient } from "agentmail";

const client = new AgentMailClient({ apiKey: "am_..." });

const ws = client.websockets.connect();
ws.on("message.received", (event) => {
  console.log(`New email: ${event.message.subject}`);
});
```

---

# Detailed Code Examples

## Support Agent Pattern

Create an inbox, listen for incoming emails via webhook, and auto-reply using an LLM.

```python
from agentmail import AgentMail

client = AgentMail(api_key="am_...")

# Create a support inbox
inbox = client.inboxes.create(
    username="support",
    display_name="Support Agent",
    client_id="support-inbox-v1"
)

# Create webhook for incoming emails
client.webhooks.create(
    url="https://your-app.com/webhooks",
    events=["message.received"],
    client_id="support-webhook-v1"
)

# In your webhook handler:
def handle_webhook(payload):
    if payload["event_type"] == "message.received":
        message = payload["message"]
        
        # Get the new content only (strips quoted text)
        new_content = message.get("extracted_text") or message.get("text", "")
        
        # Generate reply with your LLM
        reply_text = generate_reply(new_content)
        
        # Reply in-thread
        client.inboxes.messages.reply(
            inbox.inbox_id,
            message["message_id"],
            text=reply_text
        )
        
        # Track state with labels
        client.inboxes.messages.update(
            inbox.inbox_id,
            message["message_id"],
            add_labels=["replied"],
            remove_labels=["unreplied"]
        )
```

## 2FA/Auth Agent Pattern

Create a temporary inbox to receive verification emails and extract codes.

```python
from agentmail import AgentMail
import time

client = AgentMail(api_key="am_...")

# Create a temporary inbox for this auth session
inbox = client.inboxes.create(client_id=f"auth-session-{session_id}")

# Sign up for a service using inbox.inbox_id as the email
register_for_service(email=inbox.inbox_id)

# Poll for verification email (or use WebSocket for real-time)
for _ in range(30):  # wait up to 60 seconds
    messages = client.inboxes.messages.list(inbox.inbox_id, limit=1)
    if messages.messages:
        msg = messages.messages[0]
        otp_code = extract_otp(msg.extracted_text or msg.text)
        if otp_code:
            verify_with_service(otp_code)
            break
    time.sleep(2)

# Clean up
client.inboxes.delete(inbox.inbox_id)
```

## Sales Outreach Agent Pattern

Send personalized emails and handle replies with classification.

```typescript
import { AgentMailClient } from "agentmail";

const client = new AgentMailClient({ apiKey: "am_..." });

// Create outreach inbox
const inbox = await client.inboxes.create({
  username: "sales",
  domain: "yourdomain.com",
  displayName: "Alex from YourCompany",
  clientId: "sales-outreach-v1",
});

// Send personalized email
await client.inboxes.messages.send(inbox.inboxId, {
  to: "prospect@example.com",
  subject: "Quick question about your workflow",
  text: "Hi — I noticed you're building AI agents...",
  html: "<p>Hi — I noticed you're building AI agents...</p>",
});

// Handle replies via webhook
async function handleReply(payload: any) {
  if (payload.event_type === "message.received") {
    const content = payload.message.extracted_text || payload.message.text;
    
    // Classify response
    const classification = await classifyResponse(content);
    
    // Label for tracking
    await client.inboxes.messages.update(inbox.inboxId, payload.message.message_id, {
      addLabels: [classification], // "interested", "not-interested", "question", etc.
    });
    
    if (classification === "interested") {
      // Send follow-up
      await client.inboxes.messages.reply(inbox.inboxId, payload.message.message_id, {
        text: "Great to hear! Let me set up a time to chat...",
      });
    }
  }
}
```

## Document Processing Agent Pattern

Receive emails with attachments, process them, and reply with results.

```python
from agentmail import AgentMail

client = AgentMail(api_key="am_...")

inbox = client.inboxes.create(
    username="documents",
    display_name="Document Processor",
    client_id="doc-processor-v1"
)

def handle_document_email(payload):
    if payload["event_type"] == "message.received":
        message = payload["message"]
        
        # Download attachments
        for attachment in message.get("attachments", []):
            file_data = client.inboxes.messages.get_attachment(
                inbox.inbox_id,
                message["message_id"],
                attachment["attachment_id"]
            )
            
            # Process the document
            result = process_document(file_data, attachment["filename"])
            
            # Reply with results
            client.inboxes.messages.reply(
                inbox.inbox_id,
                message["message_id"],
                text=f"Processed {attachment['filename']}:\n\n{result}"
            )
```

## Human-in-the-Loop with Drafts

Create drafts for review before sending.

```typescript
import { AgentMailClient } from "agentmail";

const client = new AgentMailClient({ apiKey: "am_..." });

// Agent creates a draft for human review
const draft = await client.inboxes.drafts.create(inboxId, {
  to: ["important-client@example.com"],
  subject: "Proposal follow-up",
  text: "AI-generated response here...",
  html: "<p>AI-generated response here...</p>",
  clientId: "draft-proposal-followup-v1",
});

// Human reviews in console or via API
// When approved:
await client.inboxes.drafts.send(inboxId, draft.draftId);
```

## Multi-Tenant with Pods

Isolate inboxes across tenants using Pods.

```python
from agentmail import AgentMail

client = AgentMail(api_key="am_...")

# Create a pod for each tenant
pod = client.pods.create(client_id=f"tenant-{tenant_id}")

# Create inboxes within the pod
inbox = client.pods.inboxes.create(
    pod.pod_id,
    username="support"
)

# Inboxes in different pods are fully isolated
```

---

# Preventing Duplicate Sends

AI agents can retry requests due to network errors or logic bugs. Use these patterns to prevent duplicate emails:

1. **Use `client_id` on all create operations** (inboxes, pods, webhooks, drafts) — same client_id returns existing resource instead of creating a duplicate.
2. **Track state with labels** — mark messages as "replied" after processing to prevent re-processing.
3. **Use drafts for critical sends** — drafts support client_id for idempotent creation, and are deleted after sending (so send can only succeed once).

---

# Idempotency

Pass `client_id` (Python) / `clientId` (TypeScript) to any create operation. If a resource with that client_id already exists, the API returns the existing resource with a 200 instead of creating a duplicate. This makes all create operations safe to retry.

Supported on: inboxes.create, pods.create, webhooks.create, drafts.create.

Best practice: generate client_id from your business logic (e.g., `inbox-for-user-{USER_ID}`) so the same logical resource always produces the same client_id.

---

# Integrations

## MCP Server
Connect AgentMail to Claude Desktop, Cursor, Windsurf, or any MCP-compatible client.
Install: `npx @smithery/cli@latest mcp add agentmail`
Source: https://mcp.agentmail.to

## Skills (OpenClaw, Claude Code, Cursor)
Pre-built AgentMail skill for AI coding assistants.
Source: https://github.com/agentmail-to/agentmail-skills

## Google ADK
AgentMail integration for Google Agent Development Kit.
Docs: https://docs.agentmail.to/integrations/google-adk

## CLI
Command-line interface for AgentMail.
Docs: https://docs.agentmail.to/integrations/cli
~~~