How to Receive Email Programmatically with an API
For years, “receiving email in your app” meant running an SMTP server, wrangling MX records, and parsing MIME by hand. You don’t have to anymore. This guide shows how to receive and parse inbound email over a plain REST API — create an address, get the message as JSON, done.
The old way (and why it hurts)
Traditionally, to receive mail programmatically you’d register a domain, set MX records, run an SMTP server, handle TLS, parse raw MIME into something usable, store it, and fend off spam. That’s real ops work for what’s usually a simple need: “tell me when an email arrives and give me its contents.”
The API way
A hosted inbound-email service does all of that for you and hands you a clean HTTP interface:
- Create an address (or use a catch-all).
- Mail arrives; the service receives, parses, and stores it.
- You read it as JSON — subject, from, text, html, attachments, already parsed.
1. Create an address
const BASE = 'https://api.devmailr.app/api'
const headers = { Authorization: `Bearer ${process.env.DEVMAILR_API_KEY}` }
const res = await fetch(`${BASE}/mailboxes`, {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify({ prefix: 'orders' }),
})
const inbox = await res.json() // { _id, address: 'orders@devmailr.app', ... }2. Read the mail as JSON
Two ways, depending on whether you want to wait. Check what’s there:
const list = await fetch(`${BASE}/mailboxes/${inbox._id}/emails`, { headers }).then((r) => r.json())
// [{ _id, from, to, subject, date, extractedCodes, ... }]…or block until one arrives, with no polling loop:
const email = await fetch(`${BASE}/mailboxes/${inbox._id}/wait?timeout=60`, { headers })
.then((r) => r.json())What you get back
Each email is already parsed — no MIME wrangling:
{
"from": "noreply@stripe.com",
"subject": "Your receipt",
"bodyText": "Thanks for your payment...",
"bodyHtml": "<html>...</html>",
"attachments": [{ "filename": "receipt.pdf", "size": 20480, "contentType": "application/pdf" }],
"extractedCodes": ["482913"],
"primaryLink": "https://example.com/view",
"verdicts": { "spf": "PASS", "dkim": "PASS", "dmarc": "PASS" }
}Subject, sender, plain text, HTML, and attachment metadata are all there — plus extracted codes/links and SPF/DKIM/DMARC verdicts computed at receive time.
Getting it in real time
Polling and /wait cover most needs. For a push instead — without running a mail server — you have two options:
- Webhooks — register a URL and the service POSTs each email to it.
- Server-Sent Events — open one connection and receive emails as they arrive, no public URL needed. See receiving email without a webhook server.
Common uses
- Inbound parsing — turn replies or forwarded mail into structured data and actions.
- Testing — receive verification/OTP mail in automated tests.
- Integrations — capture mail a third party sends to a per-customer address.
Related reading
Try it in two minutes
Create a disposable prefix@devmailr.app inbox over the API, send mail to it from your app, and read it in your tests. Free plan, no card required.