Email: transactional sends + support inbox

Two totally separate mail paths (PLAN.md §6 guardrail):

Gmail/M365 mailbox via their OAuth grant. Never routed through our domain.

Cash Recovered summaries. Sent from [email protected] with

Reply-To: [email protected]. This document covers only this path.

Code path

apps/api/src/lib/email/transactional.tssendTransactionalEmail().

Provider is picked by EMAIL_PROVIDER (cloudflare | resend), or

automatically: Cloudflare when CLOUDFLARE_EMAIL_API_TOKEN is set, else

Resend when RESEND_API_KEY is set, else the send is skipped with a log

line (never throws). All older Resend call sites (founder notify, feedback,

audit requests, weekly report) go through this lib; the welcome email is

lib/email/welcome.ts fired on POST /api/v1/auth/signup.

Cloudflare sends use the Email Service REST API:

POST https://api.cloudflare.com/client/v4/accounts/{account_id}/email/sending/send

with {from, to, subject, html, text?, headers: {'Reply-To': …}}.

Already provisioned via API (done 2026-07-07)

On the dunchase.com zone (DNS token at ~/.clouldflare/.env):

[email protected] (already a verified destination address on

the Cloudflare account, so forwarding works the moment routing is enabled)

Manual dashboard steps (founder — the DNS token cannot do these)

Email Routing → Enable. (Records + the support@ rule are already there;

enabling flips it live.) Send a test mail to [email protected] and

confirm it lands in the Gmail inbox.

Email Sending (Email Service beta) → add dunchase.com / noreply@

sender, then My Profile → API Tokens → create a token with the

Email Sending permission for the account.

CLOUDFLARE_EMAIL_API_TOKEN=<token> (with EMAIL_PROVIDER=cloudflare,

[email protected], [email protected]

already set), then recreate the paidup-api/paidup-worker containers.

check the welcome email arrives with Reply-To [email protected].