# Create an inbox

POST /v1/inboxes

Source: https://cherami.to/docs/api/inboxes/create-inbox



{/* Generated from apps/web/openapi. Edit the contract, not this file. */}

`POST /v1/inboxes`

Requires a [Claim-issued API key](https://cherami.to/docs/api#authentication): `Authorization: Bearer YOUR_CREDENTIAL`.

Both names accept Unicode text up to 256 UTF-8 bytes after trimming, without control characters. Omitted, null and blank names mean no name at creation. Existing inboxes without names return null for both fields. Names need not be unique. Unknown fields are rejected.

Addresses are globally unique. `hello`, `test`, `reviewer_chatgpt` and prefixes beginning `reviewer_chatgpt_` are reserved; retired addresses cannot be reused. No custom domains or allocated-address renaming are supported. To replace an address while keeping the old inbox during transition, see [Change your agent's email address](https://cherami.to/docs/guides/change-email-address).

New creation returns `201` with the inbox object and `Location: /v1/inboxes/{id}`. `400` means invalid input. `409` covers unavailable addresses, the inbox cap and key conflicts. A definitive `address_unavailable` permits choosing another prefix; do not create accounts to evade a cap.

An inbox-cap failure has `error.code: "inbox_limit_reached"` and `error.details` containing `allowance` (the same shape as `inbox_allowance`), `increase_request` and `policy_url`. Request additional slots for another workflow or an address transition rather than retiring an inbox you still need. See [Free and custom allowances](https://cherami.to/pricing).

### Recover creation [#recover-creation]

Creation keys are scoped to the authenticated account across HTTP and MCP, independently of sending keys. Protection lasts **24 hours from successful allocation**, without renewal. Keyed results add `replayed` and `idempotency_expires_at`. Initial creation returns `201` with `replayed: false`; a matching retry returns `200` with `replayed: true` and the original inbox ID. Both supply `Location`.

A replay returns the inbox's **current state**, not a frozen creation response. Later name edits are preserved. Retry with the original creation inputs, not those edited names. JSON property order is irrelevant; address-prefix case and surrounding whitespace, trimmed name whitespace, and absent/null/blank names normalize equivalently. Different validated inputs return `409 idempotency_conflict`.

Deleting the inbox does not free an active key. A matching retry returns `409 idempotency_result_unavailable`, never allocates a replacement and never restores the deleted inbox. Concurrent matching requests allocate only one inbox and consume one slot.

If creation's outcome is uncertain, reuse the original key and unchanged payload **within 24 hours of your first request**. Do not replace the key or choose another address to resolve uncertainty. Validation and allocation failures that definitely precede creation do not consume a key; an infrastructure error may follow successful creation.

After expiry, the key no longer protects a request. List inboxes and reconcile the intended address instead of blindly creating again. An existing or retired address remains unavailable, but that is not a replay result. Unkeyed creation is supported: another request for the same address conflicts rather than returning the original resource. If its response was lost, list inboxes before deciding what to do.

## Request body [#request-body]

JSON object. Total UTF-8 request body limit: 4096 bytes.

### Schema: CreateInbox [#schema-createinbox]

| Field             | Required | Type           | Meaning and constraints                                                                                                                                                              |
| ----------------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `local_part`      | Yes      | string         | Trimmed and lowercased, then 1–64 ASCII letters, digits, hyphens or underscores with alphanumeric ends. Reserved, existing and retired addresses are unavailable.                    |
| `name`            | No       | string or null |                                                                                                                                                                                      |
| `sender_name`     | No       | string or null |                                                                                                                                                                                      |
| `idempotency_key` | No       | string         | Retain a unique key, exact payload and first request time for this intended operation. Account-scoped protection lasts 24 hours without renewal. `pattern`: `^[A-Za-z0-9_-]{1,128}$` |

Unknown fields are rejected.

## curl example [#curl-example]

Replace resource-ID placeholders with returned IDs. Supply `CHERAMI_API_KEY` through your private shell environment.

Save the intended payload as a private `request.json` file and replace illustrative values. For an uncertain response, follow the [operation-specific recovery rules](https://cherami.to/docs/api/errors#retry-by-operation).

```json
{
  "local_part": "my-agent",
  "name": "Research",
  "idempotency_key": "RETAIN_A_UNIQUE_CREATION_KEY"
}
```

```sh
curl --silent --show-error --include --request POST \
  "https://cherami.to/v1/inboxes" \
  --header "Authorization: Bearer $CHERAMI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data-binary @request.json
```

## Responses [#responses]

### HTTP 200 [#http-200]

Matching replay: current resource or saved attempt, without another allocation or provider submission.

* `X-Request-ID`: Support correlation ID, not an idempotency key.
* `Location`: Relative URL of the resulting resource.

Content type: `application/json`.

All of these schemas apply.

### Part 1 [#part-1]

[CreatedInbox](#schema-createdinbox)

### Part 2 [#part-2]

| Field                    | Required | Type   | Meaning and constraints                                                                                                              |
| ------------------------ | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `replayed`               | Yes      | `true` |                                                                                                                                      |
| `idempotency_expires_at` | Yes      | string | UTC service instant with milliseconds and Z suffix. `format`: `date-time` `pattern`: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$` |

```json
{
  "id": "11111111-1111-4111-8111-111111111111",
  "local_part": "my-agent",
  "address": "my-agent@cherami.to",
  "name": null,
  "sender_name": null,
  "created_at": "2026-10-01T00:00:00.000Z",
  "replayed": true,
  "idempotency_expires_at": "2026-10-02T00:00:00.000Z"
}
```

### HTTP 201 [#http-201]

Successful operation; inspect resource state and outcome fields.

* `X-Request-ID`: Support correlation ID, not an idempotency key.
* `Location`: Relative URL of the resulting resource.

Content type: `application/json`.

All of these schemas apply.

### Part 1 [#part-1-1]

[CreatedInbox](#schema-createdinbox)

### Part 2 [#part-2-1]

| Field      | Required | Type    | Meaning and constraints |
| ---------- | -------- | ------- | ----------------------- |
| `replayed` | No       | `false` |                         |

### HTTP 400 [#http-400]

`invalid_json`: Send a valid UTF-8 JSON object, not an array or scalar.

`invalid_inbox`: Use supported inbox fields; editing requires at least one name field.

`invalid_local_part`: Correct the requested [address prefix](https://cherami.to/docs/api/inboxes/create-inbox).

`invalid_name`: Correct the inbox, sender or recipient display name using the returned guidance.

`invalid_idempotency_key`: Use 1–128 ASCII letters, digits, hyphens or underscores.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 401 [#http-401]

`unauthorized`: Provide a valid bearer credential. Use [human-approved recovery](https://cherami.to/docs/guides/recovery) if access is lost.

* `X-Request-ID`: Support correlation ID, not an idempotency key.
* `WWW-Authenticate`: `"Bearer"`

Content type: `application/json`.

[Error](#schema-error)

### HTTP 404 [#http-404]

`not_found`: Resource is absent or inaccessible to this account. Reply targets must be in the sending inbox.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 409 [#http-409]

`address_unavailable`: Choose another address prefix; this address cannot be allocated.

`inbox_limit_reached`: Read `error.details.allowance` for occupied and remaining slots; [request an increase](https://cherami.to/docs/guides/support) if needed.

`idempotency_conflict`: The key belongs to different input. Recover with the original inbox and payload, not a replacement key.

`idempotency_result_unavailable`: The key was used but its inbox, draft or sent copy is unavailable. No replacement was created or submitted; do not bypass protection with a new key.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[InboxError](#schema-inboxerror)

### HTTP 413 [#http-413]

`body_too_large`: Reduce the JSON request to the endpoint's body limit.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 415 [#http-415]

`unsupported_media_type`: Send `Content-Type: application/json`.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

### HTTP 500 [#http-500]

`internal_error`: Operation failed; a write may already have happened. Follow the operation-specific recovery below.

* `X-Request-ID`: Support correlation ID, not an idempotency key.

Content type: `application/json`.

[Error](#schema-error)

## Schema: CreatedInbox [#schema-createdinbox]

Keyed creation adds both replay fields. Replay returns the inbox's current names, not the initial snapshot.

| Field                    | Required | Type           | Meaning and constraints                                                                                                              |
| ------------------------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `id`                     | Yes      | string         | Cherami resource ID, distinct from the RFC Message-ID. Use the returned value.                                                       |
| `local_part`             | Yes      | string         |                                                                                                                                      |
| `address`                | Yes      | string         |                                                                                                                                      |
| `name`                   | Yes      | string or null |                                                                                                                                      |
| `sender_name`            | Yes      | string or null |                                                                                                                                      |
| `created_at`             | Yes      | string         | UTC service instant with milliseconds and Z suffix. `format`: `date-time` `pattern`: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$` |
| `replayed`               | No       | boolean        |                                                                                                                                      |
| `idempotency_expires_at` | No       | string         | UTC service instant with milliseconds and Z suffix. `format`: `date-time` `pattern`: `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$` |

## Schema: Error [#schema-error]

| Field   | Required | Type   | Meaning and constraints |
| ------- | -------- | ------ | ----------------------- |
| `error` | Yes      | object |                         |

### `error` fields [#error-fields]

| Field     | Required | Type   | Meaning and constraints                                                                       |
| --------- | -------- | ------ | --------------------------------------------------------------------------------------------- |
| `code`    | Yes      | string | Programmatic error code. Handle unrecognized codes by status and operation-specific recovery. |
| `message` | Yes      | string | Human-readable context, not a stable string to match.                                         |

## Schema: InboxError [#schema-inboxerror]

| Field   | Required | Type   | Meaning and constraints |
| ------- | -------- | ------ | ----------------------- |
| `error` | Yes      | object |                         |

### `error` fields [#error-fields-1]

| Field     | Required | Type   | Meaning and constraints                                                                       |
| --------- | -------- | ------ | --------------------------------------------------------------------------------------------- |
| `code`    | Yes      | string | Programmatic error code. Handle unrecognized codes by status and operation-specific recovery. |
| `message` | Yes      | string | Human-readable context, not a stable string to match.                                         |
| `details` | No       | object |                                                                                               |

#### `details` fields [#details-fields]

| Field              | Required | Type                                     | Meaning and constraints |
| ------------------ | -------- | ---------------------------------------- | ----------------------- |
| `allowance`        | Yes      | [InboxAllowance](#schema-inboxallowance) |                         |
| `increase_request` | Yes      | string                                   |                         |
| `policy_url`       | Yes      | string                                   |                         |

## Schema: InboxAllowance [#schema-inboxallowance]

| Field       | Required | Type            | Meaning and constraints |
| ----------- | -------- | --------------- | ----------------------- |
| `allowance` | Yes      | integer         | `minimum`: `0`          |
| `used`      | Yes      | integer         | `minimum`: `0`          |
| `remaining` | Yes      | integer         | `minimum`: `0`          |
| `unit`      | Yes      | `"inbox_slots"` |                         |

[HTTP conventions, errors and pagination](https://cherami.to/docs/api/errors) · [Download OpenAPI 3.1](https://cherami.to/openapi.json)
