How to Receive Emails in Your App

A practical guide to receiving and processing incoming emails in your application. Learn the different approaches and find the simplest solution.

Mailhooks TeamJanuary 26, 20255 min read
tutorialemailwebhooksapi

Your app can send emails easily — every framework has libraries for that. But what about receiving emails? That's where things get complicated.

Maybe you want to:

  • Let users reply to notifications by email
  • Build a support ticketing system
  • Parse incoming invoices or receipts
  • Create an email-based workflow automation

Whatever your use case, you'll need to solve the inbound email problem.

The Three Approaches

1. Run Your Own Mail Server

The DIY approach. You set up Postfix, Haraka, or similar, configure MX records, handle SMTP connections, parse MIME messages, deal with spam filtering...

Pros:

  • Full control
  • No per-email costs

Cons:

  • Massive maintenance burden
  • Security responsibility (mail servers are attack targets)
  • Deliverability reputation to manage
  • IP warming, blacklist monitoring, etc.

Unless you're building an email company, this is overkill.

2. Poll via IMAP

Connect to an IMAP server (Gmail, Outlook, or your own) and periodically fetch new messages.

// Pseudo-code: IMAP polling
const imap = new ImapClient(config)
setInterval(async () => {
  const messages = await imap.fetch('INBOX', { since: lastCheck })
  for (const msg of messages) {
    await processEmail(msg)
  }
}, 60000) // Check every minute

Pros:

  • Works with existing email accounts
  • No infrastructure changes

Cons:

  • Polling means delays (1-5 minute latency typical)
  • Connection management headaches
  • Rate limits on providers like Gmail
  • Doesn't scale well with high volume

Good for low-volume, non-time-sensitive use cases.

3. Email to Webhook

The modern approach: emails arrive, get converted to HTTP requests, and hit your webhook endpoint instantly.

// Your webhook handler
app.post('/webhook/email', (req, res) => {
  const { from, subject, body, attachments } = req.body
  
  // Process immediately - no polling!
  await createTicket({ from, subject, body })
  
  res.status(200).send('OK')
})

Pros:

  • Real-time (sub-second delivery)
  • No infrastructure to manage
  • Just HTTP — works with any stack
  • Attachments included in payload

Cons:

  • Requires a service provider
  • Per-email costs (usually minimal)

This is what most production apps should use.

How Email-to-Webhook Works

  1. You get a receiving address — like [email protected] or a custom domain
  2. Emails arrive at that address
  3. The service parses the email — extracts from, to, subject, body (text + HTML), attachments
  4. Your webhook gets called with a clean JSON payload
  5. You process it — create ticket, trigger workflow, whatever you need

No mail servers. No IMAP connections. Just HTTP.

Example: Support Ticket System

Let's say you're building a support system. Here's the complete flow:

1. Set up your webhook endpoint

// Express.js example
app.post('/webhooks/support-email', async (req, res) => {
  const {
    from,          // "[email protected]"
    fromName,      // "Jane Customer"
    subject,       // "Re: Order #12345"
    text,          // Plain text body
    html,          // HTML body (if sent)
    attachments,   // Array of { filename, contentType, content }
    messageId,     // For threading
    inReplyTo,     // If this is a reply
  } = req.body

  // Find existing ticket or create new one
  const ticket = await findOrCreateTicket({
    email: from,
    subject: subject.replace(/^Re:\s*/i, ''),
  })

  // Add the message
  await ticket.addMessage({
    from: fromName || from,
    body: text || stripHtml(html),
    attachments,
  })

  // Notify your team
  await notifySlack(`New message on ticket #${ticket.id}`)

  res.status(200).json({ received: true })
})

2. Configure your receiving address

With Mailhooks, you'd create an address like [email protected] or use your own domain ([email protected]) and point it to our servers.

3. That's it

Emails to your support address now create tickets automatically. No cron jobs, no polling, no mail server maintenance.

Why Not Just Use SendGrid/Mailgun?

You can! Both offer inbound email parsing. But:

  • SendGrid Inbound Parse — works, but configuration is clunky and the payload format hasn't been updated in years
  • Mailgun Routes — solid, but you're locked into their ecosystem

Mailhooks is purpose-built for receiving email. It's our entire focus, not an afterthought feature on a sending platform.

Getting Started

  1. Sign up at mailhooks.dev
  2. Create your first hook — pick an address, set your webhook URL
  3. Send a test email — see the payload in your logs
  4. Build your integration — usually takes less than an hour

Your webhook receives clean, parsed JSON. No MIME parsing, no charset headaches, no attachment encoding issues. Just data you can use.

Use Our SDK

For an even smoother experience, use our official Node.js SDK:

npm install @mailhooks/sdk
import { Mailhooks } from '@mailhooks/sdk'

const mailhooks = new Mailhooks({ apiKey: process.env.MAILHOOKS_API_KEY })

// List recent emails
const emails = await mailhooks.emails.list({ limit: 10 })

// Get a specific email
const email = await mailhooks.emails.get('email_123')

// Access parsed data
console.log(email.from, email.subject, email.text)

The SDK handles authentication, pagination, and gives you full TypeScript support. Check it out on npm.

Realtime with Server-Sent Events

Need to react to emails instantly without setting up webhooks? Use our SSE stream:

import { Mailhooks } from '@mailhooks/sdk'

const mailhooks = new Mailhooks({ apiKey: process.env.MAILHOOKS_API_KEY })

// Subscribe to realtime email events
const stream = mailhooks.emails.stream()

stream.on('email', (email) => {
  console.log('New email received:', email.subject)
  // Process immediately — no polling, no webhooks to configure
})

stream.on('error', (err) => console.error('Stream error:', err))

SSE is perfect for:

  • E2E testing — wait for verification emails in your test suite
  • Development — see emails arrive in real-time while building
  • Simple integrations — when you don't want to expose a webhook endpoint

Have questions? Check out our documentation or reach out — we're happy to help you get set up.

Ready to receive emails in your app?

Get started with Mailhooks in minutes. No credit card required.