SendGrid Setup Guide

This guide walks through setting up SendGrid as your email provider for NornWeave.

Prerequisites

  • A SendGrid 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 SendGrid

Go to the SendGrid Dashboard.

Create API Key

Navigate to Settings > API Keys > Create API Key.

  • Name: NornWeave
  • Permissions: Full Access (or restrict to Mail Send and Inbound Parse)

Copy the Key

Copy the API key immediately - it won’t be shown again.

Step 2: Authenticate Your Domain

Navigate to Sender Authentication

Go to Settings > Sender Authentication.

Authenticate Domain

Click Authenticate Your Domain and follow the wizard.

You’ll need to add DNS records:

TypeNameValue
CNAMEem1234.yourdomain.comu1234.wl.sendgrid.net
CNAMEs1._domainkey.yourdomain.coms1.domainkey.u1234.wl.sendgrid.net
CNAMEs2._domainkey.yourdomain.coms2.domainkey.u1234.wl.sendgrid.net

Verify

Click Verify after adding the DNS records.

Step 3: Configure Inbound Parse

Navigate to Inbound Parse

Go to Settings > Inbound Parse.

Add Host & URL

Click Add Host & URL:

  • Subdomain: mail (or leave blank for root)
  • Domain: Select your authenticated domain
  • Destination URL: https://your-server.com/webhooks/sendgrid
  • Check POST the raw, full MIME message

Configure MX Records

Add MX record for your receiving subdomain:

TypeNameValuePriority
MXmailmx.sendgrid.net10

Step 4: Secure Inbound Parse (Recommended)

SendGrid supports cryptographic signature verification for Inbound Parse webhooks using ECDSA. This is highly recommended for production deployments.

Create Security Policy

Use the SendGrid API to create a webhook security policy:

curl -X POST https://api.sendgrid.com/v3/user/webhooks/security/policies \
  -H "Authorization: Bearer YOUR_SENDGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "NornWeave Inbound Parse",
    "signature": { "enabled": true }
  }'

The response includes a public_key - save this securely:

{
  "policy": {
    "id": "dd677638-a16d-4e19-95ea-20231c35511b",
    "signature": {
      "public_key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE..."
    }
  }
}

Attach Policy to Parse Webhook

Link the security policy to your Inbound Parse settings:

curl -X PATCH "https://api.sendgrid.com/v3/user/webhooks/parse/settings/mail.yourdomain.com" \
  -H "Authorization: Bearer YOUR_SENDGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/sendgrid",
    "security_policy": "dd677638-a16d-4e19-95ea-20231c35511b"
  }'

Configure Public Key in NornWeave

Add the public key to your environment configuration (see Step 5).

When signature verification is enabled, SendGrid adds X-Twilio-Email-Event-Webhook-Signature and X-Twilio-Email-Event-Webhook-Timestamp headers to webhook requests. NornWeave validates these automatically when SENDGRID_WEBHOOK_PUBLIC_KEY is configured.

Step 5: Configure NornWeave

Update your .env file:

EMAIL_PROVIDER=sendgrid
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Optional: Webhook signature verification (highly recommended for production)
SENDGRID_WEBHOOK_PUBLIC_KEY=MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...

Step 6: Verify Setup

Restart NornWeave

docker compose restart api

Create 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 api

Troubleshooting

Inbound Parse Not Working

  • Verify MX records are correct with dig MX mail.yourdomain.com
  • Check SendGrid’s Activity Feed for incoming emails
  • Ensure your webhook URL is publicly accessible

Authentication Issues

  • Regenerate API key if issues persist
  • Verify the key has Mail Send permissions