Mailbox API: A Developer's Guide to Agent-Scale Email

A mailbox API gives an application a durable email identity it can operate through code. It can list messages, follow threads, fetch selected content, update mailbox state, send replies, and react when new mail arrives. The useful distinction is not REST versus SMTP. It is whether the API exposes enough mailbox state to keep an automated workflow correct after retries, reconnects, and concurrent changes.
For agents, that state boundary matters more than a long endpoint list. A production integration should minimise retrieved content, keep credentials narrowly scoped, treat message bodies and attachments as untrusted, and recover from missed events without rebuilding the entire inbox.
Start with the Mailbox API boundary
The Sendmux Mailbox API is designed for a client acting as one mailbox, or as one mailbox from a connected-app grant. Team-wide provisioning belongs to the Management API, while high-volume provider-routed sending belongs to the Sending API. Keeping those product lines separate prevents a mailbox worker from inheriting team-wide authority it does not need.
Requests use JSON over HTTPS at https://app.sendmux.ai/api/v1. Authenticate with a mailbox credential, a connected-app access token, or an agent access token in the Authorization: Bearer <token> header. Manual mailbox credentials are scoped to one mailbox. Connected-app tokens can be granted one or more mailboxes, and agent tokens remain limited by their granted scopes. Root API keys are rejected on Mailbox API endpoints.
Start a client by discovering its boundary rather than hard-coding assumptions. GET /mailbox/me resolves the mailbox for a mailbox-scoped credential. GET /mailbox/mailboxes lists the mailboxes granted to a connected app, and GET /mailbox/session reports supported capabilities, limits, and current state tokens.
Model messages, threads, folders, and submissions separately
A usable mailbox model has several related resources, but they are not interchangeable.
| Resource | Use it for |
|---|---|
| Messages | Individual inbound or outbound records, flags, bodies, headers, and attachment metadata. |
| Threads | Conversation-level participants, message order, unread state, and clean thread content. |
| Folders | Mailbox organisation and folder-specific state changes. |
| Submissions | The lifecycle and result of a send initiated from the mailbox. |
| Quotas | Current mailbox usage and limits. |
Keep opaque resource IDs as identifiers. Do not derive meaning from their shape or try to recreate threading from subjects alone. Thread APIs already provide message IDs, participants, the latest message, unread count, and conversation state.
Retrieve less before you retrieve full content
At mailbox scale, payload design has a direct operational cost. The cheapest question is often a count, not a list. GET /mailbox/messages/count applies message filters without returning rows, so a worker can decide whether further retrieval is necessary. GET /mailbox/messages/search-snippets returns subject and preview snippets for text searches without loading every body.
List endpoints support filters, sorting, and cursor pagination. Use the narrowest available query, then batch exact IDs when the next operation is already known. POST /mailbox/messages:batch-get can read selected messages, while the batch update and delete endpoints change several records without a request per item.
Sendmux mailbox credentials are limited to 1800 requests per minute. Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. A 429 rate_limit_exceeded response also includes Retry-After. Clients should honour those values rather than guessing a fixed delay.
Choose raw or clean message content deliberately
The right message representation depends on the consumer. Use GET /mailbox/messages/{message_id}/body when an audit, migration, or diagnostic path needs the available raw text or HTML. Use GET /mailbox/messages/{message_id}/content when an agent needs deterministic cleaned content with explicit controls.
Clean content can strip signatures and quoted text, include or omit links and HTML, select headers, and return attachment metadata without parsing attachment contents. That makes the product decision visible in the request. Signature removal is not HTML sanitisation, and a cleaned body is not permission to follow instructions found inside a message.
Attachments remain a separate trust boundary. Read their metadata first, enforce file type and size policy, and download bytes only when the workflow actually needs them. Do not place an attachment or an entire historical thread into a model prompt by default.
Use state tokens for reliable mailbox sync
Events tell a client that something happened. State tokens prove what changed. A reliable integration uses both.
GET /mailbox/messages/query-changes tracks additions, removals, and ordering changes for a saved message query. Folder, submission, and quota endpoints have their own change feeds. GET /mailbox/changes can return a typed state map for messages, folders, threads, submissions, identities, and quotas.
Persist the new state token only after the corresponding changes have been applied successfully. If processing fails halfway through, retain the prior token and retry the same page. This keeps a crash from creating a silent gap in local state.
Choose webhooks or Server-Sent Events by ownership
Use signed webhooks when a backend must receive events while no mailbox client is connected. Verify X-Sendmux-Signature against the raw request body, deduplicate retries with X-Sendmux-Event-Id, and return success only after the event has been accepted durably. Process slower work after the response.
Use GET /mailbox/events when an agent, CLI, MCP server, or SDK can keep a live Server-Sent Events connection open. The stream carries received-message events. Resume with Last-Event-ID or last_event_id; if the server reports sync_required, reconcile through GET /mailbox/changes before reopening the stream.
Neither transport replaces sync. Webhook retries can arrive more than once, and an SSE connection can outlive its replay window. Event IDs handle duplicate delivery, while state tokens repair gaps.
Make writes safe under retries and concurrency
Any network can fail after the server accepts a request but before the client receives the response. For Mailbox API POST operations that support it, persist an Idempotency-Key before the first attempt and reuse that key only for the same request body. A different body under the same key is a conflict, not a new operation.
Single-resource endpoints can expose weak ETag values. Use If-None-Match to avoid transferring an unchanged resource, and use If-Match on supported updates or deletes when a stale edit must fail instead of overwriting newer state.
Sending from the authenticated mailbox uses POST /mailbox/messages/send. Track the resulting submission rather than treating request acceptance as final delivery. If an automated agent registered itself, its durable token can read and receive mail but cannot send until the owner approves sending and the agent exchanges it for the appropriate short-lived send token.
Keep protocol support and API authority distinct
Mailbox credentials can also be used as the mailbox password for SMTP submission and IMAP retrieval. That interoperability is useful for existing tools, but it does not collapse the API, SMTP, and IMAP into one permission model. Use the Mailbox API for structured mailbox state, SMTP when a client requires message submission, and IMAP when a compatible mail client needs mailbox access.
Domain authentication remains separate from mailbox retrieval. SPF, DKIM, and DMARC affect how receiving systems evaluate outbound mail. They do not fix a missing idempotency key, a stale state token, or an over-broad mailbox credential.
A practical mailbox API integration sequence
- Resolve the granted mailbox and capabilities through the discovery endpoints.
- Store opaque IDs, cursors, ETags, and state tokens without interpreting their format.
- Use counts, filters, snippets, and exact batches before requesting full content.
- Select raw or clean content explicitly and keep attachment bytes outside the default agent context.
- Combine webhooks or SSE with state-token reconciliation, deduplication, and durable acceptance.
- Add idempotency to retriable writes and optimistic concurrency where stale edits matter.
- Test rate limiting, reconnects, duplicate events, expired replay windows, partial processing, and forbidden credentials before production.
The practical rule
Treat the mailbox as synchronised state, not a stream of isolated messages. Retrieve only what the next decision needs, separate live notification from recovery, and make every retriable mutation safe. That is what lets one integration grow from a single inbox to an agent fleet without losing mail or acting twice.
Frequently Asked Questions
What is a mailbox API used for?
A mailbox API gives applications programmatic control over sending, receiving, and organising email, letting developers provision inboxes, read and reply to messages, and receive real-time events instead of building this from scratch.
How does authentication work on a mailbox API?
Most mailbox APIs use bearer tokens in the Authorization header, scoped to specific permissions like send, receive, or read, with separate credential types for infrastructure-wide access versus single-mailbox access.
Should I use webhooks or polling to retrieve new email?
Use signed webhooks for a backend that must receive events while clients are offline, or Server-Sent Events for a connected mailbox client. In both cases, use state-token change endpoints to recover gaps instead of relying on the event transport alone.
What's the difference between a connected inbox and a platform-owned mailbox?
A connected inbox gives an application authorised access to an existing provider account, while a platform-owned mailbox is provisioned as part of the application service. The important engineering questions are who controls the identity, where state lives, which permissions apply, and how changes are synchronised.
Do mailbox APIs support both REST and SMTP?
Some services support both. Sendmux uses the Mailbox API for structured mailbox state and accepts a manual mailbox credential as the password for SMTP submission and IMAP retrieval. Use each protocol for its documented purpose rather than assuming identical operations or authority.
How do I avoid large payloads when querying a mailbox API?
Use count endpoints to check how many messages match a filter and search-snippet endpoints for previews, pulling full message bodies only when you actually need them.