Getting Started: Forward Your First Email to a Webhook in 5 Minutes
This guide walks you from sign-up to your first webhook delivery. By the end you'll have a working pipeline: email in, HTTP request out.
What you need
- An email account (Gmail, Outlook, or anything else)
- A publicly reachable URL โ webhook.site gives you one instantly, with no sign-up required, and is perfect for this walkthrough
Step 1: Sign up and copy your address
Sign up for email-webhook. Once you're logged in, your dashboard shows your unique incoming address:
abc123xyz@email-webhook.com
The local part is a system-generated opaque ID โ every account gets a different one. Treat it like a secret. Anyone who can send mail to this address can trigger your webhooks.
Step 2: Create a webhook
Click New webhook in the dashboard and fill in the form:
| Field | Value |
|---|---|
| Webhook URL | The URL that should receive requests (paste your webhook.site URL here) |
| HTTP method | POST โ the right default for receiving data |
| From email | Leave blank to match mail from any sender |
Leave Enabled checked and click Create Webhook.
Step 3: Send a test email
Open your email client and send a message to your @email-webhook.com address. Any subject and body will do:
To: abc123xyz@email-webhook.com
Subject: Hello from my inbox
Body: This is my first email webhook test.
There's no "send test" button in the dashboard and no endpoint verification step โ you test by sending a real email.
Step 4: See the JSON arrive
Within a few seconds your webhook URL receives a POST request. The body looks like this:
{
"from": "you@yourdomain.com",
"to": "abc123xyz@email-webhook.com",
"subject": "Hello from my inbox",
"message": "This is my first email webhook test.",
"attachments": []
}
The request also carries these headers:
| Header | Value |
|---|---|
Content-Type |
application/json |
User-Agent |
email-webhook/1.0 |
X-email-webhook-id |
A UUID unique to this delivery |
Save that X-email-webhook-id value. It lets you trace a specific delivery through your own logs and use it as an idempotency key if your handler could receive the same request more than once.
What the payload fields mean
| Field | Type | Description |
|---|---|---|
from |
string | Sender's email address |
to |
string | Your @email-webhook.com address |
subject |
string | The email subject line |
message |
string | The plain-text body of the email. For HTML-only emails (no plain-text part), message will contain the HTML. |
attachments |
array | Attached files, if any |
If the email has attachments, each one appears as an object in the array:
{
"filename": "receipt.pdf",
"content": "JVBERi0xLjQK..."
}
content is the raw attachment data, base64-encoded.
A minimal receiving handler
Once you've confirmed delivery in webhook.site, move to a real 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(`Mail from ${from}: ${subject}`);
console.log(message);
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"Mail from {data['from']}: {data['subject']}")
print(data["message"])
return "", 200
Ruby (Sinatra)
require "sinatra"
require "json"
post "/webhook" do
data = JSON.parse(request.body.read)
puts "Mail from #{data['from']}: #{data['subject']}"
puts data["message"]
status 200
end
Return a 2xx status and the delivery is recorded as successful. Any other status marks the delivery as failed.
Next steps
- Lock it down: add a custom header (e.g.
Authorization: Bearer <token>) to your webhook so only email-webhook can call your endpoint. - Filter by sender: set the From email field on your webhook to only fire for mail from a specific address โ useful when you want to react to a particular service's notifications.
- Debug deliveries: enable Message Logs on your webhook to see the HTTP status code, duration, and metadata for each delivery.