Email Deliverability: MailParse vs Mailgun Inbound Routing

Compare MailParse and Mailgun Inbound Routing for Email Deliverability. Features, performance, and developer experience.

Why email deliverability for inbound email parsing matters

Inbound email is often the front door for support, approvals, CI notifications, and automated workflows. If your platform cannot reliably accept and process messages, everything upstream breaks. When teams compare MailParse with Mailgun Inbound Routing, they are really asking which service safeguards email-deliverability end to end - from DNS and MX routing to webhook or polling delivery - and how quickly issues can be detected and remediated.

Unlike outbound sending, inbound email-deliverability lives or dies on a different set of controls: correctly configured MX records, resilient SMTP edges, acceptance policies that avoid false positives, robust parsing for malformed MIME, and a delivery pipeline to your app that tolerates network issues without losing messages. The right approach combines predictable DNS, rigorous SMTP handling, authenticated delivery to your application, and monitoring that surfaces problems before customers notice.

Before you choose a provider, audit your stack with a focused checklist. Start with the Email Deliverability Checklist for SaaS Platforms and the Email Infrastructure Checklist for SaaS Platforms. These guides outline the exact DNS records, monitoring, and operational practices that keep inbound pipelines reliable under real-world load.

How MailParse handles email deliverability

This platform is purpose-built for receiving email at scale and getting structured data to developers quickly. It prioritizes reliability at each hop: DNS, SMTP acceptance, MIME parsing, and downstream delivery.

DNS and MX configuration

  • Per-tenant MX hostnames with at least two targets and distinct priorities for failover, typically one primary and one backup located in separate availability zones or regions.
  • Clear guidance to set low TTLs (for example, 300 seconds) so MX changes propagate quickly during incidents.
  • Validation tooling that confirms your domain's MX records, flags CNAME pitfalls, and detects stale delegation.

SMTP acceptance and authentication capture

  • Opportunistic TLS for inbound sessions with modern cipher policies and downgrade-safe behavior when senders cannot negotiate TLS.
  • Support for SMTPUTF8 and 8BITMIME to preserve non-ASCII addresses and headers.
  • Full Authentication-Results preservation: SPF, DKIM, DMARC verdicts and ARC sets are captured and included in structured JSON so your application can make policy decisions.
  • Pragmatic anti-abuse filtering that rejects obvious spam traps without discarding legitimate transactional mail. Messages that are rejected are logged with SMTP codes and reasons.

Parsing and canonical JSON

  • Strict RFC-compliant MIME parsing that tolerates real-world quirks: boundary mismatches, duplicate headers, and malformed content types.
  • Attachments are streamed, hashed, and size-limited with configurable caps and per-attachment metadata.
  • Canonical JSON schema for every message: envelope, headers, plaintext, HTML, attachments, authentication results, and a stable event identifier for idempotency.

Delivery to your application

  • Two delivery modes to maximize reliability: webhooks for push, plus a REST polling API that buffers events so you can recover from downstream outages.
  • HMAC-signed webhooks with timestamped headers to prevent replay. Signatures are calculated over the raw request body, and the cryptographic key is per-tenant.
  • Idempotency through a stable message identifier so your handler can safely deduplicate across retries.
  • Exponential backoff and jitter for 5xx or timeout responses, continued for a configurable window, followed by a dead-letter queue with replay controls.
  • Rich observability: acceptance logs, webhook attempt histories, and per-domain dashboards that surface MX misconfiguration, elevated 4xx rates, and parsing anomalies.

For teams that want practical guidance and patterns, see Top Inbound Email Processing Ideas for SaaS Platforms. It covers production-ready flows for moderation queues, ticketing, and workflow triggers.

How Mailgun Inbound Routing handles email deliverability

Mailgun Inbound Routing is a mature feature within Mailgun's platform that accepts messages for your verified domains and invokes routes to forward, store, or process those messages.

DNS and MX setup

  • You point your domain's MX records to Mailgun's MX hosts for the chosen region. Mailgun publishes multiple MX targets for resilience.
  • Standard guidance is to keep TTLs reasonably low and verify that your MX records prefer the highest priority host. Regional selection must match the domain's residency.

Inbound routing and payloads

  • Routes are evaluated against conditions like recipient or catch-all. Actions can forward to a URL, store and notify, or stop processing.
  • HTTP POST payloads are typically form-encoded and include fields such as sender, from, recipient, subject, body-plain, body-html, timestamp, token, and signature. Attachments are provided as files or via storage URLs.
  • Spam detection uses SpamAssassin-derived scoring with fields like spam and spam-score that you can use for filtering.

Security and delivery

  • Webhook signatures are HMAC-SHA256 computed from the concatenation of timestamp and token using your API key. Verification on your side is straightforward.
  • Mailgun retries failed route invocations. Developers have reported variability in retry behavior under heavy load, so it is prudent to build idempotent handlers and consider Store and Fetch when you need deterministic recovery.
  • Mail size limits are enforced, and large attachments may be stored for retrieval rather than forwarded inline.

