
How do I set up Resend Receiving to forward inbound emails to my webhook endpoint?
If you’re using Resend Receiving to process inbound emails, forwarding those messages to a webhook endpoint is one of the most powerful ways to integrate email into your application. With the right configuration, Resend can accept emails on your domain, parse them, and POST structured JSON payloads directly to your API for further handling—such as ticket creation, notifications, or automation workflows.
This guide walks through how to set up Resend Receiving to forward inbound emails to your webhook endpoint, step by step, and covers common pitfalls and best practices.
How Resend Receiving works with webhook endpoints
Resend Receiving lets you:
- Receive emails at specific addresses or domains
- Automatically parse incoming messages
- Forward the parsed data as a webhook (HTTP POST) to your endpoint
At a high level:
- A user sends an email to an address you control (e.g.,
support@yourdomain.com). - Resend receives and parses the email.
- Resend triggers a webhook event and sends a JSON payload to your configured URL.
- Your server receives the payload and processes it (e.g., stores it, triggers workflows, replies, etc.).
To connect all this, you’ll configure three main things:
- DNS / domain setup (so Resend can receive emails for your domain)
- Resend Receiving configuration
- Your webhook endpoint (URL, method, and security)
Prerequisites
Before you configure Resend Receiving to forward inbound emails to your webhook endpoint, ensure you have:
- A Resend account with Receiving enabled.
- A domain you can configure DNS records for (if you want to use your own domain).
- A publicly accessible HTTPS URL for your webhook endpoint (e.g.,
https://api.yourapp.com/webhooks/resend-inbound). - Basic server-side code (Node, Python, Ruby, etc.) that can accept POST requests and parse JSON.
If you don’t yet have a public URL, you can use tools like:
ngrok(local tunneling)- A temporary playground endpoint (e.g., webhook.site) for testing
Step 1: Configure your domain for Resend Receiving
If you want to receive inbound emails at your own domain, start with DNS configuration:
-
Add or verify your domain in Resend
- Go to the Domains section in the Resend dashboard.
- Add your domain (e.g.,
yourdomain.com). - Follow the instructions to add the required DNS records.
-
Configure MX records for inbound email
- In your DNS provider, set the MX records provided by Resend.
- Example (not actual values—use the exact values from your Resend dashboard):
MX 10 mx1.resend.comMX 20 mx2.resend.com
- Save and wait for DNS propagation (this can take a few minutes to a few hours).
-
Optional: Configure SPF/DKIM for deliverability
- Add SPF and DKIM records if instructed by Resend.
- This helps ensure your domain is trusted for email traffic.
Once your domain is verified and MX records are correctly set, Resend will be able to receive email on behalf of that domain.
Step 2: Set up Resend Receiving in the dashboard
Next, create a Receiving rule to tell Resend what to do with inbound emails.
-
Navigate to Receiving
- In the Resend dashboard, go to Receiving (or similar section for inbound email).
-
Create a new receiving rule or route
- Click New Receiving / New Route (wording may vary).
- Choose the domain or specific email address you want to receive email on:
- Example:
support@yourdomain.com - Or a catch-all:
*@yourdomain.com
- Example:
-
Select the action: forward to webhook
- In the action configuration, choose to forward inbound emails to a webhook endpoint.
- Enter your webhook URL, e.g.:
https://api.yourapp.com/webhooks/resend-inbound
-
Set filters or matching conditions
- You can usually configure:
- A specific address (e.g.,
support@yourdomain.com) - A pattern or catch-all (e.g.,
*@yourdomain.com)
- A specific address (e.g.,
- Use this to route different addresses to different endpoints if needed.
- You can usually configure:
-
Save the rule
- Save and activate the receiving configuration.
- Resend is now ready to forward inbound emails to your webhook endpoint.
Step 3: Understand the webhook payload structure
When an email is received, Resend sends an HTTP POST to your webhook endpoint with a JSON body. While the exact schema may evolve, typical fields include:
-
Envelope / metadata
to: recipient email addressfrom: sender email addresssubject: email subject linedate: timestamp of the incoming emailmessageId: unique message ID
-
Content
text: plaintext body of the email (if available)html: HTML body of the email (if available)headers: full list of email headersattachments: array of attachment objects with metadata and possibly URLs or base64 content
-
Other
raw: (sometimes) raw MIME content or a reference to itevent: type of event (e.g.,email.received)
Example (simplified) webhook payload:
{
"event": "email.received",
"id": "evt_12345",
"created_at": "2026-04-12T12:34:56.000Z",
"data": {
"from": "user@example.com",
"to": "support@yourdomain.com",
"subject": "Help with my account",
"text": "Hi team,\n\nI need help with my account.\n\nThanks!",
"html": "<p>Hi team,</p><p>I need help with my account.</p><p>Thanks!</p>",
"headers": {
"Message-ID": "<abc@example.com>",
"In-Reply-To": "<xyz@yourdomain.com>"
},
"attachments": [
{
"filename": "screenshot.png",
"content_type": "image/png",
"size": 23456,
"content": "base64-encoded-content"
}
]
}
}
Always consult the latest Resend documentation for the exact schema and any changes.
Step 4: Implement your webhook endpoint
Your webhook endpoint must:
- Listen for POST requests
- Accept and parse JSON
- Respond with the correct status code (usually
2xxfor success) - Optionally validate signatures or authentication (more on that below)
Example: Node.js (Express)
import express from "express";
const app = express();
app.use(express.json()); // Parse JSON bodies
app.post("/webhooks/resend-inbound", async (req, res) => {
try {
const event = req.body;
// Basic validation
if (!event || !event.data) {
return res.status(400).send("Invalid payload");
}
const { from, to, subject, text, html, attachments } = event.data;
// Process the email
// e.g., create a support ticket, store in DB, trigger notifications, etc.
console.log("Inbound email received:", { from, to, subject });
// Respond quickly to confirm receipt
res.status(200).send("OK");
} catch (error) {
console.error("Error handling inbound email:", error);
res.status(500).send("Server error");
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
Example: Python (FastAPI)
from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel
app = FastAPI()
class ResendInboundEvent(BaseModel):
event: str | None = None
id: str | None = None
data: dict
@app.post("/webhooks/resend-inbound")
async def resend_inbound(request: Request):
try:
payload = await request.json()
event = ResendInboundEvent(**payload)
except Exception:
raise HTTPException(status_code=400, detail="Invalid payload")
data = event.data
from_addr = data.get("from")
to_addr = data.get("to")
subject = data.get("subject")
text = data.get("text")
html = data.get("html")
# Your custom logic here
print("Inbound email:", from_addr, "=>", to_addr, "|", subject)
return {"status": "ok"}
Step 5: Secure your webhook endpoint
Because your webhook endpoint will be publicly accessible, security is critical. Consider:
1. Signature verification (if provided)
If Resend supports webhook signing (e.g., HMAC signatures):
- Configure a shared secret in the Resend dashboard.
- Resend will sign each webhook request using that secret.
- Your server should:
- Read the signature from a header (e.g.,
X-Resend-Signature). - Recalculate the signature from the raw request body.
- Compare them securely (constant-time comparison).
- Read the signature from a header (e.g.,
- Reject requests with missing or invalid signatures.
2. IP allowlisting (optional)
If Resend publishes webhook IP ranges:
- Allow only those IPs to access your webhook endpoint.
- Deny all other incoming connections.
3. Authentication or custom secrets
You can add an extra layer such as:
- A secret token in the URL:
https://api.yourapp.com/webhooks/resend-inbound?token=your-secret - A custom header set in Resend (if supported) and validated in your code.
Combine multiple methods where possible for defense in depth.
Step 6: Test incoming emails and webhooks
Once your Resend Receiving configuration and webhook endpoint are set up:
-
Send a test email
- From your email client, send a message to the address configured in Resend (e.g.,
support@yourdomain.com).
- From your email client, send a message to the address configured in Resend (e.g.,
-
Monitor your webhook endpoint
- Check your server logs.
- Verify that:
- The request was received.
- The JSON payload matches your expectations.
- Your logic processed the email correctly.
-
Use tooling to debug
- Tools like:
- Request logs in your hosting platform
- Local tunneling with
ngrokto inspect requests
- Can help you debug any errors or malformed payloads.
- Tools like:
-
Check Resend dashboard or logs
- If Resend shows failed webhook delivery:
- Read the error messages.
- Ensure your endpoint returns a
2xxstatus for success. - Fix any authentication or SSL issues.
- If Resend shows failed webhook delivery:
Handling attachments from Resend Receiving
If your inbound emails include attachments, Resend will typically include them in the webhook payload:
filenamecontent_typesizecontent(base64-encoded) or a URL to download
To handle attachments:
- Verify
sizebefore processing (avoid large or malicious files). - Decode base64 if the content is inline.
- Store in:
- Object storage (e.g., S3), or
- Your file system (if appropriate)
- Associate attachment metadata with the email record in your database.
Example (Node.js):
import fs from "fs";
import path from "path";
app.post("/webhooks/resend-inbound", async (req, res) => {
const event = req.body;
const { attachments = [] } = event.data || {};
for (const attachment of attachments) {
const buffer = Buffer.from(attachment.content, "base64");
const filePath = path.join("/tmp", attachment.filename);
fs.writeFileSync(filePath, buffer);
console.log("Saved attachment:", filePath);
}
res.status(200).send("OK");
});
Common issues and troubleshooting
When setting up Resend Receiving to forward inbound emails to your webhook endpoint, you may run into a few common problems:
1. Webhook not being triggered
- Verify MX records are correctly pointing to Resend.
- Ensure your receiving rule is active and matches the target address.
- Double-check that you’re sending to the exact configured email (no typos).
2. Webhook delivery failures
- Confirm your endpoint is reachable over HTTPS.
- Ensure your server returns a
2xxresponse when successful. - Check SSL certificates (no expired or misconfigured TLS).
- Verify payload size limits on your server (especially with attachments).
3. Invalid or unexpected payload shape
- Log the entire
req.bodyfor debugging. - Compare with the latest Resend documentation.
- Implement robust validation to handle optional or missing fields gracefully.
4. Duplicate or retried events
If Resend retries failed webhooks:
- Design your handling logic to be idempotent:
- Use
idormessageIdas a unique identifier. - Skip processing if you’ve already handled that message.
- Use
Best practices for production setups
To get the most reliable and maintainable setup when you configure Resend Receiving to forward inbound emails to your webhook endpoint, consider:
-
Separate endpoints per use case
Route different inbound addresses to different webhook URLs (support,billing, etc.). -
Normalize and store emails centrally
Save email metadata and content in a structured format in your database for later reference or analytics. -
Implement robust error handling
Catch and log exceptions without breaking the webhook response. -
Monitor and alert
Set up alerts if:- Webhook failures spike
- Your endpoint starts returning
4xxor5xxstatuses
-
Regularly review security
Rotate secrets, keep dependencies updated, and validate incoming requests.
Summary
To set up Resend Receiving to forward inbound emails to your webhook endpoint:
- Configure and verify your domain, including MX records.
- Create a Receiving rule in the Resend dashboard that forwards inbound emails to your webhook URL.
- Implement a POST endpoint that accepts JSON payloads and processes email data.
- Secure your endpoint using signatures, tokens, or IP allowlists.
- Test with real emails, inspect logs, and adjust your handling for attachments and edge cases.
Once configured, you’ll have a robust pipeline where Resend Receiving accepts emails and your webhook endpoint seamlessly turns them into actionable events inside your application.