Inbound and inboxes
Receive email with Amazon SES in your own AWS account, read it through Resend's received-email API, and run inboxes with threads, replies, drafts and agent keys.
SES receives the mail, your S3 bucket stores it, and Stamp0 parses, threads and indexes it. Message bodies and attachments never leave your account: the API reads them from your bucket when you ask, and download links are presigned for one hour at most.
Turn on receiving
Receiving needs three things, and the domain's receiving.setup tells you which are missing:
- The domain: set
capabilities.receivingtoenabled(when you add it, or later withPATCH /domains/:id). The DNS records then include the apexMXto SES's inbound endpoint for your region. - The stack: the domain (or the address) is in your connection stack's
InboundRecipients, withEnableInbound=true.receiving.setupgives the exact stack update, with a console link and an AWS CLI command. - The rule set: the Stamp0 receipt rule is in your account's active rule set. See Receiving mail.
Once all three hold, receiving.status is enabled. Each message is stored in your bucket as raw MIME, EventBridge tells Stamp0, and Stamp0 parses it and sends an email.received webhook.
Received emails
GET /emails/receiving lists received mail with Resend's shape, plus SES's spam and virus verdicts and the inboxes it reached: inbox_ids lists every inbox the message was routed to, and inbox_id (kept for compatibility) is the first of them. GET /emails/receiving/:id returns the html, text and headers parsed from the raw message, and raw.download_url for the original .eml. Attachments are listed at /emails/receiving/:id/attachments, each with a presigned download URL.
const { data } = await stamp0.emails.receiving.get('rcv_…');Inboxes
An inbox is an address on a project domain, such as support@acme.co. Mail to it is grouped into threads by Message-ID, In-Reply-To and References, so a customer's reply to an email you sent lands in the same thread.
curl https://api.stamp0.com/inboxes \
-H "Authorization: Bearer $STAMP0_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Support", "address": "support", "domain_id": "dom_…" }'address is a local part (support) or a full address on the domain. agent_settings is a free-form object for whatever your agent needs to know about the inbox.
Every inbox has a status: active, or activating for the first five minutes of an inbox on a Cloudflare receiving domain. Cloudflare takes one to three minutes to propagate the inbox's Email Routing rule, and mail sent to the address meanwhile is refused (550 5.1.1). A bounce from your own inbox or receiving domain is recorded on the email, but Stamp0 never suppresses the address.
Threads and messages
GET /inboxes/:id/threadslists threads by latest activity. Filter withquery(subject or a participant),label,status(openorclosed) andunread.GET /inboxes/:id/threads/:threadIdreturns the thread with its messages;…/messagespages through them. Each message has astatus:receivedfor inbound mail, and the email'slast_eventfor mail you sent, so a reply thatfailedor wassuppressedsays so. Such messages stay in the thread but are not part ofmessage_count;failed_message_countcounts them.PATCH /inboxes/:id/threads/:threadIdcloses or reopens a thread, sets labels (labels,add_labels,remove_labels; lowercase tokens such asbillingorneeds:reply) and marks it read.GET /inboxes/:id/messages/:messageIdreturns one message with its bodies, read from your bucket. Messages havedirectioninboundoroutbound.
Replying
POST /inboxes/:id/threads/:threadId/reply answers the latest message of the thread, or the one in message_id. It goes to that message's Reply-To (or From), never to the inbox itself; reply_all copies the other recipients. The subject becomes Re: …, and In-Reply-To and References are set so the reply threads in the recipient's mail client.
{ "text": "Refund issued. It should appear in 3–5 days.", "reply_all": false }To start a new conversation, POST /inboxes/:id/messages with to, subject and html or text; with a thread_id the same endpoint replies in that thread. Mail is sent from the inbox address, through the domain's SES configuration, and suppressed recipients are left out.
Drafts
/inboxes/:id/drafts holds replies that are not ready, for example an agent's proposal waiting for a human. Create, edit and delete them, then POST /inboxes/:id/drafts/:draftId/send. Sending deletes the draft in the same step, so it goes out once.
Agent keys
An agent key is an API key bound to one inbox. Create one with POST /api-keys:
{ "name": "Support agent", "permission": "sending_access", "inbox_id": "ibx_…" }It can read that inbox's threads, messages, drafts and received mail, and send only from the inbox address. Any other inbox answers 404, and it cannot create, change or delete inboxes. Use it for an AI assistant that answers support mail, directly or through the MCP server.
Receiving on Cloudflare
On a domain whose receiving connection is a Cloudflare connection, Cloudflare Email Routing receives the mail and Stamp0's Worker in your account stores it in your R2 bucket; nothing passes through Stamp0's servers until Stamp0 reads it from your bucket. Turn it on with receiving_connection_id and receiving: { "enabled": true } plus a setup token (POST /domains or PATCH /domains/:id). On a subdomain only addresses with an inbox receive mail: creating an inbox adds its Email Routing rule and deleting it removes the rule (at most 200 per zone); apex_catch_all receives every address on the zone apex. Messages may be up to 25 MiB, and there is no virus verdict. How Stamp0 authenticates this mail without a provider-signed notification is described under Security.
Reference: Inboxes API, List received emails.
Send email
Send transactional email through Amazon SES with the Resend API, single or batch, with scheduling, tags, attachments, idempotency keys and delivery statuses.
Webhooks
Receive delivery, bounce, complaint, engagement, inbound, domain and unsubscribe events as signed Standard Webhooks, and verify the signature in Node.js or any language.