---
title: "Inboxes"
description: "Create, list, search, read, update, pause and delete MachineMail inboxes, and check whether an address is available. The inbox_id is the email address."
canonical: "https://machinemail.dev/docs/reference/api/inboxes"
---

# Inboxes

> Create, list, search, read, update, pause and delete MachineMail inboxes, and check whether an address is available. The inbox_id is the email address.

Source: https://machinemail.dev/docs/reference/api/inboxes

| Method   | Path                                     | Summary                                                             |
| -------- | ---------------------------------------- | ------------------------------------------------------------------- |
| `GET`    | `/v0/inboxes`                            | [List Inboxes](#list-inboxes)                                       |
| `POST`   | `/v0/inboxes`                            | [Create Inbox](#create-inbox)                                       |
| `GET`    | `/v0/inboxes/availability`               | [Check Inbox Availability](#check-inbox-availability)               |
| `GET`    | `/v0/inboxes/search`                     | [Search Inboxes](#search-inboxes)                                   |
| `GET`    | `/v0/inboxes/{inbox_id}`                 | [Get Inbox](#get-inbox)                                             |
| `PATCH`  | `/v0/inboxes/{inbox_id}`                 | [Update Inbox](#update-inbox)                                       |
| `DELETE` | `/v0/inboxes/{inbox_id}`                 | [Delete Inbox](#delete-inbox)                                       |
| `GET`    | `/v0/pods/{pod_id}/inboxes`              | [List Inboxes in Pod](#list-inboxes-in-pod)                         |
| `POST`   | `/v0/pods/{pod_id}/inboxes`              | [Create Inbox in Pod](#create-inbox-in-pod)                         |
| `GET`    | `/v0/pods/{pod_id}/inboxes/availability` | [Check Inbox Availability in Pod](#check-inbox-availability-in-pod) |
| `GET`    | `/v0/pods/{pod_id}/inboxes/search`       | [Search Inboxes in Pod](#search-inboxes-in-pod)                     |
| `GET`    | `/v0/pods/{pod_id}/inboxes/{inbox_id}`   | [Get Inbox in Pod](#get-inbox-in-pod)                               |
| `PATCH`  | `/v0/pods/{pod_id}/inboxes/{inbox_id}`   | [Update Inbox in Pod](#update-inbox-in-pod)                         |
| `DELETE` | `/v0/pods/{pod_id}/inboxes/{inbox_id}`   | [Delete Inbox in Pod](#delete-inbox-in-pod)                         |

## List Inboxes

```http
GET /v0/inboxes
```

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Query parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `limit` | `integer` |  | Maximum number of items to return. Default 50, maximum 500; larger values are capped. |
| `page_token` | `string` |  | next_page_token from the previous page. |
| `ascending` | `boolean` |  | Sort oldest first. |
| `ephemeral` | `boolean` |  | Only ephemeral (true) or only permanent (false) inboxes. |

#### Response

**200** A page of inboxes (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `count` | `integer` | required | Number of items returned. |
| `limit` | `integer` |  | Maximum number of items per page. Default 50, maximum 500; larger values are capped. |
| `next_page_token` | `string` |  | Page token for pagination. Absent on the last page. |
| `inboxes` | `Inbox[]` | required | Ordered by created_at, newest first unless ascending is set. |

Each item of `inboxes` is a [Inbox](https://machinemail.dev/docs/reference/api/objects#inbox):

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/inboxes" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "inboxes": [
    {
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "inbox_id": "agent@machinemail.dev",
      "email": "agent@machinemail.dev",
      "display_name": "Support Agent",
      "client_id": "my-client-id",
      "status": "active",
      "metadata": {
        "key": "value"
      },
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
      "ephemeral": false,
      "ttl_seconds": 1,
      "expires_at": "2026-10-01T12:00:00.000Z",
      "created_by": "api"
    }
  ]
}
```

## Create Inbox

```http
POST /v0/inboxes
```

`ephemeral: true` without `ttl_seconds` creates an inbox with a one hour TTL (3600 seconds).

An organization can have at most 1,000 inboxes on the shared domain; past that the API returns `403`. Add your own domain for more. Inbox-scoped credentials cannot create inboxes (`403`).

A taken address returns `409`, and so does a reserved one: role and brand names on the shared domain, and `{slug}@` on the shared domain, which only the organization with that slug can create (`agent-` followed by 16 or more hex digits is reserved the same way).

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_create`.

#### Request body

Content type: `application/json`.

| Field | Type | | Description |
| --- | --- | --- | --- |
| `username` | `string` |  | Local part of the address: a-z, 0-9 and . _ + -, 1 to 64 characters. Randomly generated if omitted. On the shared domain, a username equal to another organization's slug is reserved for that organization (409). |
| `domain` | `string` |  | Domain of the address: a domain verified by this organization. Defaults to the shared domain. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Idempotency key: a create with a client_id already used in the organization returns that inbox with 200, or 409 when that inbox is outside the pod of the API key or route. |
| `status` | `"active" \| "paused"` |  | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `pod_id` | `string` |  | Pod to create the inbox in. Defaults to the credential pod or the organization default pod. |
| `ephemeral` | `boolean` |  | true without ttl_seconds creates an ephemeral inbox with a one hour TTL (3600 seconds). |
| `ttl_seconds` | `integer \| null` |  | Creates an ephemeral inbox that expires ttl_seconds after creation, extended by each inbound message. |
| `import_source` | `"agentmail"` |  | Marks an inbox copied from another provider by an importer (machinemail import agentmail sets agentmail). The only effect: its inbox.created event is not delivered to webhooks or MCP subscribers, so they are not notified about an inbox that already existed elsewhere. The event is still recorded (GET /v0/events, the event stream), marked as an import in its payload, so the event log shows every import. Everything else about the create is unchanged. |

#### Response

**200** An inbox with this client\_id already exists; it is returned unchanged. (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

**201** Created (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `409`  | Conflicts with an existing resource.                                                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl -X POST "https://api.machinemail.dev/v0/inboxes" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "username": "agent",
  "display_name": "Support Agent"
}'
```

```json title="Response 200"
{
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "email": "agent@machinemail.dev",
  "display_name": "Support Agent",
  "client_id": "my-client-id",
  "status": "active",
  "metadata": {
    "key": "value"
  },
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "ephemeral": false,
  "ttl_seconds": 1,
  "expires_at": "2026-10-01T12:00:00.000Z",
  "created_by": "api"
}
```

## Check Inbox Availability

```http
GET /v0/inboxes/availability
```

Whether `username@domain` can be created by this organization now. Never a 4xx for a bad name: `reason` says why it is not available.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Query parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `username` | `string` |  | Local part to check. |
| `domain` | `string` |  | Domain to check. Defaults to the shared domain. |

#### Response

**200** Availability of the address (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `available` | `boolean` | required |  |
| `email` | `string` | required | The address that was checked (lowercased). |
| `reason` | `"invalid_username" \| "domain_not_found" \| "taken"` |  | Why the address is not available. |
| `message` | `string` |  | Human-readable reason. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/inboxes/availability" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "available": false,
  "email": "agent@machinemail.dev",
  "reason": "invalid_username",
  "message": "string"
}
```

## Search Inboxes

```http
GET /v0/inboxes/search
```

Inboxes whose address or display name contains `q` (case-insensitive), newest first. Searches the newest 500 inboxes in scope; the response has `truncated: true` when there were more. Not ranked by relevance.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Query parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `q` | `string` | required | Text to find in the address or display name (case-insensitive substring). (min length 1) |
| `limit` | `integer` |  | Maximum number of items to return. Default 50, maximum 500; larger values are capped. |
| `page_token` | `string` |  | next_page_token from the previous page. |

#### Response

**200** A page of matching inboxes (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `count` | `integer` | required | Number of items returned. |
| `limit` | `integer` |  | Maximum number of items per page. Default 50, maximum 500; larger values are capped. |
| `next_page_token` | `string` |  | Page token for pagination. Absent on the last page. |
| `inboxes` | `Inbox[]` | required | Matching inboxes, newest first. |
| `truncated` | `true` |  | Present when the organization has more than 500 inboxes in scope: only the newest 500 were searched. |

Each item of `inboxes` is a [Inbox](https://machinemail.dev/docs/reference/api/objects#inbox):

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/inboxes/search?q=invoice" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "inboxes": [
    {
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "inbox_id": "agent@machinemail.dev",
      "email": "agent@machinemail.dev",
      "display_name": "Support Agent",
      "client_id": "my-client-id",
      "status": "active",
      "metadata": {
        "key": "value"
      },
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
      "ephemeral": false,
      "ttl_seconds": 1,
      "expires_at": "2026-10-01T12:00:00.000Z",
      "created_by": "api"
    }
  ],
  "truncated": true
}
```

## Get Inbox

```http
GET /v0/inboxes/{inbox_id}
```

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |

#### Response

**200** The inbox (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "email": "agent@machinemail.dev",
  "display_name": "Support Agent",
  "client_id": "my-client-id",
  "status": "active",
  "metadata": {
    "key": "value"
  },
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "ephemeral": false,
  "ttl_seconds": 1,
  "expires_at": "2026-10-01T12:00:00.000Z",
  "created_by": "api"
}
```

## Update Inbox

```http
PATCH /v0/inboxes/{inbox_id}
```

Fields you omit are unchanged. To pause an inbox, set `status` to `paused`; set it back to `active` to resume.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_update`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |

#### Request body

Content type: `application/json`.

| Field | Type | | Description |
| --- | --- | --- | --- |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `status` | `"active" \| "paused"` |  | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `(Record<string, string \| number \| boolean \| null>) \| null` |  | Merged into the existing metadata: keys you send are added or overwritten, keys set to null are removed, other keys are kept. null clears all metadata. |
| `ttl_seconds` | `integer \| null` |  | Make the inbox ephemeral with this TTL (expires_at restarts from now), or null to make it permanent. |
| `ephemeral` | `boolean` |  | false makes the inbox permanent (same as ttl_seconds: null). true alone has no effect; send ttl_seconds. |

#### Response

**200** The updated inbox (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl -X PATCH "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "display_name": "Support Agent"
}'
```

```json title="Response 200"
{
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "email": "agent@machinemail.dev",
  "display_name": "Support Agent",
  "client_id": "my-client-id",
  "status": "active",
  "metadata": {
    "key": "value"
  },
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "ephemeral": false,
  "ttl_seconds": 1,
  "expires_at": "2026-10-01T12:00:00.000Z",
  "created_by": "api"
}
```

## Delete Inbox

```http
DELETE /v0/inboxes/{inbox_id}
```

Deletes the inbox with its messages, attachments, threads and drafts. Inbox-scoped credentials cannot delete their own inbox (`403`).

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_delete`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |

#### Response

**200** Deleted (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `ok` | `true` | required |  |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl -X DELETE "https://api.machinemail.dev/v0/inboxes/agent@machinemail.dev" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "ok": true
}
```

## List Inboxes in Pod

```http
GET /v0/pods/{pod_id}/inboxes
```

Same as List Inboxes (`GET /v0/inboxes`), limited to the pod.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod. |

#### Query parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `limit` | `integer` |  | Maximum number of items to return. Default 50, maximum 500; larger values are capped. |
| `page_token` | `string` |  | next_page_token from the previous page. |
| `ascending` | `boolean` |  | Sort oldest first. |
| `ephemeral` | `boolean` |  | Only ephemeral (true) or only permanent (false) inboxes. |

#### Response

**200** A page of inboxes (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `count` | `integer` | required | Number of items returned. |
| `limit` | `integer` |  | Maximum number of items per page. Default 50, maximum 500; larger values are capped. |
| `next_page_token` | `string` |  | Page token for pagination. Absent on the last page. |
| `inboxes` | `Inbox[]` | required | Ordered by created_at, newest first unless ascending is set. |

Each item of `inboxes` is a [Inbox](https://machinemail.dev/docs/reference/api/objects#inbox):

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "inboxes": [
    {
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "inbox_id": "agent@machinemail.dev",
      "email": "agent@machinemail.dev",
      "display_name": "Support Agent",
      "client_id": "my-client-id",
      "status": "active",
      "metadata": {
        "key": "value"
      },
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
      "ephemeral": false,
      "ttl_seconds": 1,
      "expires_at": "2026-10-01T12:00:00.000Z",
      "created_by": "api"
    }
  ]
}
```

## Create Inbox in Pod

```http
POST /v0/pods/{pod_id}/inboxes
```

Same as Create Inbox (`POST /v0/inboxes`), limited to the pod.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_create`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod. |

#### Request body

Content type: `application/json`.

| Field | Type | | Description |
| --- | --- | --- | --- |
| `username` | `string` |  | Local part of the address: a-z, 0-9 and . _ + -, 1 to 64 characters. Randomly generated if omitted. On the shared domain, a username equal to another organization's slug is reserved for that organization (409). |
| `domain` | `string` |  | Domain of the address: a domain verified by this organization. Defaults to the shared domain. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Idempotency key: a create with a client_id already used in the organization returns that inbox with 200, or 409 when that inbox is outside the pod of the API key or route. |
| `status` | `"active" \| "paused"` |  | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `pod_id` | `string` |  | Pod to create the inbox in. Defaults to the credential pod or the organization default pod. |
| `ephemeral` | `boolean` |  | true without ttl_seconds creates an ephemeral inbox with a one hour TTL (3600 seconds). |
| `ttl_seconds` | `integer \| null` |  | Creates an ephemeral inbox that expires ttl_seconds after creation, extended by each inbound message. |
| `import_source` | `"agentmail"` |  | Marks an inbox copied from another provider by an importer (machinemail import agentmail sets agentmail). The only effect: its inbox.created event is not delivered to webhooks or MCP subscribers, so they are not notified about an inbox that already existed elsewhere. The event is still recorded (GET /v0/events, the event stream), marked as an import in its payload, so the event log shows every import. Everything else about the create is unchanged. |

#### Response

**200** An inbox with this client\_id already exists; it is returned unchanged. (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

**201** Created (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `409`  | Conflicts with an existing resource.                                                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl -X POST "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "username": "agent",
  "display_name": "Support Agent"
}'
```

```json title="Response 200"
{
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "email": "agent@machinemail.dev",
  "display_name": "Support Agent",
  "client_id": "my-client-id",
  "status": "active",
  "metadata": {
    "key": "value"
  },
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "ephemeral": false,
  "ttl_seconds": 1,
  "expires_at": "2026-10-01T12:00:00.000Z",
  "created_by": "api"
}
```

## Check Inbox Availability in Pod

```http
GET /v0/pods/{pod_id}/inboxes/availability
```

Same as Check Inbox Availability (`GET /v0/inboxes/availability`), limited to the pod.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod. |

#### Query parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `username` | `string` |  | Local part to check. |
| `domain` | `string` |  | Domain to check. Defaults to the shared domain. |

#### Response

**200** Availability of the address (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `available` | `boolean` | required |  |
| `email` | `string` | required | The address that was checked (lowercased). |
| `reason` | `"invalid_username" \| "domain_not_found" \| "taken"` |  | Why the address is not available. |
| `message` | `string` |  | Human-readable reason. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes/availability" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "available": false,
  "email": "agent@machinemail.dev",
  "reason": "invalid_username",
  "message": "string"
}
```

## Search Inboxes in Pod

```http
GET /v0/pods/{pod_id}/inboxes/search
```

Same as Search Inboxes (`GET /v0/inboxes/search`), limited to the pod.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod. |

#### Query parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `q` | `string` | required | Text to find in the address or display name (case-insensitive substring). (min length 1) |
| `limit` | `integer` |  | Maximum number of items to return. Default 50, maximum 500; larger values are capped. |
| `page_token` | `string` |  | next_page_token from the previous page. |

#### Response

**200** A page of matching inboxes (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `count` | `integer` | required | Number of items returned. |
| `limit` | `integer` |  | Maximum number of items per page. Default 50, maximum 500; larger values are capped. |
| `next_page_token` | `string` |  | Page token for pagination. Absent on the last page. |
| `inboxes` | `Inbox[]` | required | Matching inboxes, newest first. |
| `truncated` | `true` |  | Present when the organization has more than 500 inboxes in scope: only the newest 500 were searched. |

Each item of `inboxes` is a [Inbox](https://machinemail.dev/docs/reference/api/objects#inbox):

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes/search?q=invoice" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "inboxes": [
    {
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
      "inbox_id": "agent@machinemail.dev",
      "email": "agent@machinemail.dev",
      "display_name": "Support Agent",
      "client_id": "my-client-id",
      "status": "active",
      "metadata": {
        "key": "value"
      },
      "updated_at": "2026-10-01T12:00:00.000Z",
      "created_at": "2026-10-01T12:00:00.000Z",
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
      "ephemeral": false,
      "ttl_seconds": 1,
      "expires_at": "2026-10-01T12:00:00.000Z",
      "created_by": "api"
    }
  ],
  "truncated": true
}
```

## Get Inbox in Pod

```http
GET /v0/pods/{pod_id}/inboxes/{inbox_id}
```

Same as Get Inbox (`GET /v0/inboxes/{inbox_id}`), limited to the pod.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_read`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |

#### Response

**200** The inbox (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes/agent@machinemail.dev" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "email": "agent@machinemail.dev",
  "display_name": "Support Agent",
  "client_id": "my-client-id",
  "status": "active",
  "metadata": {
    "key": "value"
  },
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "ephemeral": false,
  "ttl_seconds": 1,
  "expires_at": "2026-10-01T12:00:00.000Z",
  "created_by": "api"
}
```

## Update Inbox in Pod

```http
PATCH /v0/pods/{pod_id}/inboxes/{inbox_id}
```

Same as Update Inbox (`PATCH /v0/inboxes/{inbox_id}`), limited to the pod.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_update`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |

#### Request body

Content type: `application/json`.

| Field | Type | | Description |
| --- | --- | --- | --- |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `status` | `"active" \| "paused"` |  | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `(Record<string, string \| number \| boolean \| null>) \| null` |  | Merged into the existing metadata: keys you send are added or overwritten, keys set to null are removed, other keys are kept. null clears all metadata. |
| `ttl_seconds` | `integer \| null` |  | Make the inbox ephemeral with this TTL (expires_at restarts from now), or null to make it permanent. |
| `ephemeral` | `boolean` |  | false makes the inbox permanent (same as ttl_seconds: null). true alone has no effect; send ttl_seconds. |

#### Response

**200** The updated inbox (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod the inbox belongs to. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |
| `email` | `string` | required | Email address of the inbox. |
| `display_name` | `string` |  | Display name: Display Name <username@domain.com>. |
| `client_id` | `string` |  | Client ID given at creation (idempotency key). |
| `status` | `"active" \| "paused"` | required | Whether the inbox sends and receives mail. paused stops both: sends return 403 (Inbox <inbox_id> is paused), and incoming mail is not stored; a message.rejected event with reason inbox_paused is emitted instead. Mail already in the inbox, its drafts and its API keys are kept. Set active to resume. |
| `metadata` | `Record<string, string \| number \| boolean>` |  | Custom key-value pairs attached to the inbox. |
| `updated_at` | `string (date-time)` | required | Time at which the inbox was last updated. |
| `created_at` | `string (date-time)` | required | Time at which the inbox was created. |
| `organization_id` | `string` | required | ID of the organization. |
| `ephemeral` | `boolean` | required | Whether the inbox expires (see ttl_seconds). |
| `ttl_seconds` | `integer` |  | TTL of an ephemeral inbox. Each inbound message pushes expires_at to now + ttl_seconds. |
| `expires_at` | `string (date-time)` |  | When an ephemeral inbox and its mail are deleted. |
| `created_by` | `"api" \| "catch_all" \| "dashboard" \| "agent"` | required | What created the inbox: the API, a catch-all domain, the dashboard or an agent registration. |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid request: error.type is validation and error.param names the field.                                                                                                                                                             |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl -X PATCH "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes/agent@machinemail.dev" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "display_name": "Support Agent"
}'
```

```json title="Response 200"
{
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "inbox_id": "agent@machinemail.dev",
  "email": "agent@machinemail.dev",
  "display_name": "Support Agent",
  "client_id": "my-client-id",
  "status": "active",
  "metadata": {
    "key": "value"
  },
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "ephemeral": false,
  "ttl_seconds": 1,
  "expires_at": "2026-10-01T12:00:00.000Z",
  "created_by": "api"
}
```

## Delete Inbox in Pod

```http
DELETE /v0/pods/{pod_id}/inboxes/{inbox_id}
```

Same as Delete Inbox (`DELETE /v0/inboxes/{inbox_id}`), limited to the pod.

**Authentication:** `Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `inbox_delete`.

#### Path parameters

| Field | Type | | Description |
| --- | --- | --- | --- |
| `pod_id` | `string` | required | ID of the pod. |
| `inbox_id` | `string` | required | ID of the inbox: its email address, as in AgentMail (inbox_id == email). |

#### Response

**200** Deleted (`application/json`)

| Field | Type | | Description |
| --- | --- | --- | --- |
| `ok` | `true` | required |  |

#### Errors

| Status | Meaning                                                                                                                                                                                                                                |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | Missing, invalid, expired or revoked credential.                                                                                                                                                                                       |
| `403`  | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404`  | Not found. Also returned for resources outside the credential scope.                                                                                                                                                                   |
| `500`  | Unexpected server error.                                                                                                                                                                                                               |

Error bodies use the [error envelope](https://machinemail.dev/docs/reference/errors).

#### Example

```bash title="Request"
curl -X DELETE "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/inboxes/agent@machinemail.dev" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

```json title="Response 200"
{
  "ok": true
}
```
