Two things stop email from reaching the inbox: misconfigured authentication and bad sender reputation. The Broadcast module addresses both — it provisions DNS through whatever email provider the org has connected (SES, SendGrid, Mailgun, Resend) and tracks reputation per sender account so you know when to slow down.
Step 1: connect a provider
Email goes through whatever provider your org has connected via Upstream. One of:
- AWS SES — high deliverability, low cost, requires production-mode access for non-trivial volume
- SendGrid — easiest setup, mature event webhooks
- Mailgun — strong EU presence, mailing-list features
- Resend — newest, simplest API
Connect via POST /upstream/save-integration with the provider type. See Twilio integration for the same flow applied to a different vendor.
Step 2: register the domain
/broadcast/domains/registerJWT{ "domain": "acme.com" }
Returns the DNS records the provider wants you to publish (SPF, DKIM, sometimes a return-path CNAME). The provider also creates an internal "domain" or "identity" record on its side.
{
"success": true,
"domain": "acme.com",
"domainId": "...",
"verified": false,
"dkimStatus": "Pending",
"records": [
{ "purpose": "DKIM", "type": "CNAME", "name": "abc123._domainkey.acme.com", "value": "abc123.dkim.amazonses.com" },
{ "purpose": "DKIM", "type": "CNAME", "name": "def456._domainkey.acme.com", "value": "def456.dkim.amazonses.com" },
{ "purpose": "DKIM", "type": "CNAME", "name": "ghi789._domainkey.acme.com", "value": "ghi789.dkim.amazonses.com" }
]
}
Step 3: publish DNS records
Add the records to your DNS — through your registrar, Cloudflare, Route 53, whatever you use.
You'll typically need three categories:
- SPF — TXT on the apex domain. Authorizes your provider's MTAs to send for you.
- DKIM — three CNAMEs (or one TXT, depending on provider). Cryptographic signature.
- DMARC — TXT on
_dmarc.<domain>. Policy that tells receivers what to do with unauthenticated mail.
A reasonable starting DMARC: v=DMARC1; p=quarantine; rua=mailto:[email protected]. Move to p=reject once SPF and DKIM are passing for all your sending sources.
Step 4: verify
/broadcast/domains/status/{domain}JWTThis endpoint does three things:
- Asks the provider whether it has verified the domain (DKIM tokens visible, SPF aligned).
- Performs a live DNS lookup of SPF, DKIM, and DMARC.
- Compares them and returns per-record status:
verified | invalid | missing.
{
"domain": "acme.com",
"registeredWithProvider": true,
"providerVerified": true,
"isOurDomain": false,
"allVerified": true,
"records": [
{ "purpose": "SPF", "status": "verified", "type": "TXT", ... },
{ "purpose": "DKIM", "status": "verified", "type": "CNAME", ... },
{ "purpose": "DMARC","status": "verified", "type": "TXT", ... }
],
"currentDNS": { "a": [...], "cname": [...], "mx": [...] }
}
DNS propagation can take 5-60 minutes. Poll this endpoint every 30 seconds in the UI until allVerified: true.
Auto-configure (registered through AppMint)
If you bought the domain through AppMint (ResellerClub, Cloudflare, or internal registrar), AppEngine can write the DNS records for you:
/broadcast/domains/auto-configureJWT{ "domain": "acme.com" }
The endpoint:
- Calls
/broadcast/domains/status/{domain}to know what's needed. - Talks to the registrar API to add SPF, DKIM, DMARC, and any return-path records.
- Re-checks status and returns the result.
Only works for domains where purchasedThroughUs: true and the registrar is resellerclub, cloudflare, or internal. External domains stay manual.
Single-email verification (no domain)
For one-off senders without their own domain (e.g., [email protected]), some providers let you verify a single email address:
/broadcast/domains/register-emailJWT{ "email": "[email protected]" }
Returns immediately; the provider sends a verification link to the inbox. Click it, then check status:
/broadcast/domains/email-status/{email}JWTThis is fine for transactional sends from a personal mailbox but not for bulk — domain auth is required for any meaningful volume.
Live DNS validators (no provider needed)
/broadcast/validate/domain/{domain}No auth/broadcast/validate/email/{email}No authPure DNS lookups — SPF, DKIM, DMARC, MX, CNAME. Useful as a sanity check before kicking off provider registration, or to debug an existing setup that's failing in the wild.
Sender reputation
Each email_account (the sending identity, e.g., [email protected]) has a daily health check that records:
- Reputation score (0-100)
- Bounce rate
- Spam-complaint rate
- DNS verified state
/broadcast/healthJWT/broadcast/health/{accountId}/checkJWTThe dashboard view shows summary counters across the org. Per-account history is held in email_health records (one daily snapshot for at least 30 days).
When bounceRate > 3%, health.status flips to flagged. The send pipeline then prefers other accounts in the same broadcast's rotation set, gradually warming the flagged account back up.
Multi-account warmup
A new domain shouldn't start at 100k emails/day. Configure several email_account records ([email protected] … [email protected]) all on the same domain, set autoRotate: true, and choose a rotation strategy on each broadcast:
healthiest— pick the account with the best score for each batchround_robin— even distributionrandom— random pickpriority_based— use accounts with higherpriorityfirst
Combined with low daily caps in early weeks, this gives the domain a reputation ramp.
Major mailbox providers (Gmail, Yahoo) increasingly drop unauthenticated mail. SPF + DKIM alone is no longer enough; publish a DMARC record (p=quarantine is fine to start) on day one.