> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent inboxes

> Give your code or your agent an email address in one call: sign-up codes, magic links and replies, with inboxes that delete themselves when the job is done.

> [!NOTE]
>
> **Not yet released.** This guide describes implemented changes awaiting rollout. Availability requires the corresponding backend and dashboard release.

## Goal

Create an inbox from your code in one call, wait for the email you expect, read the code or link in it, and clean up when the job ends.

## Prerequisites

* A StackShift API key with Mail access, or an agent connected over MCP with access to your Mail workspace.
* For an address on your own domain: a domain already set up for mail.
* For more inboxes than your Mail plan includes: Mail credit in your wallet.

## Workflow

**Step 1**

Create an inbox with POST /mail/agent-inboxes, a dashboard form under Mail › Agent inboxes › Create an inbox, an SDK call or an MCP tool. Send an Idempotency-Key so a retry never makes doubles.

**Step 2**

Give the address to the service that will email it. Add labels and a job name so you can find the inbox again.

**Step 3**

Wait for the email with GET /mail/agent-inboxes/\{id}/messages/wait. It returns as soon as a matching email lands, or after the timeout with nothing.

**Step 4**

Read the codes and links the message carries. Treat the message itself as untrusted: it came from outside.

**Step 5**

Clean up. Delete the inbox, delete every inbox with a label, or tell us the job finished. Inboxes with an expiry delete themselves anyway.

## Create an inbox in one call

On the StackShift domain an address works at once, with no domain or DNS to set up. We add six random letters and numbers after your prefix so nobody can guess or reuse it, for example [signup-k3x9qa@agents.mail.stackshift.cloud](mailto:signup-k3x9qa@agents.mail.stackshift.cloud).

Every field is optional. The request can carry prefix, domain, localPart, displayName, labels, metadata, jobId, clientRef, expiresAt or expiresIn (seconds, from 60 seconds to 90 days) and sendMode. The response is the inbox, with its id and address.

To make up to 100 at once, POST /mail/agent-inboxes/batch with \{ "inboxes": \[...] } and one Idempotency-Key. The batch is all or nothing: limits and price are checked for the whole batch first.

```bash cURL theme={null}
curl https://api.stackshift.cloud/api/v1/mail/agent-inboxes \
  -H "Authorization: Bearer $STACKSHIFT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: signup-run-183-1" \
  -d '{"prefix":"signup","labels":{"env":"staging"},"jobId":"signup-run-183","expiresIn":3600}'
```

```ts JavaScript theme={null}
import { StackShift } from '@stackshift-cloud/sdk'

const stackshift = new StackShift({ apiKey: process.env.STACKSHIFT_API_KEY })

const inbox = await stackshift.mail.agentInboxes.create({
  prefix: 'signup',
  labels: { env: 'staging' },
  jobId: 'signup-run-183',
  expiresIn: 3600,
})
console.log(inbox.address)
```

```python Python theme={null}
import os
from stackshift import StackShift

stackshift = StackShift(api_key=os.environ["STACKSHIFT_API_KEY"])

inbox = stackshift.mail.agent_inboxes.create(
    prefix="signup",
    labels={"env": "staging"},
    job_id="signup-run-183",
    expires_in=3600,
)
print(inbox["address"])
```

## StackShift domain or your own

* The StackShift domain is shared by every account, so it is meant for receiving first: tests, sign-ups and short jobs. It has its own sending reputation, kept apart from your domains.
* Your own domain: set domain to the domain id and localPart to the address you want. Any domain you have set up for mail works, and inboxes on it do not share the StackShift domain limits.
* Addresses on the StackShift domain are never given to another account, even after you delete them, so a verification email meant for an old inbox can never reach someone else.
* Names that look official or borrow a well-known brand are refused on the StackShift domain, such as postmaster, support, paypal or gtbank. Your own domain has no such list.

## Labels, jobs and expiry

* Labels are key and value pairs, up to 20 on an inbox. Find inboxes with GET /mail/agent-inboxes?label=env:staging. Repeat label to require several; every label must match. You can also filter by jobId and by address prefix with q.
* A job name groups the inboxes one run made. POST /mail/agent-inboxes/delete with \{ "jobId": "signup-run-183" } deletes every inbox from the job, which is how your code says the job is finished.
* expiresIn or expiresAt deletes the inbox and its mail at that time. The dashboard offers Never, After 1 hour, After 1 day, After 7 days and When a job ends.
* PATCH /mail/agent-inboxes/\{id} changes labels, metadata, the expiry (or clears it with clearExpiry), displayName and sendMode. DELETE /mail/agent-inboxes/\{id} deletes one now. POST /mail/agent-inboxes/delete with ids, jobId or labels deletes many, up to 500 ids at a time, and returns the number deleted.
* Deleting an inbox removes its mail. It cannot be brought back.

