cherami.
API referenceInboxes and rules

Create an inbox

POST /v1/inboxes

Read as Markdown ↗

POST /v1/inboxes

Requires a Claim-issued API key: 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.

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.

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

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

Schema: CreateInbox

FieldRequiredTypeMeaning and constraints
local_partYesstringTrimmed and lowercased, then 1–64 ASCII letters, digits, hyphens or underscores with alphanumeric ends. Reserved, existing and retired addresses are unavailable.
nameNostring or null
sender_nameNostring or null
idempotency_keyNostringRetain 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

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.

{
  "local_part": "my-agent",
  "name": "Research",
  "idempotency_key": "RETAIN_A_UNIQUE_CREATION_KEY"
}
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

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

CreatedInbox

Part 2

FieldRequiredTypeMeaning and constraints
replayedYestrue
idempotency_expires_atYesstringUTC 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$
{
  "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

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

CreatedInbox

Part 2

FieldRequiredTypeMeaning and constraints
replayedNofalse

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.

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

HTTP 401

unauthorized: Provide a valid bearer credential. Use human-approved recovery if access is lost.

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

Content type: application/json.

Error

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

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 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

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

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

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: CreatedInbox

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

FieldRequiredTypeMeaning and constraints
idYesstringCherami resource ID, distinct from the RFC Message-ID. Use the returned value.
local_partYesstring
addressYesstring
nameYesstring or null
sender_nameYesstring or null
created_atYesstringUTC 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$
replayedNoboolean
idempotency_expires_atNostringUTC 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

FieldRequiredTypeMeaning and constraints
errorYesobject

error fields

FieldRequiredTypeMeaning and constraints
codeYesstringProgrammatic error code. Handle unrecognized codes by status and operation-specific recovery.
messageYesstringHuman-readable context, not a stable string to match.

Schema: InboxError

FieldRequiredTypeMeaning and constraints
errorYesobject

error fields

FieldRequiredTypeMeaning and constraints
codeYesstringProgrammatic error code. Handle unrecognized codes by status and operation-specific recovery.
messageYesstringHuman-readable context, not a stable string to match.
detailsNoobject

details fields

FieldRequiredTypeMeaning and constraints
allowanceYesInboxAllowance
increase_requestYesstring
policy_urlYesstring

Schema: InboxAllowance

FieldRequiredTypeMeaning and constraints
allowanceYesintegerminimum: 0
usedYesintegerminimum: 0
remainingYesintegerminimum: 0
unitYes"inbox_slots"

HTTP conventions, errors and pagination · Download OpenAPI 3.1

On this page