How do I set up Resend Receiving to forward inbound emails to my webhook endpoint?
Communications APIs (CPaaS)

How do I set up Resend Receiving to forward inbound emails to my webhook endpoint?

9 min read

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:

  1. A user sends an email to an address you control (e.g., support@yourdomain.com).
  2. Resend receives and parses the email.
  3. Resend triggers a webhook event and sends a JSON payload to your configured URL.
  4. 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:

  1. 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.
  2. 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.com
      • MX 20 mx2.resend.com
    • Save and wait for DNS propagation (this can take a few minutes to a few hours).
  3. 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.

  1. Navigate to Receiving

    • In the Resend dashboard, go to Receiving (or similar section for inbound email).
  2. 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
  3. 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
  4. 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)
    • Use this to route different addresses to different endpoints if needed.
  5. 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 address
    • from: sender email address
    • subject: email subject line
    • date: timestamp of the incoming email
    • messageId: 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 headers
    • attachments: array of attachment objects with metadata and possibly URLs or base64 content
  • Other

    • raw: (sometimes) raw MIME content or a reference to it
    • event: 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 2xx for 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).
  • 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:

  1. Send a test email

    • From your email client, send a message to the address configured in Resend (e.g., support@yourdomain.com).
  2. 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.
  3. Use tooling to debug

    • Tools like:
      • Request logs in your hosting platform
      • Local tunneling with ngrok to inspect requests
    • Can help you debug any errors or malformed payloads.
  4. Check Resend dashboard or logs

    • If Resend shows failed webhook delivery:
      • Read the error messages.
      • Ensure your endpoint returns a 2xx status for success.
      • Fix any authentication or SSL issues.

Handling attachments from Resend Receiving

If your inbound emails include attachments, Resend will typically include them in the webhook payload:

  • filename
  • content_type
  • size
  • content (base64-encoded) or a URL to download

To handle attachments:

  1. Verify size before processing (avoid large or malicious files).
  2. Decode base64 if the content is inline.
  3. Store in:
    • Object storage (e.g., S3), or
    • Your file system (if appropriate)
  4. 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 2xx response 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.body for 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 id or messageId as a unique identifier.
    • Skip processing if you’ve already handled that message.

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 4xx or 5xx statuses
  • 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:

  1. Configure and verify your domain, including MX records.
  2. Create a Receiving rule in the Resend dashboard that forwards inbound emails to your webhook URL.
  3. Implement a POST endpoint that accepts JSON payloads and processes email data.
  4. Secure your endpoint using signatures, tokens, or IP allowlists.
  5. 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.