# Inboxes

{/* // REAL MAILBOXES */}

A Postern **inbox** is a real mailbox — not a forwarding alias, not a catch-all. It has a full IMAP
backing store (WildDuck), an authenticated sender registration (Azure Communication Services), and an
agent-ownership overlay that ties it to the agent and the enrollment key that minted it.

## Lifecycle

1. **Create** — pick or derive a domain per the org's onboarding mode, create a WildDuck mailbox,
   register the ACS sender (this step is **never skipped** — it's what stops bounces), seal the
   password with the credential AEAD, and return the address. The default path mints on an
   already-verified shared subdomain of `mszazu.com`, so creation is instant. POST /v1/inboxes

2. **Send** — via ACS as an authenticated sender, so mail is SPF + DKIM aligned and lands. POST /v1/inboxes/{addr}/send

3. **Receive** — into the WildDuck mailbox over IMAP; surfaced as structured messages, HMAC-signed
   webhooks, and [`wait_for_email`](https://docs.agents.mszazu.com/quickstart/wait-for-email/). GET /v1/inboxes/{addr}/messages

4. **Reply** — in-thread; `In-Reply-To` / `References` are handled server-side from IMAP. POST /v1/messages/{id}/reply

5. **Delete** — WildDuck account teardown + ACS sender removal, tenant re-checked. DELETE /v1/inboxes/{addr}
**ACS sender registration is mandatory:** Creating a mailbox without registering it as an authorized ACS sender causes bounces. Postern
  always performs the sender registration as part of `create` — there is no path that skips it.

## Addressing

Omit `username` and `domain` on create and Postern mints an instant address on a pre-warmed shared
subdomain — for example `agent7@x4p.mszazu.com`. Provide a `username` for a stable local part, or a
`domain` (within the key's `allowed_domains`) to place the mailbox on a specific
[onboarded domain](https://docs.agents.mszazu.com/concepts/domains-and-onboarding/).

```ts
// instant, shared subdomain
await postern.inboxes.create();                              // agent7@x4p.mszazu.com

// stable local part
await postern.inboxes.create({ username: "support" });       // support@x4p.mszazu.com

// a specific onboarded domain
await postern.inboxes.create({ username: "billing", domain: "mail.acme.com" });
```

## Receiving: three ways to read

| Mechanism | Use it when |
|---|---|
| **Poll** `messages` / `threads` | A simple loop or a UI that lists what's there. |
| **Webhooks** (`message.received`) | You want push delivery — HMAC-signed, timestamped, verifiable at the edge. |
| **`wait_for_email`** | You need the *next* matching message in the same turn (OTP, verification). |

Threading is reconstructed from IMAP headers, so a `thread` groups a conversation across inbound and
outbound messages without you tracking message ids by hand.

## Credentials & the encrypted store

The mailbox password is sealed with the credential AEAD and never returned in plaintext by default.
When credentials are returned (e.g. for an IMAP integration), they ride the console's signed,
short-TTL link discipline. The agent doesn't need the IMAP password for the normal send/receive/wait
path — the agent key is enough.

## Deleting cleanly

`delete` tears down both halves — the WildDuck account and the ACS sender — and re-checks tenancy so
one org can never delete another's mailbox. Deleting a mailbox does **not** refund a mailbox slot on
the enrollment key; the `used_count` reflects lifetime mints, which is what bounds a leaked key.

## Next

- [Domains & onboarding](https://docs.agents.mszazu.com/concepts/domains-and-onboarding/) — where mailboxes can live.
- [Deliverability & karma](https://docs.agents.mszazu.com/concepts/deliverability-and-karma/) — what keeps them landing.
- [wait_for_email](https://docs.agents.mszazu.com/quickstart/wait-for-email/) — the receive primitive agents reach for most.