Mailgun to Webhook

Forward every Mailgun email to your endpoint as structured JSON — headers, body, and attachments included. No polling, no MIME parsing, no infrastructure to maintain.

Table of Contents
  1. Why Route Mailgun Emails to a Webhook?
  2. How to Forward Mailgun to JsonHook
  3. Mailgun vs Mailgun Routes
  4. JSON Payload Example
  5. Common Mailgun to Webhook Use Cases

Why Route Mailgun Emails to a Webhook?

Mailgun is a developer-focused email API service used for sending, receiving, and tracking transactional and notification emails. While Mailgun is a capable email platform, its native tooling for programmatic automation was not built for developers who need structured, reliable data delivery to backend systems.

The native approach — Mailgun Routes — introduces significant operational overhead. You need to manage credentials, poll or maintain persistent connections, and write custom parsing logic for every message field you care about. When your team is moving fast, that friction adds up to hours of maintenance per integration.

JsonHook eliminates that overhead by accepting inbound mail on your behalf and immediately firing a structured JSON payload to any HTTPS endpoint you specify. The email is parsed, attachments are base64-encoded, and headers are normalised — so your webhook handler can focus entirely on business logic rather than MIME parsing.

Below are the core benefits of routing your Mailgun messages through JsonHook instead of relying on the native alternative:

  • Limitation avoided: Mailgun Routes forward emails using multipart form-data encoding, not JSON — your endpoint must parse this format, which includes raw MIME fields and base64-encoded attachments in a non-standard structure.
  • Limitation avoided: Mailgun's inbound routes do not provide HMAC-signed payloads by default; verifying authenticity requires additional timestamp-based validation logic.
  • Limitation avoided: Mailgun Routes require the inbound domain to have MX records pointing to Mailgun's servers, which means you cannot receive mail at your primary sending domain without DNS changes.
  • Zero-polling architecture: JsonHook pushes to your endpoint the moment mail arrives — no long-running background jobs needed.
  • Automatic attachment handling: PDFs, images, and other file types are extracted, base64-encoded, and included in the JSON payload with their original MIME type.
  • Retry with exponential back-off: If your endpoint is temporarily unavailable, JsonHook retries automatically — something the Mailgun Routes does not do natively.
  • Webhook signatures for security: Every delivery includes an HMAC-SHA256 signature header so you can verify the payload originated from JsonHook.

Whether you are building a support-ticket ingestion pipeline, a lead-capture workflow, or an automated document processor, JsonHook gives you a consistent, typed interface to Mailgun messages without the fragility of raw SMTP or polling-based API integrations.

How to Forward Mailgun to JsonHook

Getting Mailgun emails delivered to your webhook takes about five minutes. The process has two parts: creating a JsonHook address via the API, and configuring Mailgun to forward a copy of each incoming message to that address.

  1. In the Mailgun dashboard, go to Sending › Domains and select your domain.
  2. Navigate to the Receiving tab and click Create Route.
  3. Set the expression to match the messages you want (e.g. match_recipient('.*@yourdomain.com')) and add the action Forward with your JsonHook inbound address as the destination.
  4. Alternatively, configure your application's reply-to header to point directly at your JsonHook inbound address, bypassing Mailgun Routes entirely and removing the need for inbound domain configuration.

Once forwarding is active, every email that arrives in your Mailgun inbox (or matches your filter) will be relayed to your JsonHook address, parsed, and delivered to your endpoint as a JSON payload within seconds.

You can create your JsonHook inbound address with a single curl command. Replace YOUR_API_KEY with the key from your dashboard and set webhookUrl to your endpoint:

curl -X POST https://jsonhook.com/api/addresses \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Mailgun inbound",
    "webhookUrl": "https://your-app.example.com/webhooks/email",
    "secret": "a-random-signing-secret"
  }'

The response includes your unique @in.jsonhook.com address. Copy that address and paste it into the forwarding field in your Mailgun settings. That is all the infrastructure you need to stand up.

Start Receiving Mailgun Webhooks in 5 Minutes

Free tier: 100 emails/month, 1 address. No credit card required.

Get Free API Key

Mailgun vs Mailgun Routes

When developers first explore email-to-webhook automation they typically discover Mailgun Routes — the official programmatic route provided by Mailgun by Sinch. The table below shows how it compares to using JsonHook as an intermediary.

Feature Mailgun Native (Mailgun Routes) JsonHook
Structured JSON payload
Attachment parsing
Retry logic
Webhook signatures
Setup time Hours to days Under 5 minutes

The native approach through Mailgun Routes requires you to set up OAuth credentials or API keys, maintain a long-running listener or polling job, write your own MIME parser, and implement your own retry queue. Any one of those steps can become a reliability bottleneck in production.

