All posts
    Guides

    How to Receive Email Programmatically with an API

    The Devmailr Team6 min read

    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:

    1. Create an address (or use a catch-all).
    2. Mail arrives; the service receives, parses, and stores it.
    3. You read it as JSON — subject, from, text, html, attachments, already parsed.

    1. Create an address

    javascript
    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:

    javascript
    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:

    javascript
    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:

    json
    {
      "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.