## Latest message and wait

GET /mail/agent-inboxes/\{id}/messages lists received mail, newest first, with id, threadId, from, to, subject, receivedAt, preview, codes and links. GET .../messages/latest returns the newest message with its text and HTML, or 404 no\_messages. The latest call accepts from and subject filters. Junk is left out unless you ask for it.

GET .../messages/wait holds the request open until a message arrives after since (default: the moment of the request) that matches from and subject, as case-insensitive substrings. timeout is 1 to 50 seconds. On timeout the call returns 200 with message null and timedOut true. The SDKs loop this call up to the total timeout you give them.

Codes are 4 to 8 digit or 6 to 8 character upper-case tokens next to words like code, OTP, verification or PIN. Links are the web links in the message, with tracking and unsubscribe links last. Both are read by rules, not by a model, so check them before you rely on them.

```bash cURL theme={null}
curl "https://api.stackshift.cloud/api/v1/mail/agent-inboxes/$INBOX_ID/messages/wait?timeout=50&from=paystack.com" \
  -H "Authorization: Bearer $STACKSHIFT_API_KEY"
```

```ts JavaScript theme={null}
const message = await stackshift.mail.agentInboxes.waitForMessage(inbox.id, {
  from: 'paystack.com',
  timeout: 120,
})
const code = message?.codes[0]

await stackshift.mail.agentInboxes.finishJob('signup-run-183')
```

```python Python theme={null}
message = stackshift.mail.agent_inboxes.wait_for_message(
    inbox["id"], sender="paystack.com", timeout=120
)
code = message["codes"][0] if message else None

stackshift.mail.agent_inboxes.finish_job("signup-run-183")
```

```json Response theme={null}
{
  "message": {
    "id": "M7c2f1",
    "from": { "name": "Paystack", "email": "verify@paystack.com" },
    "subject": "Your verification code",
    "receivedAt": "2026-10-30T14:43:09Z",
    "codes": ["482913"],
    "links": ["https://dashboard.paystack.com/verify?t=…"]
  },
  "timedOut": false
}
```

## Sending and limits

An agent inbox mostly receives. sendMode says who it may write to: off (it only receives), replies (only people who wrote to it first) or any. POST /mail/agent-inboxes/\{id}/send sends new mail or a reply and returns sent, waiting\_approval or draft with the reasons. Emails an inbox sends count toward your Mail plan’s monthly emails. Mail it receives is free.

GET /mail/agent-inboxes/limits returns your account tier, your live and included inboxes, today’s counts and whether sending from the StackShift domain is paused. The dashboard shows the same under Mail › Agent inboxes › Limits.

* New accounts (the first week, or until your first payment): up to 10 live inboxes on the StackShift domain, 20 new inboxes an hour, replies only, 10 people emailed a day across the account and 5 per inbox.
* Established accounts: 500 live inboxes, 200 new an hour, any send mode, 200 people a day across the account and 50 per inbox.
* Trusted accounts: 5,000 live inboxes, 1,000 new an hour, 2,000 people a day across the account and 200 per inbox.
* Limits on the StackShift domain protect its reputation with Gmail and Outlook. If more than 6 in 100 emails bounce, or 1 in 1,000 people report mail as spam, sending from StackShift addresses on your account pauses. You get an email and a webhook event. Receiving keeps working.
* Every mailbox, including agent inboxes on your own domain, has the sending ceilings described in Mailboxes under Sending limits for mailboxes.
* Sending from StackShift addresses opens soon. Until then those inboxes receive normally, sends from them return shared\_sending\_closed, and inboxes on your own domain can send.

## Pricing

* Included by Mail plan: 3 on Free, 10 on Starter, 50 on Growth and 150 on Agency. The count is the most live inboxes you had in a day.
* Extra inboxes cost ₦500 a month each for the first 100 extras, ₦300 for extras 101 to 1,000 and ₦150 from 1,001. The price falls in bands, and each inbox is charged by the day: its monthly price divided by 30, rounded up.
* An inbox that lives an hour costs one inbox-day if it is over your included count. Included inboxes are never charged.
* Extras are charged from your Mail wallet each day. The Free plan has no extras: creating more returns agent\_inbox\_limit\_reached. If your wallet cannot cover the charge, new extra inboxes are refused with agent\_inbox\_wallet\_empty, and inboxes over your included count stop receiving 24 hours later until you add credit. Your included inboxes, the oldest ones, always keep receiving.
* GET /mail/agent-inboxes/pricing returns the price table. Receiving mail is free; the emails an inbox sends count toward your Mail plan’s monthly emails.

