Inbound email API
The api.email inbound email API receives mail for your domain and delivers every message to your app as a signed JSON webhook. No mail server, no IMAP polling, no MIME parsing: you get the sender, the bodies, the reply without the quoted thread and the attachments, ready to use.
- One MX record, then routes by address, domain or catch-all
reply_textwithout the quote, threaded to the email you sent- Attachments as download URLs, headers and SPF/DKIM/DMARC verdicts
- Signed requests, retried for up to 24 hours, replayable
{
"type": "email.received",
"id": "in_5d1e7a",
"from": "[email protected]",
"to": "[email protected]",
"subject": "Re: Your order #1042 shipped",
"reply_text": "Can I change the address?",
"in_reply_to": "em_8f2c1a",
"attachments": [],
"auth": { "spf": "pass", "dkim": "pass", "dmarc": "pass" }
}app.post("/hooks/inbound", express.raw({ type: "application/json" }), (req, res) => { if (!verify(req)) return res.sendStatus(400); const { from, reply_text, in_reply_to } = JSON.parse(req.body); tickets.addReply(in_reply_to, from, reply_text); res.sendStatus(200); });
@app.post("/hooks/inbound") def inbound(): raw = request.get_data() if not verify(raw, request.headers["api-email-signature"]): abort(400) event = json.loads(raw) tickets.add_reply(event["in_reply_to"], event["from"], event["reply_text"]) return "", 200
Receiving email in three steps
1. Add an MX record
Point a domain or subdomain such as in.acme.com at mx.api.email.
2. Create a route
Match an address or *@in.acme.com and choose the webhook URL it forwards to.
3. Handle the webhook
Verify the signature, answer 2xx quickly and process the message in the background.
What teams build with inbound email
Support inbox
Turn support@ into tickets with the sender, body and attachments.
Reply by email
Let users answer comments and notifications straight from their inbox.
Document intake
Receive invoices, receipts and forms by email and process the files.
End-to-end tests
Assert that signup emails, magic links and codes arrive in CI.
Notifications in
Accept alerts from systems that can only send email and route them to chat.
Agents with an inbox
Give an AI agent an address it can read and answer through the same API.
Receiving is included on every plan and counts like any other email. New to the idea? Readhow email to webhook works →
Receive email in your stack
Complete handlers with signature verification, threading and attachments.
Inbound email API questions
What is an inbound email API?
An inbound email API receives email for your domain and delivers each message to your application, parsed into JSON, through a webhook. You get the sender, subject, text and HTML bodies, the reply without the quoted thread, attachments and authentication results without running a mail server.
Do I need a mail server to receive email?
No. You add one MX record that points your receiving domain at mx.api.email. api.email accepts the mail, parses it and POSTs it to your webhook.
Can I receive email on my root domain?
Only if nothing else receives mail there. If your team already has mailboxes on acme.com, use a subdomain such as in.acme.com for inbound processing, so your own mail keeps flowing to your mail provider.
How are attachments delivered?
Each attachment is listed in the webhook with its filename, content type, size and a download URL. You fetch the file with your API key, which keeps webhook requests small even for large attachments.
How do I verify that a webhook came from api.email?
Every request carries an api-email-signature header with a timestamp and an HMAC-SHA256 signature of the raw body, keyed with the secret returned when you created the route. Recompute it, compare in constant time and reject old timestamps. Webhook signatures →