API Reference

Complete reference for the agentmail REST API. All endpoints are relative to /api/v0.

Authentication

All requests require a Bearer token in the Authorization header:

Authorization: Bearer inai_xxxx...

Pagination

List endpoints accept page (default 1) and page_size (default 20, max 100) query parameters. Responses include total, page, and page_size fields.

Organizations

GET/api/v0/organizations

Get the current organization's details including usage counts and limits.

Response

{
  "org_id": "org_abc",
  "name": "My Org",
  "inbox_count": 5,
  "inbox_limit": 50,
  "domain_count": 2,
  "domain_limit": 10,
  "created_at": "2025-01-01T00:00:00.000Z",
  "updated_at": "2025-01-10T00:00:00.000Z"
}

Example

curl https://your-instance.com/api/v0/organizations \
  -H "Authorization: Bearer <API_KEY>"

Inboxes

POST/api/v0/inboxes

Create a new inbox. Provisions a real mailbox on the underlying mail server.

Request Body

{
  "username": "agent-1",          // required, a-zA-Z0-9._%+-
  "domain": "yourdomain.com",     // optional, defaults to platform domain
  "display_name": "Agent One",    // optional
  "client_id": "my-agent"         // optional, for your own tracking
}

Response

{
  "inbox_id": "nk8x2j...",
  "email_address": "agent-1@yourdomain.com",
  "username": "agent-1",
  "domain": "yourdomain.com",
  "display_name": "Agent One",
  "client_id": "my-agent",
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T10:30:00.000Z"
}

Example

curl -X POST https://your-instance.com/api/v0/inboxes \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"username": "agent-1", "display_name": "Agent One"}'
GET/api/v0/inboxes

List all inboxes in the organization. Supports pagination.

Response

