# sendgrid

Transactional email. Used by:
- `/api/lead.js` (marketing lead inquiry + autoresponder)
- `/api/auth-send-code.js` (passwordless email OTP)
- escalation-cycle workflow (alerts to GMs / owners / brand HQ)
- weekly-recap workflow (Monday digests)
- lead-followup workflow (drafted first-touch replies)

## Endpoint

`POST https://api.sendgrid.com/v3/mail/send`

## Auth

`Authorization: Bearer <SENDGRID_API_KEY>`. The key needs the Mail Send permission only.

## Required env vars

- `SENDGRID_API_KEY` - the key itself.
- `LEAD_FROM` - the sender address; must be verified in SendGrid (e.g. `noreply@franchisefrontline.com`).
- `LEAD_FROM_NAME` - the display name.

## Sender setup

- Verify `franchisefrontline.com` as a sending domain in SendGrid (DNS records: SPF, DKIM).
- Verify `noreply@franchisefrontline.com` as a single sender (or use the domain auth).
- Set up the unsubscribe footer for marketing emails (lead-acknowledgement, weekly-recap) per CAN-SPAM. Transactional emails (passwordless code, escalation alerts) are exempt but we add the footer anyway for hygiene.

## Templates

We do not use SendGrid dynamic templates. All bodies are composed in code from the `/templates/*.md` files. Reason: keeping the templates in the repo means they're versioned, reviewable in PR, and editable without logging into SendGrid.

## Rate limits

- SendGrid's standard plan: 100 emails/second sustained.
- Our expected peak is a Monday morning weekly-recap burst: ~5,000 emails over 5 minutes at full scale, well within limits.

## Failure modes

- **401:** key revoked. Engineer alert.
- **429:** back off per their guidance.
- **400 with body listing the bad field:** typically a misformatted `from` or `to`. Log and skip; do not retry.

## Compliance

- CAN-SPAM: physical address in the footer of marketing emails. Use the Durango Advisors LLC address with the brand name "FranchiseFrontline" in the From line.
- Customer suppression list synced on `bounce` and `unsubscribe` events via SendGrid Event Webhook.
