Resend Setup Guide
This guide walks through setting up Resend as your email provider for NornWeave.
Prerequisites
- A Resend account (sign up)
- A domain you control for sending/receiving email
- Access to your domain’s DNS settings
Step 1: Create API Key
Log in to Resend
Go to the Resend Dashboard.
Create API Key
Navigate to API Keys > Create API Key.
- Name:
NornWeave - Permissions: Full Access (required for both sending and receiving)
Copy the Key
Copy the API key immediately - it won’t be shown again. It looks like: re_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Step 2: Verify Your Domain
Navigate to Domains
Go to the Domains page > Add Domain.
mail. or updates. rather than your root domain to isolate sending reputation.Add DNS Records
Resend will provide DNS records to verify ownership. You’ll need to add:
| Type | Name | Value |
|---|---|---|
| TXT | send.mail | v=spf1 include:amazonses.com ~all |
| CNAME | resend._domainkey.mail | resend._domainkey.resend.dev |
| MX | mail | feedback-smtp.us-east-1.amazonses.com (priority 10) |
The exact values will be shown in your Resend dashboard for your specific domain.
Verify Domain
Click Verify DNS Records in Resend. Verification typically completes within minutes, but can take up to 72 hours.
Step 3: Enable Receiving
Resend supports receiving emails (inbound) via webhooks. You have two options:
Option A: Use Resend-Managed Domain
Resend provides a .resend.app domain for testing. Any emails sent to <anything>@<id>.resend.app will be received.
To find your Resend domain:
- Go to the Emails page
- Select the Receiving tab
- The predefined address should be shown.
Option B: Use Custom Domain
For production, use your own domain:
Enable Receiving
Go to your domain details and enable the Receiving toggle.
Add MX Record
Add the MX record shown in the Resend dashboard to your DNS:
| Type | Name | Value | Priority |
|---|---|---|---|
| MX | inbound-smtp.resend.com | 10 |
mail.yourdomain.com) to avoid conflicts.Verify MX Record
Click I’ve added the record and wait for verification.
Step 4: Configure Webhooks
Navigate to Webhooks
Go to the Webhooks page.
Add Webhook
Click Add Webhook with these settings:
- URL:
https://your-server.com/webhooks/resend - Events: Select
email.received(and optionallyemail.delivered,email.bouncedfor tracking)
Copy Webhook Secret
Copy the webhook signing secret for verifying webhook authenticity.
Step 5: Configure NornWeave
Update your .env file:
EMAIL_PROVIDER=resend
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
RESEND_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxxxx| Variable | Description |
|---|---|
RESEND_API_KEY | Your API key from Step 1 |
RESEND_WEBHOOK_SECRET | Webhook signing secret for verification |
Step 6: Verify Setup
Restart NornWeave
docker compose restart apiCreate a Test Inbox
curl -X POST http://localhost:8000/v1/inboxes \
-H "Content-Type: application/json" \
-d '{"name": "Test", "email_username": "test"}'Send a Test Email
Send an email to test@mail.yourdomain.com from your personal email.
Check Logs
docker compose logs -f apiYou should see the incoming webhook being processed.
Webhook Payload
Resend sends a JSON webhook payload for received emails:
{
"type": "email.received",
"created_at": "2024-02-22T23:41:12.126Z",
"data": {
"email_id": "56761188-7520-42d8-8898-ff6fc54ce618",
"created_at": "2024-02-22T23:41:11.894719+00:00",
"from": "Sender <sender@example.com>",
"to": ["test@mail.yourdomain.com"],
"cc": [],
"bcc": [],
"message_id": "<example+123>",
"subject": "Test Email",
"attachments": [
{
"id": "2a0c9ce0-3112-4728-976e-47ddcd16a318",
"filename": "document.pdf",
"content_type": "application/pdf"
}
]
}
}Troubleshooting
Webhook Not Receiving
- Verify your server is publicly accessible
- Check the webhook events log in Resend dashboard
- Ensure you selected the
email.receivedevent type - Verify webhook signature validation is working
Domain Verification Failed
- DNS changes can take up to 72 hours to propagate
- Use
digornslookupto verify records - Ensure no typos in the DNS values
- Check the domain status in Resend dashboard
Emails Not Arriving
- Verify MX records are correct with
dig MX mail.yourdomain.com - Ensure MX record has the lowest priority if you have multiple
- Check the Receiving tab in Resend for incoming emails
Webhook Verification Failing
Resend webhooks include svix-id, svix-timestamp, and svix-signature headers for verification. Ensure you’re using the correct webhook secret.
# Example verification
import hashlib
import hmac
def verify_webhook(payload, headers, secret):
msg_id = headers.get('svix-id')
timestamp = headers.get('svix-timestamp')
signature = headers.get('svix-signature')
signed_content = f"{msg_id}.{timestamp}.{payload}"
expected = hmac.new(
secret.encode(),
signed_content.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"v1,{expected}", signature)