{
  "data": [
    {
      "inbox_id": "nk8x2j...",
      "email_address": "agent-1@yourdomain.com",
      "username": "agent-1",
      "domain": "yourdomain.com",
      "display_name": "Agent One",
      "client_id": null,
      "created_at": "2025-01-15T10:30:00.000Z",
      "updated_at": "2025-01-15T10:30:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20
}

Example

curl https://your-instance.com/api/v0/inboxes \
  -H "Authorization: Bearer <API_KEY>"
GET/api/v0/inboxes/:inboxId

Get a single inbox by ID.

Response

{
  "inbox_id": "nk8x2j...",
  "email_address": "agent-1@yourdomain.com",
  "username": "agent-1",
  "domain": "yourdomain.com",
  "display_name": "Agent One",
  "client_id": null,
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T10:30:00.000Z"
}

Example

curl https://your-instance.com/api/v0/inboxes/nk8x2j... \
  -H "Authorization: Bearer <API_KEY>"
PATCH/api/v0/inboxes/:inboxId

Update an inbox's display name.

Request Body

{
  "display_name": "Updated Name"   // optional
}

Response

{
  "inbox_id": "nk8x2j...",
  "email_address": "agent-1@yourdomain.com",
  "username": "agent-1",
  "domain": "yourdomain.com",
  "display_name": "Updated Name",
  "client_id": null,
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T12:00:00.000Z"
}

Example

curl -X PATCH https://your-instance.com/api/v0/inboxes/nk8x2j... \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"display_name": "Updated Name"}'
DELETE/api/v0/inboxes/:inboxId

Delete an inbox and its mailbox from the mail server. Returns 204 No Content.

Example

curl -X DELETE https://your-instance.com/api/v0/inboxes/nk8x2j... \
  -H "Authorization: Bearer <API_KEY>"

Messages

POST/api/v0/inboxes/:inboxId/messages/send

Send a new email from the inbox. Supports text, HTML, attachments, CC, BCC, and custom headers.

Request Body

{
  "to": "recipient@example.com",              // required, string or string[]
  "cc": "cc@example.com",                     // optional, string or string[]
  "bcc": "bcc@example.com",                   // optional, string or string[]
  "reply_to": "reply@example.com",            // optional, string or string[]
  "subject": "Hello",                         // optional
  "text": "Plain text body",                  // optional
  "html": "<h1>HTML body</h1>",               // optional
  "labels": ["important"],                    // optional
  "attachments": [                            // optional
    {
      "filename": "doc.pdf",
      "content_type": "application/pdf",
      "content": "<base64>",                  // base64-encoded content
      "url": "https://..."                    // or a URL to fetch
    }
  ],
  "headers": {                                // optional custom headers
    "X-Custom": "value"
  }
}

Response

{
  "message_id": "msg_abc123",
  "thread_id": "thr_xyz789"
}

Example

curl -X POST https://your-instance.com/api/v0/inboxes/nk8x2j.../messages/send \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "recipient@example.com",
    "subject": "Hello from agentmail",
    "text": "This is a test email."
  }'
GET/api/v0/inboxes/:inboxId/messages

List all messages in an inbox. Supports pagination. Returns both sent and received messages ordered by timestamp descending.

Response

{
  "data": [
    {
      "inbox_id": "nk8x2j...",
      "thread_id": "thr_xyz789",
      "message_id": "msg_abc123",
      "direction": "outbound",
      "labels": [],
      "timestamp": "2025-01-15T10:32:00.000Z",
      "from": "Agent One <agent-1@yourdomain.com>",
      "to": ["recipient@example.com"],
      "cc": null,
      "subject": "Hello from agentmail",
      "preview": "This is a test email.",
      "size": 156
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20
}

Example

curl https://your-instance.com/api/v0/inboxes/nk8x2j.../messages \
  -H "Authorization: Bearer <API_KEY>"
GET/api/v0/inboxes/:inboxId/messages/:messageId

Get a single message by ID with full content (text, HTML, headers, references).

Response

{
  "inbox_id": "nk8x2j...",
  "thread_id": "thr_xyz789",
  "message_id": "msg_abc123",
  "direction": "outbound",
  "labels": [],
  "timestamp": "2025-01-15T10:32:00.000Z",
  "from": "Agent One <agent-1@yourdomain.com>",
  "reply_to": null,
  "to": ["recipient@example.com"],
  "cc": null,
  "bcc": null,
  "subject": "Hello from agentmail",
  "preview": "This is a test email.",
  "text": "This is a test email.",
  "html": null,
  "in_reply_to": null,
  "references": null,
  "headers": {},
  "size": 156,
  "created_at": "2025-01-15T10:32:00.000Z",
  "updated_at": "2025-01-15T10:32:00.000Z"
}

Example

curl https://your-instance.com/api/v0/inboxes/nk8x2j.../messages/msg_abc123 \
  -H "Authorization: Bearer <API_KEY>"
PATCH/api/v0/inboxes/:inboxId/messages/:messageId

Update a message's labels.

Request Body

{
  "labels": ["important", "follow-up"]   // required
}

Response

{
  "message_id": "msg_abc123",
  "labels": ["important", "follow-up"],
  "..."
}

Example

curl -X PATCH https://your-instance.com/api/v0/inboxes/nk8x2j.../messages/msg_abc123 \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"labels": ["important", "follow-up"]}'
POST/api/v0/inboxes/:inboxId/messages/:messageId/reply

Reply to a message. Sends to the original sender only (or the Reply-To address if set). Automatically sets In-Reply-To and References headers for threading.

Request Body

{
  "text": "Thanks for your email!",     // optional
  "html": "<p>Thanks!</p>",            // optional
  "cc": "cc@example.com",              // optional, string or string[]
  "labels": ["replied"],               // optional
  "attachments": [                     // optional
    {
      "filename": "doc.pdf",
      "content_type": "application/pdf",
      "content": "<base64>"
    }
  ]
}

Response

{
  "message_id": "msg_reply123",
  "thread_id": "thr_xyz789"
}

Example

curl -X POST https://your-instance.com/api/v0/inboxes/nk8x2j.../messages/msg_abc123/reply \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"text": "Thanks for your email!"}'
POST/api/v0/inboxes/:inboxId/messages/:messageId/reply-all

Reply to all recipients of a message. Sends to the original sender + all To and CC recipients, excluding the inbox's own address. Automatically sets In-Reply-To and References headers for threading.

Request Body

{
  "text": "Thanks, everyone!",          // optional
  "html": "<p>Thanks, everyone!</p>",   // optional
  "cc": "extra-cc@example.com",         // optional, additional CC recipients
  "labels": ["replied"],                // optional
  "attachments": [                      // optional
    {
      "filename": "doc.pdf",
      "content_type": "application/pdf",
      "content": "<base64>"
    }
  ]
}

Response

{
  "message_id": "msg_replyall123",
  "thread_id": "thr_xyz789"
}

Example

curl -X POST https://your-instance.com/api/v0/inboxes/nk8x2j.../messages/msg_abc123/reply-all \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"text": "Thanks, everyone!"}'
POST/api/v0/inboxes/:inboxId/messages/:messageId/forward

Forward a message to new recipients. Creates a new thread. Includes the original message content if no override is provided.

Request Body

{
  "to": "forward@example.com",          // required, string or string[]
  "cc": "cc@example.com",              // optional
  "text": "FYI, see below.",           // optional override
  "html": "<p>FYI</p>",               // optional override
  "labels": ["forwarded"]              // optional
}

Response

{
  "message_id": "msg_fwd123",
  "thread_id": "thr_new456"
}

Example

curl -X POST https://your-instance.com/api/v0/inboxes/nk8x2j.../messages/msg_abc123/forward \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"to": "forward@example.com", "text": "FYI, see below."}'
GET/api/v0/inboxes/:inboxId/messages/:messageId/attachments/:attachmentId

Get attachment metadata and a pre-signed download URL. The download URL expires after a short period.

Response

{
  "attachment_id": "att_abc123",
  "filename": "document.pdf",
  "size": 245000,
  "content_type": "application/pdf",
  "content_disposition": "attachment",
  "content_id": null,
  "download_url": "https://storage.../presigned-url",
  "expires_at": "2025-01-15T11:30:00.000Z"
}

Example

curl https://your-instance.com/api/v0/inboxes/nk8x2j.../messages/msg_abc123/attachments/att_abc123 \
  -H "Authorization: Bearer <API_KEY>"

Threads

GET/api/v0/inboxes/:inboxId/threads

List all threads in an inbox. Supports pagination. Ordered by most recent activity.

Response

{
  "data": [
    {
      "inbox_id": "nk8x2j...",
      "thread_id": "thr_xyz789",
      "labels": [],
      "timestamp": "2025-01-15T10:32:00.000Z",
      "received_timestamp": "2025-01-15T10:30:00.000Z",
      "sent_timestamp": "2025-01-15T10:32:00.000Z",
      "senders": ["sender@example.com"],
      "recipients": ["agent-1@yourdomain.com"],
      "subject": "Hello",
      "preview": "This is a test...",
      "last_message_id": "msg_abc123",
      "message_count": 3,
      "size": 1200
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20
}

Example

curl https://your-instance.com/api/v0/inboxes/nk8x2j.../threads \
  -H "Authorization: Bearer <API_KEY>"
GET/api/v0/inboxes/:inboxId/threads/:threadId

Get a single thread with all its messages included, ordered chronologically.

Response

{
  "inbox_id": "nk8x2j...",
  "thread_id": "thr_xyz789",
  "subject": "Hello",
  "message_count": 2,
  "preview": "Thanks for your email!",
  "messages": [
    {
      "message_id": "msg_abc123",
      "direction": "inbound",
      "from": "sender@example.com",
      "to": ["agent-1@yourdomain.com"],
      "subject": "Hello",
      "text": "Hi there!",
      "timestamp": "2025-01-15T10:30:00.000Z"
    },
    {
      "message_id": "msg_reply123",
      "direction": "outbound",
      "from": "Agent One <agent-1@yourdomain.com>",
      "to": ["sender@example.com"],
      "subject": "Re: Hello",
      "text": "Thanks for your email!",
      "timestamp": "2025-01-15T10:32:00.000Z"
    }
  ]
}

Example

curl https://your-instance.com/api/v0/inboxes/nk8x2j.../threads/thr_xyz789 \
  -H "Authorization: Bearer <API_KEY>"
DELETE/api/v0/inboxes/:inboxId/threads/:threadId

Delete a thread and all its messages. Returns 204 No Content.

Example

curl -X DELETE https://your-instance.com/api/v0/inboxes/nk8x2j.../threads/thr_xyz789 \
  -H "Authorization: Bearer <API_KEY>"

Domains

POST/api/v0/domains

Add a custom domain. Returns the DNS records you need to configure at your DNS provider.

Request Body

{
  "domain": "yourdomain.com",           // required
  "feedback_enabled": true              // optional, default true
}

Response

{
  "domain_id": "yourdomain.com",
  "status": "PENDING",
  "feedback_enabled": true,
  "records": [
    {
      "type": "MX",
      "name": "yourdomain.com",
      "value": "mail.yourdomain.com",
      "status": "MISSING",
      "priority": 10
    },
    {
      "type": "TXT",
      "name": "yourdomain.com",
      "value": "v=spf1 include:_spf.yourdomain.com ~all",
      "status": "MISSING",
      "priority": null
    },
    {
      "type": "TXT",
      "name": "dkim._domainkey.yourdomain.com",
      "value": "v=DKIM1; k=rsa; p=...",
      "status": "MISSING",
      "priority": null
    },
    {
      "type": "TXT",
      "name": "_dmarc.yourdomain.com",
      "value": "v=DMARC1; p=none; rua=mailto:...",
      "status": "MISSING",
      "priority": null
    }
  ],
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T10:30:00.000Z"
}

Example

curl -X POST https://your-instance.com/api/v0/domains \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"domain": "yourdomain.com"}'
GET/api/v0/domains

List all domains in the organization with their DNS records and verification status.

Response

{
  "data": [
    {
      "domain_id": "yourdomain.com",
      "status": "VERIFIED",
      "feedback_enabled": true,
      "records": [...],
      "created_at": "2025-01-15T10:30:00.000Z",
      "updated_at": "2025-01-16T08:00:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20
}

Example

curl https://your-instance.com/api/v0/domains \
  -H "Authorization: Bearer <API_KEY>"
GET/api/v0/domains/:domainId

Get a single domain by ID with its DNS records.

Response

{
  "domain_id": "yourdomain.com",
  "status": "PENDING",
  "feedback_enabled": true,
  "records": [...],
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T10:30:00.000Z"
}

Example

curl https://your-instance.com/api/v0/domains/yourdomain.com \
  -H "Authorization: Bearer <API_KEY>"
DELETE/api/v0/domains/:domainId

Delete a domain. Removes it from the mail server. Returns 204 No Content.

Example

curl -X DELETE https://your-instance.com/api/v0/domains/yourdomain.com \
  -H "Authorization: Bearer <API_KEY>"
POST/api/v0/domains/:domainId/verify

Trigger DNS verification for a domain. Checks all required DNS records and updates their status. When all records are valid, the domain status changes to VERIFIED.

Response

{
  "domain_id": "yourdomain.com",
  "status": "VERIFIED",
  "feedback_enabled": true,
  "records": [
    {
      "type": "MX",
      "name": "yourdomain.com",
      "value": "mail.yourdomain.com",
      "status": "VALID",
      "priority": 10
    },
    {
      "type": "TXT",
      "name": "yourdomain.com",
      "value": "v=spf1 ...",
      "status": "VALID",
      "priority": null
    }
  ],
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-16T09:00:00.000Z"
}

Example

curl -X POST https://your-instance.com/api/v0/domains/yourdomain.com/verify \
  -H "Authorization: Bearer <API_KEY>"

Webhooks

Event Types

message.receivedmessage.sentmessage.deliveredmessage.bouncedmessage.complainedmessage.rejecteddomain.verified
POST/api/v0/webhooks

Create a new webhook subscription. Returns the webhook including its signing secret (shown only once).

Request Body

{
  "url": "https://your-app.com/webhooks/email",  // required
  "event_types": ["message.received"],            // required
  "inbox_ids": ["nk8x2j..."],                    // optional, filter by inbox
  "client_id": "my-integration"                   // optional
}

Response

{
  "webhook_id": "wh_abc123",
  "url": "https://your-app.com/webhooks/email",
  "event_types": ["message.received"],
  "inbox_ids": ["nk8x2j..."],
  "enabled": true,
  "client_id": "my-integration",
  "secret": "a1b2c3d4...",
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T10:30:00.000Z"
}

Example

curl -X POST https://your-instance.com/api/v0/webhooks \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/email",
    "event_types": ["message.received", "message.sent"]
  }'
GET/api/v0/webhooks

List all webhooks in the organization.

Response

{
  "data": [
    {
      "webhook_id": "wh_abc123",
      "url": "https://your-app.com/webhooks/email",
      "event_types": ["message.received"],
      "inbox_ids": [],
      "enabled": true,
      "client_id": null,
      "created_at": "2025-01-15T10:30:00.000Z",
      "updated_at": "2025-01-15T10:30:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20
}

Example

curl https://your-instance.com/api/v0/webhooks \
  -H "Authorization: Bearer <API_KEY>"
GET/api/v0/webhooks/:webhookId

Get a single webhook by ID.

Response

{
  "webhook_id": "wh_abc123",
  "url": "https://your-app.com/webhooks/email",
  "event_types": ["message.received"],
  "inbox_ids": [],
  "enabled": true,
  "client_id": null,
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T10:30:00.000Z"
}

Example

curl https://your-instance.com/api/v0/webhooks/wh_abc123 \
  -H "Authorization: Bearer <API_KEY>"
PATCH/api/v0/webhooks/:webhookId

Update a webhook's URL, event types, inbox filter, or enabled status.

Request Body

{
  "url": "https://new-url.com/hook",      // optional
  "event_types": ["message.received"],    // optional
  "inbox_ids": [],                        // optional
  "enabled": false                        // optional
}

Response

{
  "webhook_id": "wh_abc123",
  "url": "https://new-url.com/hook",
  "event_types": ["message.received"],
  "inbox_ids": [],
  "enabled": false,
  "client_id": null,
  "created_at": "2025-01-15T10:30:00.000Z",
  "updated_at": "2025-01-15T12:00:00.000Z"
}

Example

curl -X PATCH https://your-instance.com/api/v0/webhooks/wh_abc123 \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'
DELETE/api/v0/webhooks/:webhookId

Delete a webhook. Returns 204 No Content.

Example

curl -X DELETE https://your-instance.com/api/v0/webhooks/wh_abc123 \
  -H "Authorization: Bearer <API_KEY>"

API Keys

POST/api/v0/api-keys

Create a new API key. The full key is returned only in this response — store it securely.

Request Body

{
  "name": "my-agent-key"   // required
}

Response

{
  "key_id": "key_abc123",
  "name": "my-agent-key",
  "prefix": "inai_xxxx_...",
  "key": "inai_xxxx_full_key_here",
  "used_at": null,
  "created_at": "2025-01-15T10:30:00.000Z"
}

Example

curl -X POST https://your-instance.com/api/v0/api-keys \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-agent-key"}'
GET/api/v0/api-keys

List all API keys. Only the prefix is shown, never the full key.

Response

{
  "data": [
    {
      "key_id": "key_abc123",
      "name": "my-agent-key",
      "prefix": "inai_xxxx_...",
      "used_at": "2025-01-15T12:00:00.000Z",
      "created_at": "2025-01-15T10:30:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20
}

Example

curl https://your-instance.com/api/v0/api-keys \
  -H "Authorization: Bearer <API_KEY>"
DELETE/api/v0/api-keys/:keyId

Revoke and delete an API key. Returns 204 No Content.

Example

curl -X DELETE https://your-instance.com/api/v0/api-keys/key_abc123 \
  -H "Authorization: Bearer <API_KEY>"