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" }
| Field | Accepts |
|---|---|
name | Required. Up to 60 characters |
ttl | Optional. 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.