If you already use Mailgun for outbound sending, consolidating inbound under the same vendor can simplify account management. Keep in mind that teams operating at high concurrency sometimes observe inconsistent webhook timing, so monitoring and fallback paths are essential.

Side-by-side comparison of email-deliverability features

Capability MailParse Mailgun Inbound Routing
MX setup and validation Per-tenant MX with automated validation and low-TTL guidance Provider MX with standard guidance, manual validation
Redundant MX targets across zones or regions Yes, separate priorities and failure domains Yes, multi-target MX
TLS for inbound SMTP Opportunistic TLS with modern ciphers Opportunistic TLS
Authentication results included in payload SPF, DKIM, DMARC, ARC captured in JSON Spam score fields, headers available; authentication details vary
Canonical JSON schema for MIME Yes, stable schema and attachment metadata Form-encoded fields with optional stored raw message
Webhook signing HMAC over raw body with timestamped headers HMAC using timestamp + token
Retry strategy for failed webhooks Exponential backoff with jitter, dead-letter and replay Retries supported, timing can vary under load
Pull-based recovery REST polling API with cursor-based pagination Store and Fetch option for raw messages
Idempotency key for deduplication Stable message ID in headers and body Derive from Message-Id or payload; not guaranteed stable across retries
Observability and per-domain dashboards Acceptance logs, webhook attempts, MX health Logs and events available in dashboard
Cost at scale for heavy inbound volumes Predictable pricing for high webhook throughput Can become expensive at scale

Code examples: verifying and delivering inbound messages

Webhook verification and idempotent handling with a push pipeline

Example in Node.js that verifies an HMAC-signed webhook, enforces a 5-minute timestamp window to prevent replay, and ensures idempotency via a stable event ID:

// Node.js (Express)
const crypto = require('crypto');
const express = require('express');
const app = express();

app.use(express.raw({ type: '*/*', limit: '25mb' })); // verify signature over raw body

// Your secret and tolerance window
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
const MAX_SKEW_MS = 5 * 60 * 1000;

function verifySignature(req) {
  const ts = req.header('X-Timestamp');
  const sig = req.header('X-Signature');
  if (!ts || !sig) return false;

  const now = Date.now();
  const skew = Math.abs(now - Number(ts));
  if (skew > MAX_SKEW_MS) return false;

  const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
  hmac.update(req.body); // raw bytes
  const digest = 'sha256=' + hmac.digest('hex');
  return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(sig));
}

const seen = new Set(); // replace with durable store

app.post('/inbound-webhook', (req, res) => {
  if (!verifySignature(req)) return res.status(401).send('bad signature');

  const eventId = req.header('X-Event-Id'); // stable per message
  if (seen.has(eventId)) return res.status(200).send('duplicate');
  seen.add(eventId);

  const json = JSON.parse(req.body.toString('utf8'));
  // Process json.envelope, json.headers, json.text, json.html, json.attachments...
  // Acknowledge quickly, then do heavy work asynchronously
  res.status(200).send('ok');

  // queueWork(json);
});

app.listen(3000);

Polling fallback to ensure recovery during outages

If your webhook endpoint is down, use a cursor-based poller to fetch and acknowledge pending events. Fetch small batches frequently to minimize latency:

# Bash + curl
API_TOKEN="$INBOUND_API_TOKEN"
CURSOR=""

while true; do
  RESP=$(curl -sS -H "Authorization: Bearer $API_TOKEN" \
              "https://api.example.com/inbound/events?cursor=$CURSOR&limit=50")
  echo "$RESP" | jq -r '.events[] | .id + " " + .subject'
  # acknowledge processed IDs
  IDS=$(echo "$RESP" | jq -r '.events[].id' | paste -sd, -)
  if [ -n "$IDS" ]; then
    curl -sS -X POST -H "Authorization: Bearer $API_TOKEN" \
         -H "Content-Type: application/json" \
         -d "{\"ack\":[\"${IDS//,/\\",\"}\"]}" \
         https://api.example.com/inbound/ack
  fi
  CURSOR=$(echo "$RESP" | jq -r '.nextCursor')
  sleep 2
done

Mailgun Inbound Routing signature verification

For Mailgun's inbound routes, verify signatures using the documented method: HMAC-SHA256 of timestamp + token with your API key. Here is a minimal Python example:

# Python 3
import hashlib
import hmac
import os
from flask import Flask, request, abort

app = Flask(__name__)
API_KEY = os.environ['MAILGUN_API_KEY'].encode()

