Overview
Sending email to a webhook means routing inbound messages to an HTTP endpoint rather than a mailbox. Instead of a human reading the email, your application receives a structured JSON payload containing the sender, subject, body, headers, and attachments — and can act on it programmatically.
This pattern is useful for countless workflows: processing order confirmations, capturing support requests, ingesting lead notifications, or automating any process that currently requires someone to manually read and act on an email.
JsonHook makes this trivially easy. You register an inbound address such as [email protected], configure a target webhook URL, and JsonHook handles all the SMTP reception, MIME parsing, and HTTP delivery. You never have to run an email server or write a MIME parser.
- Works with any sender — no changes on the sending side required
- Delivers a consistent JSON schema on every message
- HMAC-SHA256 signed requests for security
- Automatic retries with exponential backoff if your endpoint is temporarily unavailable
Prerequisites
Before you begin, make sure you have the following in place:
- A JsonHook account — sign up at jsonhook.com. The free tier covers 100 emails per month with no credit card required.
- A webhook endpoint — an HTTPS URL that accepts POST requests with a JSON body. This can be an existing API route in your application, a serverless function, or a temporary tool like webhook.site for testing.
- An API key — generated from the JsonHook dashboard under Settings → API Keys.
Your webhook endpoint must:
- Accept
POSTrequests - Read
Content-Type: application/jsonbodies - Return a
2xxHTTP status code within 10 seconds to acknowledge delivery
Start Receiving Emails as Webhooks
Free tier: 100 emails/month. Set up in under 5 minutes.
Get Free API KeyStep-by-Step Instructions
Follow these steps to route email to your webhook:
- Create an inbound address. Call the JsonHook API to provision a new address:
The response includes anPOST https://api.jsonhook.com/v1/addresses Authorization: Bearer YOUR_API_KEY Content-Type: application/json { "webhookUrl": "https://your-app.com/webhooks/email", "label": "My first webhook" }emailfield — for example[email protected]— and asecretfor HMAC verification. - Send a test email. Send any email to the address returned above. You can use Gmail,
curlwith an SMTP relay, or any email client. - Receive the webhook. Within seconds, JsonHook will POST a JSON payload to your configured URL. Inspect the request body — it contains
email.from,email.subject,email.textBody,email.htmlBody, and more. - Verify the signature. Check the
X-JsonHook-Signatureheader against an HMAC-SHA256 hash of the raw request body using your secret. - Respond with 200. Your handler must return a
200 OK(or any 2xx) within 10 seconds. If it does not, JsonHook will retry.
Code Example
Here is a minimal Node.js/Express handler that receives and verifies a JsonHook delivery:
import express from "express";
import crypto from "crypto";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/webhooks/email", (req, res) => {
const sig = req.headers["x-jsonhook-signature"] as string;
const expected = crypto
.createHmac("sha256", process.env.JSONHOOK_SECRET!)
.update(req.body)
.digest("hex");
if (sig !== expected) {
return res.status(401).send("Invalid signature");
}
const payload = JSON.parse(req.body.toString());
const { from, subject, textBody } = payload.email;
console.log(`New email from ${from}: ${subject}`);
// process textBody, trigger workflows, save to DB, etc.
res.sendStatus(200);
});
app.listen(3000);
The key detail is using express.raw() rather than express.json() so you can verify the signature against the raw bytes before parsing.
Common Pitfalls
Avoid these mistakes when setting up email-to-webhook routing:
- Parsing the body before verifying the signature. Always verify the HMAC against the raw request body bytes. If you let a JSON middleware parse the body first, the raw bytes are gone and signature verification will fail.
- Returning a 5xx or timing out. JsonHook interprets any non-2xx response or a connection timeout as a delivery failure and will retry. Make sure your handler acknowledges quickly — defer heavy processing to a background job.
- Using HTTP instead of HTTPS. JsonHook only delivers to HTTPS endpoints. Make sure your webhook URL uses a valid TLS certificate.
- Ignoring the
X-JsonHook-Delivery-Idheader. This unique ID per delivery lets you implement idempotency — if JsonHook retries a delivery, you can detect the duplicate and skip double-processing. - Not handling large payloads. Emails with base64-encoded attachments can produce large JSON bodies. Ensure your web server body size limit is set to at least 10 MB.