Introduction: Why email deliverability matters for inbound parsing
Email deliverability is not only about getting messages into an inbox. When your product relies on inbound email parsing, deliverability decides whether a support request, a billing approval, or an automated workflow even reaches your application. Missed messages become lost tickets, stalled approvals, or silent failures that are hard to diagnose. The goal is simple: ensure reliable email receipt, convert MIME to structured JSON, and deliver it to your app consistently, with strong signal when anything degrades.
Two popular approaches stand out for developer teams evaluating inbound pipelines: a platform that offers both webhook and REST polling delivery, and Postmark Inbound, which focuses on a single inbound webhook. This article compares the email-deliverability capabilities of each, with practical guidance on DNS configuration, monitoring, and resilient ingestion pipelines. If you are building on a SaaS stack, you may also find this Email Deliverability Checklist for SaaS Platforms helpful for a broader review.
How MailParse handles email deliverability
MailParse is designed to ensure that messages are received, parsed, and delivered to your application with at-least-once guarantees, even if your webhook is briefly unavailable. The platform terminates SMTP with redundant MTAs, validates the recipient address, and parses MIME into normalized JSON. From there, you choose how to consume events:
- Webhook delivery for low-latency ingestion with signed requests and retries.
- REST polling for pull-based consumption, ideal when you need strict control, can not expose a public webhook, or want a safety net during deployments.
Key deliverability mechanisms include:
- MX setup validation - the dashboard inspects DNS for common mistakes such as incorrect priority ordering, missing fallback MX, unsuitable TTL, or missing subdomain scoping.
- Inbound TLS - inbound SMTP supports modern TLS, which improves acceptance and reduces reputation issues with sending MTAs.
- Retained messages - if the webhook is down, messages remain available via REST polling for a defined retention window, with idempotency keys so you can safely reprocess.
- Webhook signing - HMAC signatures on every request with timestamped headers, so you can reject forged payloads.
- Replay controls - you can re-deliver specific messages to a webhook or fetch-by-cursor through REST if you need to rebuild state.
In practice, this means you can roll deploys without fear. If your webhook endpoint cold-starts or briefly returns 500, you poll and catch up. You also get a clear signal when DNS is misconfigured. For implementation checklists that complement this model, see the Email Infrastructure Checklist for SaaS Platforms.
How Postmark Inbound handles email deliverability
Postmark Inbound focuses on a single, reliable inbound webhook. You configure an inbound domain with MX records pointing to Postmark's infrastructure, and Postmark delivers parsed JSON to your endpoint. The payload includes sender and recipient details, subject, text and HTML bodies, and attachments metadata. It is straightforward, easy to set up, and well-documented.
Postmark Inbound provides HTTP retries with backoff when your endpoint is unavailable. This works well for most workloads that can rely solely on webhooks. However, there is no REST polling option to fetch missed payloads, no cursor-based retrieval, and no native replay mechanism you can initiate on demand. You can roll your own message queue downstream of your webhook, but that adds more moving parts on day one.
The tradeoff is simplicity versus control. If your webhook is online and stable, postmark-inbound delivers promptly. If your service is redeploying, or a regional network blip occurs, you are relying on Postmark's retry window to catch up. Many teams are comfortable with this model, but others prefer a pull-based safety net for critical workflows.
Side-by-side comparison of email-deliverability features
| Capability | MailParse | Postmark Inbound |
|---|---|---|
| Inbound delivery modes | Webhook and REST polling | Webhook only |
| MX configuration assistance | Dashboard validation and guidance | Documentation-based guidance |
| Retry behavior | Webhook retries, plus persistent queue for polling | Webhook retries with backoff |
| Message retention for recovery | Retained for a defined window, accessible via REST | Not available via REST |
| Replay on demand | Redeliver to webhook or fetch-by-cursor | Not supported natively |
| Webhook signing | HMAC signature with timestamp header | HMAC signature via X-Postmark-Signature |
| Idempotency controls | Idempotency keys exposed in events | Implement at your application layer |
| Attachment handling | Size limits and metadata in JSON, streaming download | Size limits and metadata in JSON |
| Monitoring signals | DNS checks, webhook failures, queue depth, lag | Webhook failure logs, retry status |
| Regional redundancy | Redundant MX and processing nodes | Redundant inbound infrastructure |
| Security posture | TLS for inbound SMTP, signed webhooks, role-scoped API keys | Signed webhooks, secure inbound endpoints |
| Typical fit | Critical workflows that need a pull-based safety net | Teams comfortable with webhook-only ingestion |
Code examples: implementing resilient inbound delivery
1) DNS: configure MX records correctly
Use a subdomain dedicated to inbound parsing, keep TTL reasonable, and include a fallback MX target. Avoid mixing with user-facing inbox domains to reduce risk.
; Subdomain for inbound parsing
inbound.example.com. 3600 IN MX 10 mx1.provider.example.
inbound.example.com. 3600 IN MX 20 mx2.provider.example.
; Postmark Inbound example
inbound.example.com. 3600 IN MX 10 inbound.postmarkapp.com.
Double check that the MX targets resolve to A or AAAA records, not CNAMEs. Verify with dig or nslookup before enabling production traffic.
2) Webhook verification and idempotency
Always verify signatures, de-duplicate by message ID, and acknowledge quickly. Process the payload asynchronously after storing it, so the sender does not time out and retry unnecessarily.
// Node.js Express - generic HMAC verification pattern
import crypto from 'crypto';
import express from 'express';
const app = express();
app.use(express.raw({ type: 'application/json' })); // preserve raw body
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
function verifySignature(req) {
const sigHeader = req.get('X-Webhook-Signature'); // or provider-specific header
const ts = req.get('X-Webhook-Timestamp');
const body = req.body; // Buffer
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
hmac.update(ts);
hmac.update('.');
hmac.update(body);
const expected = hmac.digest('hex');
return crypto.timingSafeEqual(Buffer.from(sigHeader, 'hex'), Buffer.from(expected, 'hex'));
}
app.post('/inbound', (req, res) => {
try {
if (!verifySignature(req)) {
return res.status(401).send('invalid signature');
}
const event = JSON.parse(req.body.toString('utf8'));
// Deduplicate by provider message id
// e.g. store event.id in a key-value store before enqueueing
enqueueForProcessing(event);
res.status(200).send('ok');
} catch (e) {
res.status(400).send('bad payload');
}
});
app.listen(3000);
3) Postmark Inbound signature verification
Postmark's inbound webhook provides an HMAC signature in the X-Postmark-Signature header. Validate it using your inbound webhook token.
// Node.js - verifying X-Postmark-Signature
import crypto from 'crypto';
import express from 'express';
const app = express();
app.use(express.raw({ type: 'application/json' }));
const POSTMARK_TOKEN = process.env.POSTMARK_WEBHOOK_TOKEN;
function verifyPostmark(req) {
const signature = req.get('X-Postmark-Signature');
const computed = crypto.createHmac('sha256', POSTMARK_TOKEN)
.update(req.body)
.digest('base64');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(computed));
}
app.post('/postmark-inbound', (req, res) => {
if (!verifyPostmark(req)) return res.status(401).send('invalid signature');
const event = JSON.parse(req.body.toString('utf8'));
// Store, dedupe by event.MessageID, then process asynchronously
res.status(200).send('ok');
});
app.listen(3001);
4) Pull-based recovery via REST polling
A pull model lets you recover during redeploys or outages, and it enables batch ingestion for heavy processing windows. Poll with cursors or timestamps, acknowledge processed messages, and apply exponential backoff on 204 responses.
# Example shell pseudo-commands for polling
# 1) Fetch a page of messages newer than a cursor
curl -sS -H "Authorization: Bearer $API_KEY" \
"https://api.provider.example/v1/inbound?cursor=$CURSOR&limit=100" > batch.json
# 2) Process each message and ack by id to advance the cursor
jq -r '.messages[].id' batch.json | while read id; do
process_message "$id"
curl -sS -X POST -H "Authorization: Bearer $API_KEY" \
-d "{\"status\":\"ack\"}" \
"https://api.provider.example/v1/inbound/$id/ack"
done
# 3) Save returned next_cursor for the next poll
export CURSOR=$(jq -r '.next_cursor' batch.json)
This pattern ensures you never lose messages if a webhook is temporarily unavailable. It is also friendlier to large attachments and bursty traffic, since you control concurrency and back pressure.
Performance and reliability in real-world conditions
Inbound pipelines experience all the usual edge cases: large attachments, delayed remote MTAs, forwarded messages with odd encodings, and brief downstream downtime during deploys. A resilient setup includes:
- Redundant MX with correct priorities, so if one ingress path is under maintenance, senders still connect.
- Immediate 2xx from your webhook after durable storage, so retries do not stack up.
- Idempotent processing keyed by message ID, so replays and retries are safe.
- REST polling fallback so you can catch up after a partial outage or a rate-limited webhook.
- Alerting on increased 4xx or 5xx at your webhook, increased queue depth, and parse failures on malformed MIME.
With a webhook-only system like Postmark Inbound, your primary lever is lowering endpoint error rates and tightening deploy procedures. With a dual-mode system, you can also pause webhooks during deploys, process via polling, then resume. For more implementation ideas, see Top Inbound Email Processing Ideas for SaaS Platforms.
Verdict: which is better for email deliverability?
Both options accept inbound email reliably and provide clear JSON payloads. If your team prefers a single push-based integration, Postmark Inbound is battle tested and easy to adopt. If your application handles time-sensitive support tickets, financial approvals, or compliance workflows where missed messages are unacceptable, MailParse offers stronger guarantees for email-deliverability through its combination of webhook, polling, replay, and retention. The ability to pull and recover on your schedule is the differentiator that reduces operational risk the most.
FAQ
What DNS records affect inbound email deliverability?
MX records decide where mail is delivered. Use a dedicated subdomain with at least two MX targets and correct priorities. Keep TTL moderate so you can change providers quickly. SPF, DKIM, and DMARC primarily affect sender authentication, but correct alignment reduces filtering by intermediate systems when mail is forwarded into your inbound pipeline.
How do I prevent webhook retries from causing duplicates?
Validate signatures, store the payload durably, and de-duplicate by a unique message identifier. Acknowledge the webhook quickly, then process asynchronously. If your provider exposes idempotency keys or stable message IDs, index them in a key-value store to ensure exactly-once effects in your application.
Can I survive deployments without dropping inbound messages?
Yes. Pause your public webhook during deploys, or serve a lightweight 200 after durable storage. Use a polling endpoint to catch up on messages accumulated during the deploy. If you use Postmark's inbound-only webhook, reduce deployment time and use blue-green or canary patterns to keep the endpoint healthy.
How should I monitor email-deliverability for inbound processing?
Track 4xx and 5xx rates at your webhook, queue depth for pending messages, parse failure rates, and end-to-end latency from SMTP receipt to application ack. Add DNS monitors for MX health and certificate checks for inbound TLS. Alerts on sudden drops in volume can also surface upstream DNS or routing issues.
What about large attachments and timeouts?
Use asynchronous processing with streamed storage for large attachments. Return a 2xx quickly to avoid retries, then process attachments out of band. For webhook-only systems, increase server timeouts and memory limits judiciously. A polling workflow gives you greater control over concurrency and prevents timeouts during spikes.