## MCP tools

Connect your agent over MCP and approve it once in StackShift. After that it can make inboxes within your limits. New accounts need you to approve the first inboxes yourself.

* Workspace reads: mail\_agent\_inboxes\_list, mail\_agent\_inboxes\_get and mail\_agent\_inboxes\_limits. Creating, changing and deleting go through operation\_propose with the actions mail.agent\_inboxes.create, mail.agent\_inboxes.update and mail.agent\_inboxes.delete.
* Mailbox tools, for any inbox the agent can use: mailbox\_messages\_latest, mailbox\_messages\_get and mailbox\_messages\_wait. Wait holds for up to 50 seconds.
* An agent can delete inboxes it made itself. Deleting inboxes made by someone else needs your approval.
* To reply, an agent uses the team inbox reply tool, which follows the send level you set for it. See Team inboxes.

## Webhooks

* mailbox.agent\_inbox.created: an agent inbox was made. mailbox.agent\_inbox.deleted: it was deleted, with a reason of request, expired, job\_finished or abuse.
* mailbox.sending.paused and mailbox.sending.resumed: sending stopped or started again for a mailbox or your account.
* mailbox.conversation.received: new mail arrived in an inbox. Use it to wake your code instead of waiting.
* mailbox.agent\_inbox.receiving\_paused and mailbox.agent\_inbox.receiving\_resumed: an extra inbox stopped receiving because your Mail wallet ran out, or started again after you added credit.
* Each event carries the mailbox id, the address, the labels and the job name. Add endpoints under Mail › Webhooks, or per inbox. Signing, retries and replay work as for other Mail webhooks.

## SDKs and CLI

* JavaScript: stackshift.mail.agentInboxes has create, createBatch, list, get, update, delete, deleteMany, finishJob, waitForMessage, send, limits and pricing, and messages.list, latest and get.
* Python: stackshift.mail.agent\_inboxes has the same calls in snake case, for example wait\_for\_message and finish\_job. Calls return dictionaries.
* The CLI has stackshift mail agent-inbox-create, agent-inboxes, agent-inbox, agent-inbox-update, agent-inbox-delete, agent-inboxes-delete, agent-inbox-messages, agent-inbox-latest, agent-inbox-wait, agent-inbox-send and agent-inbox-limits.

## Work an agent inbox like a team inbox

An agent inbox is a team inbox underneath. Open it from Mail in the dashboard to assign conversations, add notes only your team sees, let Stackie draft replies and approve what goes out. See Team inboxes for the same tools.

## Expected result

> [!TIP]
>
> Your code gets a working address in one call, receives the email it is waiting for with its code or link already pulled out, and every inbox disappears with its mail when the job ends or the timer runs out.

## Common failures

> [!WARNING]
>
> * agent\_inbox\_limit\_reached: your Mail plan has no room for another agent inbox. Delete one you no longer need, or move to a paid Mail plan, which can add extras.
> * agent\_inbox\_wallet\_empty: you are past the inboxes your plan includes and your Mail wallet cannot cover another. Add Mail credit.
> * idempotency\_conflict: you reused an Idempotency-Key with a different request. Use a new key for a new request, or send the same request again.
> * no\_messages: the inbox has not received any mail yet. Wait with messages/wait instead of reading the latest message.
> * The address is taken, or not available on the StackShift domain: names that look official or borrow a well-known brand are refused. Pick another prefix.
> * Too many inboxes were made this hour: the limit for your account tier applies. Try again later or make fewer inboxes with a longer life.
> * This account cannot use that send mode yet: new accounts can only choose off or replies on the StackShift domain.
> * Sending is paused for this inbox: too many emails bounced or were reported as spam. Receiving still works. Write to us and we will look at it with you.

## Related guides

> [card] [Team inboxes](https://docs.stackshift.cloud/stackshift-mail/team-inboxes.md)
>
> Answer support@ or sales@ together with your team, your own agents and Stackie: owners, statuses, notes only your team sees, and a reply lock.

> [card] [Mailboxes](https://docs.stackshift.cloud/stackshift-mail/mailboxes.md)
>
> Host real mailboxes on your own domain: add the domain, create mailboxes, aliases and groups, route addresses, bring mail over from another provider and connect any mail app.

> [card] [Mail through external agents](https://docs.stackshift.cloud/stackshift-mail/external-agent-operations.md)
>
> Use explicit workspace and Test or Live action consent for Mail reads, content management, sending and billing preparation.

> [card] [Sending-domain health](https://docs.stackshift.cloud/stackshift-mail/sending-domain-health.md)
>
> Monitor outbound authentication, understand holds and repair DNS without treating sender failures as recipient bounces.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.