Receive & reply
Set up inbound email handling with webhooks, SSE streaming, or polling, and send automatic replies.
1. Create a webhook
curl -X POST https://api.robotomail.com/v1/webhooks \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/email",
"events": ["message.received"]
}'2. Handle the webhook
When an email arrives, Robotomail sends a POST request to your endpoint with the message data. Verify the signature before processing:
import crypto from "crypto";
app.post("/webhooks/email", (req, res) => {
// The signature is computed over the raw request body string, not parsed JSON
const rawBody = req.body; // use express.raw() or express.text() middleware
const signature = req.headers["x-robotomail-signature"];
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
if (signature !== expected) return res.status(401).send("Invalid signature");
const { event, timestamp, data } = JSON.parse(rawBody);
if (data.over_limit) {
// Account is over its monthly inbound cap. The payload omits body and
// attachments — only identity fields are present. The message is safely
// persisted; upgrading or the first-of-month reset unlocks it.
console.log(`[over-limit] message_id=${data.message_id} mailbox=${data.mailbox_id}`);
return res.status(200).send("OK");
}
console.log(`[${event}] from ${data.from}: ${data.subject} at ${timestamp}`);
res.status(200).send("OK");
});See 402 INBOUND_LIMIT_EXCEEDED for the full over-limit behavior across webhooks, SSE, and the REST API.
3. Send a reply
Reply to the inbound message by passing its messageId (the RFC 5322 Message-ID header value) in the inReplyTo field:
curl -X POST https://api.robotomail.com/v1/mailboxes/MAILBOX_ID/messages \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": ["sender@example.com"],
"subject": "Re: Their subject",
"bodyText": "Thanks for your email! Here is my reply.",
"inReplyTo": "<original-message-id@example.com>"
}'This automatically threads the reply with the original message.
Alternative: Polling or SSE
If you can't set up a webhook endpoint, you have two alternatives:
SSE streaming: Open a persistent connection to GET /v1/events for real-time events without a public URL. Use robotomail listen from the CLI, or connect directly. See the Events (SSE) API.
Polling: Poll for new messages using the since parameter:
curl "https://api.robotomail.com/v1/mailboxes/MAILBOX_ID/messages?direction=INBOUND&since=2026-03-11T00:00:00Z" \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY"