Inboxes

An inbox is what an application sends to. The API can list the ones you have, and mint one per pipeline run that cleans up after itself.

List inboxes

GET /api/v1/inboxes
Scope: inboxes:read

Response:
[
  {
    "id": "k3n8x2p9qa7c1m4z",
    "name": "Acme — staging",
    "color": "#6366f1",
    "forward_email": "k3n8x2p9qa7c1m4z@mailclutch.com",
    "ephemeral": false,
    "expires_at": null,
    "created_at": "2026-08-03T09:14:22.000000Z",
    "url": "https://app.mailclutch.com/studio-nord/acme-staging",
    "organization": { "id": "b7t4m1w0zc9k2r5e", "name": "Studio Nord" }
  }
]

Every inbox the token reaches — all of the organization's, or the ones it is bound to. The listing never carries SMTP credentials; read one inbox for those.

Read one inbox

GET /api/v1/inboxes/{inbox_id}
Scope: inboxes:read

Response: the inbox above, plus
{
  "smtp": {
    "host": "smtp.mailclutch.com",
    "port": 587,
    "username": "mc_7f3k...",
    "password": "…",
    "encryption": "starttls"
  }
}

The SMTP pair is what an application configures to send into this inbox. Treat the response as a secret. forward_email is the other way in: mail sent or forwarded to that address lands in the inbox like any other capture.

Create an inbox

POST /api/v1/inboxes
Scope: inboxes:create
Idempotency-Key: <recommended>

{ "name": "pr-482", "ttl": "30m" }

Response: 201, the inbox with its smtp block and
{
  "ephemeral": true,
  "expires_at": "2026-09-02T09:44:22.000000Z"
}
Fields accepted when creating an inbox
FieldAccepts
nameRequired. Up to 60 characters
ttlOptional. A duration: 90s, 30m, 2h, 1d. Clamped to between 1 minute and 24 hours

Permanent or ephemeral

Without a ttl the inbox is permanent and counts against the plan's project quota, exactly as one created in the app. When the quota is full the call answers 422 and says so.

With a ttl the inbox is ephemeral: the unit of a pipeline. One per pull request, per branch, per matrix cell. It is outside the project quota on purpose — the first team to adopt CI would otherwise hit the limit on day one — and bounded instead by how many can be alive at once: 50 per organization. When the TTL runs out the inbox and everything in it are deleted for good, within about fifteen minutes. A runner that dies mid-run leaves nothing behind.

Send an Idempotency-Key: a retried create must not mint a second inbox. See Conventions.

A token bound to specific inboxes cannot create one — the result would be outside its own reach — and answers 403.

Delete an inbox

DELETE /api/v1/inboxes/{inbox_id}
Scope: inboxes:delete

Response:
{ "deleted": true }

A permanent inbox goes to the trash, as it does from the app. An ephemeral one is purged outright. Either way the inbox disappears from every open browser tab and any share link into it dies immediately.