def verify_mailgun(req):
    timestamp = req.form.get('timestamp', '')
    token = req.form.get('token', '')
    signature = req.form.get('signature', '')
    digest = hmac.new(API_KEY, (timestamp + token).encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(digest, signature)

@app.route('/mg-inbound', methods=['POST'])
def mg_inbound():
    if not verify_mailgun(request):
        abort(401)
    message_id = request.form.get('Message-Id') or request.form.get('message-id') or ''
    # Idempotency: use a durable store keyed by message_id or a hash of form fields
    # Process request.form['body-plain'], request.form['subject'], request.files for attachments...
    return 'ok', 200

if __name__ == '__main__':
    app.run(port=3000)

With Mailgun Inbound Routing, consider deriving a stable idempotency key from the Message-Id header and your domain. Store processed IDs to avoid duplicate work across retries.

Performance and reliability in real-world conditions

DNS resilience and failover

For high availability, use at least two MX records with different priorities and avoid using a CNAME as an MX target. Keep TTLs low so you can cut over during incidents. Test resolution from multiple resolvers and regions. Both platforms publish multiple MX targets, but your domain's configuration is what ultimately determines who accepts the mail during a failure.

Acceptance at the SMTP layer

Legitimate senders may retry with backoff if they encounter transient 4xx codes. Your provider should only emit 4xx when it can reasonably accept the message later and avoid triggering sender deferrals unnecessarily. False 5xx errors cause permanent bounces that your customers will see as failures. Watch 4xx and 5xx rates by domain and sender network to detect upstream problems. The service described earlier captures SMTP session outcomes and makes them visible in dashboards, which accelerates root-cause analysis.

Webhook variance and recovery strategies

Webhooks are fast but sensitive to your API's health and the provider's retry behavior. Teams have reported that Mailgun Inbound Routing may show inconsistent delivery schedules during spikes or regional events. The safest approach for critical workflows is to combine signed webhooks with a second-chance channel: either a built-in polling API or Mailgun's Store and Fetch. Always implement idempotency and return 2xx quickly to avoid unnecessary retries.

Parsing edge cases

Malformed MIME is common in the wild. Providers that normalize headers and maintain both plaintext and HTML variants reduce breakage in downstream processors. Ensure you test with:

  • Non-ASCII From/To with SMTPUTF8
  • Nested multiparts and inline attachments
  • Missing boundaries and duplicate headers
  • Large attachments near your configured cap

Run synthetic tests from consumer ISPs, marketing platforms, and automated systems. Measure acceptance latency, webhook latency, and end-to-end parse completeness. Tie your findings back to infrastructure improvements through the Email Infrastructure Checklist for Customer Support Teams if your primary use case is ticketing.

Verdict: which is better for email deliverability?

If email-deliverability for inbound workflows is your top priority, Mailgun Inbound Routing is dependable and well documented, especially if you already send through Mailgun. It supports regional MX records, HMAC-signed webhooks, and flexible routing. That said, teams that need deterministic recovery and deep observability will appreciate how MailParse combines signed push delivery, a resilient polling API, idempotency primitives, and dead-letter replay. Add the cost advantages for high-volume inbound traffic and it is a strong choice when reliability and long-term scale are critical.

In short: use Mailgun Inbound Routing if consolidation with your existing Mailgun stack outweighs the need for a pull-based safety net. Choose MailParse if you want a platform optimized for structured inbound parsing and bulletproof delivery into your app, with controls that make failures transparent and recoverable.

FAQ

What DNS records matter most for inbound email-deliverability?

The MX records on your domain control who accepts mail for your domain. Publish at least two MX targets with distinct priorities, avoid CNAMEs as MX targets, and keep TTLs low so you can change routing quickly during incidents. SPF and DKIM are outbound technologies, but inbound providers should capture their results for your application logic.

How should I design my webhook handler for reliability?

Verify HMAC signatures, enforce a short timestamp window to prevent replay, and acknowledge quickly with a 2xx response. Make the handler idempotent by using a stable event ID or Message-Id. Defer heavy work to background jobs and rely on retries or a polling fallback for recovery.

How do I monitor inbound pipelines in production?

Continuously send synthetic test messages from multiple networks and providers. Track acceptance latency, 4xx and 5xx rates, webhook success rates, and the number of pending or dead-lettered events. Alert on MX misconfiguration, elevated parse errors, and unusually large attachments.

When should I prefer polling over webhooks?

Webhooks minimize latency and are great for steady-state operations. Polling is a safety net when your API is down, you are rate limited, or you need to reprocess events deterministically. The best practice is to enable both and switch to polling during incidents or maintenance windows.

Does spam filtering affect deliverability for legitimate automation?

Yes. Overly aggressive filtering can reject legitimate alerts and replies. Tune thresholds, whitelist expected senders, and log every rejection with the SMTP code and reason. Review false positives regularly and adjust policies accordingly.

Ready to get started?

Start parsing inbound emails with MailParse today.

Get Started Free