# Inboxes

> Create, list, rename and delete inboxes. One inbox per agent, per user or per task.

Source: https://aimulti.inbox/docs/inboxes/

An inbox is an email address your agent owns. Creating one is a single API call; there is nothing to configure on a mail server.

## Create

* `username`: the local part, lowercase letters, digits, dots, dashes and underscores. Random when empty.
* `domain`: a verified [custom domain](https://aimulti.inbox/docs/custom-domains.md) of your organization. The platform shared domain when empty.
* `display_name`: the name shown to recipients, up to 200 characters.
* `client_id`: your own identifier. Repeating it returns the existing inbox with status `200` instead of `201`, so create calls are safe to retry.

```bash
curl -s -X POST https://api.162-55-213-24.sslip.io/v0/inboxes \
  -H "Authorization: Bearer $MAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"username": "billing", "domain": "agents.your-domain.eu", "display_name": "Billing agent", "client_id": "billing"}'
```

Errors: `403 limit_exceeded` when the plan's inbox limit is reached, `403 domain_not_verified` when the domain is not verified for your organization, `409 already_exists` when the address is taken, `409 address_quarantined` when it belonged to an inbox deleted less than 90 days ago.

## Identify an inbox

Paths take the inbox email address as `{inbox}`, for example `/v0/inboxes/billing@agents.your-domain.eu`. URL encode it when your HTTP client does not do it for you.

## Delete

Deleting an inbox deletes all its threads, messages and attachments, including the stored raw messages and files. It cannot be undone. The address is then reserved for 90 days: no organization can create it again in that window (`409 address_quarantined`), so nobody receives mail meant for the previous owner.

## Endpoints

### POST /v0/inboxes

Create an inbox (repeat client_id to get the same inbox)

Body (CreateInbox):

| Name | Type | Notes |
| --- | --- | --- |
| `username` | string | pattern ^[a-z0-9]([a-z0-9._-]{0,62}[a-z0-9])?$ |
| `domain` | string |  |
| `display_name` | string | max length 200 |
| `client_id` | string | pattern ^[A-Za-z0-9._~-]{1,256}$ |

Responses:

* `200` Existing inbox for this client_id: Inbox
* `201` Created: Inbox
* `403` Error envelope: Error
* `409` Error envelope: Error

### GET /v0/inboxes

List inboxes, newest first

Parameters:

| Name | Type | Notes |
| --- | --- | --- |
| `limit` | integer | in query, min 1, max 100, default 20 |
| `page_token` | string | in query |

Responses:

* `200` OK: InboxList

### GET /v0/inboxes/{inbox}

Get an inbox

Parameters:

| Name | Type | Notes |
| --- | --- | --- |
| `inbox` | string (email) | in path, required |

Responses:

* `200` OK: Inbox
* `404` Error envelope: Error

### PATCH /v0/inboxes/{inbox}

Update the display name, the signature, or the support intake of an inbox

Parameters:

| Name | Type | Notes |
| --- | --- | --- |
| `inbox` | string (email) | in path, required |

Body:

| Name | Type | Notes |
| --- | --- | --- |
| `display_name` | string | max length 200 |
| `ticket_intake` | boolean | New threads on this inbox become tickets in the support queue. |
| `signature_html` | string | HTML signature of this address. Empty string removes it., max length 20000 |

Responses:

* `200` OK: Inbox

### DELETE /v0/inboxes/{inbox}

Delete an inbox and all its mail

Parameters:

| Name | Type | Notes |
| --- | --- | --- |
| `inbox` | string (email) | in path, required |

Responses:

* `204` Deleted
* `404` Error envelope: Error

### Inbox object

| Name | Type | Notes |
| --- | --- | --- |
| `id` | string (uuid) |  |
| `inbox_id` | string (email) |  |
| `email` | string (email) |  |
| `display_name` | string |  |
| `client_id` | string |  |
| `ticket_intake` | boolean | New threads on this inbox become tickets. |
| `sending_paused_at` | string (date-time) | Set when the breaker paused sending for this inbox; null when only the organization is paused, which sending_health reports in paused_scope. An operator resumes it. |
| `sending_paused_reason` | string |  |
| `sending_health` | SendingHealth |  |
| `signature_html` | string | The signature of this address, HTML, applied to every message composed after it was written. Changing it never rewrites a draft that already exists (the rule of Proton): a draft keeps the signature of its own moment. |
| `group` | GroupRef |  |
| `grants_count` | integer | How many people hold access directly on this inbox. Null unless the caller is the owner or an admin. |
| `created_at` | string (date-time) |  |
| `updated_at` | string (date-time) |  |

### SendingHealth object

| Name | Type | Notes |
| --- | --- | --- |
| `state` | ok \| paused | paused means sending from this inbox is refused with 403 sending_paused. |
| `paused_scope` | string | What paused sending: inbox, organization, or empty while state is ok. A send is refused by both scopes, so this is what tells them apart. Not an enum because the empty string is a value, and a validator that rejected it would fail on every healthy inbox. |
| `paused_at` | string (date-time) | When the breaker paused the inbox or its organization; null while state is ok. |
| `paused_reason` | string | The same sentence the 403 sending_paused carries, naming the window and the limit that was crossed, and the counts at the moment of the pause. |
| `window_hours` | integer | Length of the rolling window the counts cover. |
| `sends` | integer | Messages that reached a final outcome (accepted or rejected) in the window. |
| `hard_bounces` | integer | Permanent rejections at send time plus bounces reported later by a delivery status notification. |
| `complaints` | integer | Spam complaints reported through the feedback loop. |
| `bounce_rate` | number | hard_bounces divided by sends, 0 when sends is 0. |
| `complaint_rate` | number | complaints divided by sends, 0 when sends is 0. |
| `thresholds` | SendingThresholds |  |

### SendingThresholds object

| Name | Type | Notes |
| --- | --- | --- |
| `max_bounce_rate` | number | Hard bounce rate above which sending pauses. |
| `max_complaint_rate` | number | Complaint rate above which sending pauses, once min_complaint_sends is reached. |
| `min_sends` | integer | Sends needed in the window before the bounce rate applies. |
| `min_complaint_sends` | integer | Sends needed before the complaint rate applies; below it the limit is a count. |
| `small_sender_complaints` | integer | Complaints in the window that pause sending below min_complaint_sends. |