JsonHook handles all of that infrastructure on your behalf. You get a single HTTPS webhook call with a predictable JSON schema every time a Mailgun email arrives — no polling, no credential rotation, no MIME parsing, and no bespoke retry code to maintain.

JSON Payload Example

When a Mailgun email is forwarded to your JsonHook address and delivered to your endpoint, the request body looks like the following. All fields are consistently present; optional fields such as htmlBody and attachments are included when the source message contains them.

{
  "id": "msg_01j8xkr4p2vn3q7w",
  "receivedAt": "2026-03-15T14:32:07.412Z",
  "from": {
    "name": "Alice Smith",
    "address": "[email protected]"
  },
  "to": [
    {
      "name": "",
      "address": "[email protected]"
    }
  ],
  "subject": "Your Mailgun message subject here",
  "textBody": "Plain-text content of the email body.",
  "htmlBody": "<div>HTML version of the email body.</div>",
  "headers": {
    "message-id": "<[email protected]>",
    "x-mailer": "Mailgun by Sinch",
    "mime-version": "1.0"
  },
  "attachments": [
    {
      "filename": "document.pdf",
      "contentType": "application/pdf",
      "size": 84234,
      "content": "JVBERi0xLjQK..."
    }
  ],
  "spf": "pass",
  "dkim": "pass"
}

The id field is a unique, stable identifier you can use for idempotent processing. The spf and dkim fields reflect the authentication results JsonHook observed when receiving the message, which you can use to enforce additional trust policies in your handler.

Attachment content is standard base64. Decode it with a single call in any language — Buffer.from(att.content, 'base64') in Node.js, base64.b64decode(att.content) in Python, and so on.

Node.js handler for Mailgun emails forwarded through JsonHook:

import express from 'express';
import crypto from 'crypto';

const app = express();
app.use(express.json());

app.post('/webhooks/mailgun', (req, res) => {
  const sig = req.headers['x-jsonhook-signature'] as string;
  const body = JSON.stringify(req.body);
  const expected = crypto
    .createHmac('sha256', process.env.JSONHOOK_SECRET!)
    .update(body).digest('hex');
  if (sig !== expected) return res.status(401).send('Forbidden');

  const { from, to, subject, textBody } = req.body;
  // Route by recipient address for multi-tenant apps
  const recipient = Array.isArray(to) ? to[0].address : to.address;
  console.log(`Mailgun → ${recipient}: ${subject} (from ${from.address})`);
  res.sendStatus(200);
});

app.listen(3000);

Common Mailgun to Webhook Use Cases

Mailgun's Routes feature provides basic inbound email handling, but it uses a multipart form-data webhook format and requires MX record changes on a dedicated subdomain. JsonHook works as a drop-in complement or replacement for Mailgun Routes, offering a cleaner JSON schema and built-in retry logic.

  • Reply-to-ticket conversion: SaaS applications that send support emails via Mailgun can forward customer replies through JsonHook to automatically create or update help-desk tickets without touching the Mailgun Routes API.
  • Domain-specific inbox routing: Multi-tenant applications that assign each customer a dedicated email subdomain can forward all inbound messages to a single JsonHook webhook and route them internally based on the to address in the payload.
  • Event-driven billing alerts: Invoicing systems that deliver receipts via Mailgun can also receive payment confirmation emails at a Mailgun address and forward them to a webhook that reconciles payment records automatically.
  • A/B test reply analysis: Marketing teams running A/B email campaigns through Mailgun can forward reply emails to a webhook for sentiment analysis and engagement scoring.

Frequently Asked Questions

Can I forward Mailgun emails to a webhook?
Yes. Mailgun supports email forwarding rules that let you relay a copy of any incoming message to an external address. By forwarding to your JsonHook @in.jsonhook.com address, those messages are immediately parsed and delivered as a JSON POST to your webhook endpoint — no polling required.
Does JsonHook parse Mailgun attachments?
Yes. Every attachment in a forwarded Mailgun message is extracted from the MIME envelope, base64-encoded, and included in the attachments array of the JSON payload. Each entry contains the original filename, MIME content type, file size in bytes, and the base64-encoded content string. You can decode it with a single line in any language.
How fast does Mailgun forwarding work?
End-to-end delivery is near real-time. Once Mailgun forwards the message to your JsonHook inbound address, JsonHook parses and dispatches the webhook within a few seconds. The main variable is how quickly Mailgun itself applies your forwarding rule after a message arrives — this is typically instantaneous for filters and a few seconds for rule-based forwarding.
Can I use JsonHook as a drop-in replacement for Mailgun Routes?
Yes. If you are using Mailgun Routes primarily to receive replies or inbound messages and forward them to a webhook, you can point the reply-to header of your Mailgun-sent emails directly at your JsonHook address. This removes the need for Mailgun inbound domain setup and gives you a consistent JSON payload with retry logic and HMAC signatures.