What is an Email Webhook? A Developer's Guide

Email has been around since the 1970s, yet consuming it programmatically is still surprisingly painful. If you've ever needed to react to an incoming email inside a web application โ€” parse an order confirmation, open a support ticket, trigger an automation โ€” you've probably run into the same wall: email doesn't push, it sits in a mailbox waiting to be polled.

An email webhook solves this by flipping the model. Instead of your code asking "are there new emails?", the system calls your code the moment a message arrives, just like any other webhook.

The core idea

A webhook is simply an HTTP request that one system makes to another when something happens. You've used them before: Stripe calls your /webhook endpoint when a payment succeeds; GitHub calls it when someone pushes a commit.

An email webhook extends that same pattern to email. When a message arrives at a particular address, the service immediately makes an HTTP POST (or PUT, PATCH, DELETE, or GET) to a URL you've configured. The email's contents (sender, subject, body, attachments) arrive as a JSON payload, ready for your code to handle.

No polling loop. No IMAP connection to maintain. No MIME parsing on your side.

What the payload looks like

When email-webhook receives a message, it parses it and sends JSON like this to your endpoint:

{
  "from": "alice@example.com",
  "to": "abc123xyz@email-webhook.com",
  "subject": "New order #4821",
  "message": "Hi, I'd like to place an order for...",
  "attachments": [
    {
      "filename": "order.pdf",
      "contentType": "application/pdf",
      "content": "JVBERi0xLjQK..."
    }
  ]
}

The message field is the plain-text body of the email. Attachment contents are base64-encoded inline. Every request also carries an X-email-webhook-id header โ€” a unique UUID for that invocation, useful for idempotency and debugging.

A minimal receiving server

Here's the smallest possible handler in a few common languages:

Node.js (Express)

import express from "express";

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

app.post("/webhook", (req, res) => {
  const { from, subject, message } = req.body;
  console.log(`New email from ${from}: ${subject}`);
  // your logic here
  res.sendStatus(200);
});

app.listen(3000);

Python (Flask)

from flask import Flask, request

app = Flask(__name__)

@app.post("/webhook")
def handle_email():
    data = request.get_json()
    print(f"New email from {data['from']}: {data['subject']}")
    # your logic here
    return "", 200

Ruby (Sinatra)

require "sinatra"
require "json"

post "/webhook" do
  data = JSON.parse(request.body.read)
  puts "New email from #{data['from']}: #{data['subject']}"
  # your logic here
  status 200
end

Return a 2xx status and the delivery is recorded as successful. Anything else, and the invocation is marked as failed.

Why not just poll an IMAP inbox?

Polling works, but it comes with real costs:

  • Latency. A 5-minute poll interval means up to 5 minutes of delay on every event.
  • Complexity. You need to manage connection state, handle reconnects, track which messages you've already processed, and deal with IMAP's stateful protocol.
  • Infrastructure. A persistent polling process has to run somewhere, even when no emails are arriving.

An email webhook handler, by contrast, is a single stateless HTTP endpoint. It can live in a serverless function, a Cloudflare Worker, or any existing web service. It only runs when there is work to do.

Real-world use cases

Support ticket ingestion: A customer emails your support address. The webhook fires, your handler creates a ticket in your database, and sends an acknowledgement. No support inbox to monitor.

Order confirmation parsing: Your e-commerce platform sends order emails. The webhook fires, an LLM or simple parser extracts the order details, and your system records the purchase.

Email-based AI agents: A user sends a natural-language request to your app's email address. The webhook fires, you pass message to an LLM, and take action based on the response.

No-code automation pipelines: Point the webhook URL at a Zapier Catch Hook, Make HTTP module, or n8n Webhook node to bridge incoming email into any downstream tool without writing a server.

How email-webhook implements this

When you sign up for email-webhook, you get a unique @email-webhook.com address. You configure one or more webhooks, each with a target URL, HTTP method, optional sender filter, and optional custom headers for authentication. When mail arrives at your address, email-webhook's SMTP server receives it, matches it to the right webhook, and fires the HTTP request in real time.

There's nothing to install, no API keys to provision for the sending side, and no persistent process to run. Your endpoint just needs to be reachable over HTTPS.

Ready to try it? Create your first webhook in under a minute.