Gmail & Yahoo Bulk-Sender Requirements as a Compliance Posture
Google and Yahoo published a joint set of sender requirements in October 2023 and have enforced them for bulk senders — anyone above 5,000 messages per day — since February 2024. The regime is not a statute and not an Orbit policy: it is the acceptance policy of the two largest mailbox providers your email lands on, and a violation is answered with rejection, not merely spam-folder placement. Messages from a non-compliant bulk sender bounce at Gmail’s and Yahoo’s doors with a policy rejection, so the surface behaves like a compliance gate even though no law created it. The obligations are tenant-owned. Orbit verifies your domain and carries the headers, but the SPF/DKIM/DMARC records live in your DNS, the complaint rate is produced by your list, and the spam-rate floor is scored by Google Postmaster Tools against your sending domain. This page maps each obligation to the Orbit surface you read or configure it on, so a bulk sender can close the regime deliberately instead of discovering it in a rejection spike.This page is guidance, not legal advice. The exposure here is not a
fine — it is deliverability rejection at the recipient mailbox
provider. The statutory layers that sit beside this regime
(CAN-SPAM in the US, CASL in Canada, the Spam Act in Australia)
specify content and consent rules and are documented on their own
pages; nothing in this page replaces them.
The four obligations, mapped to Orbit surfaces
The 2024 regime has four mechanical requirements. For each: what the rule demands, and where the control lives in Orbit.
Obligations 1 and 2 are DNS properties you publish and Orbit verifies;
obligations 3 and 4 are traffic properties your send behaviour
produces. The configuration sections below take them one at a time.
SPF + DKIM signing
The regime’s first obligation — authenticate with SPF and DKIM — is already a hard gate in Orbit: a custom sending domain does not accept traffic until its DNS verifies, and the DKIMp= public key is
bit-length-validated (minimum 1,024 bits per RFC 8301), so a
placeholder record never flips a domain to green. The records, the
Verify DNS flow, and the drift-regression health check are covered
in Email → Domain Setup; that page owns
the mechanics and this page does not repeat them.
The posture gap the bulk-sender regime closes is DMARC, which the
Domain Setup table lists as one row among four. The next section is
the policy guidance that row does not carry.
DMARC policy: p=none is the floor, not the posture
A DMARC record at_dmarc.your-domain.com must exist for Gmail and
Yahoo to accept your bulk traffic, and p=none technically satisfies
the checkbox. It is the wrong end-state. p=none tells receiver
filters “monitor only — take no action on failures,” which means:
- A domain that spoofs you fails nothing: the failed-DMARC mail in your recipients’ inboxes is indistinguishable from your own, and the reputation damage lands on your domain.
- You are one DNS edit away from enforcement anyway when the next
escalation of the regime raises the floor — Yahoo and Google have
both signalled
p=quarantine/p=rejectas the intended direction.
v=DMARC1; p=none
long enough to confirm your legitimate senders pass (SPF and DKIM
aligned — with a receiver’s rua reports if you collect them), then
step to p=quarantine, then p=reject. Each stage raises the
penalty for spoofing you while your own authenticated traffic — which
Orbit only sends once DKIM and SPF both verify — passes unchanged.
Keep the DMARC record’s policy coherent with the rest of the row: a
domain that fails its own DKIM/SPF checks and publishes p=reject
rejects its own mail. Orbit’s verification gate makes that near-self-
inflicted — verification is green before the domain accepts traffic,
but an out-of-band edit to your DNS can drift it; the daily health
check and the per-record traffic-light read below catch the drift
before it becomes a rejection wave.
One-click unsubscribe (RFC 8058)
Every outbound email Orbit dispatches already carries the mechanism the regime names:List-Unsubscribe (RFC 2369) names where the client should send the
opt-out — an HTTPS URL plus a mailto fallback. List-Unsubscribe-Post
(RFC 8058) is the signal the 2024 regime actually checks: it tells the
mailbox provider it may POST to the header URL and the opt-out must
complete without any further interaction — no confirmation page,
no login wall, no second click. Orbit’s signed unsubscribe URL meets
that contract: the POST lands at the unsubscribe endpoint, the token
is verified, a suppression row is written with scope email, and an
email.unsubscribed audit event is appended. The mailbox-provider
“Unsubscribe” button and your in-body footer link resolve to the same
endpoint, so the statutory layer (CAN-SPAM’s one-click requirement,
CASL, the Spam Act) and the mailbox-provider regime are satisfied by
the same mechanism — the framing this page adds. The in-body side is
in US CAN-SPAM Compliance.
Two points the regime adds beyond the statute:
- The header pair is checked at the gate, not sampled. A bulk
sender whose marketing mail lacks
List-Unsubscribe-Postis rejected outright, not filtered; the header has to be present on every marketing message, which Orbit’s transport-layer injection guarantees by construction. - A mailto-only footer link no longer suffices. The in-body unsubscribe link remains required by CAN-SPAM and by the Gmail/Yahoo content rules, but the one-click POST property is header-side. Keep both: the footer link for the statute and your template, the header pair for the mailbox-provider gate.
Spam-rate thresholds
The numerical floor sits in Google Postmaster Tools, not in the statute and not in Orbit: Gmail publishes a per-domain spam rate (the share of your delivered mail recipients mark as spam), and the regime’s hard ceiling is 0.30% — cross it and bulk traffic is rejected. The healthy target is 0.10%; between the two you are accepting queued gunk, not compliance. The complaint-suppression layer is what keeps you under the ceiling:- A recipient’s “Report spam” click arrives on the delivery events
path and writes a
complaintsuppression entry — the recipient is held out of later sends and cannot re-complain. See Email → Bounce and Complaint Handling for the lifecycle table. GET /api/v1/email/suppressions/reputationreports the aggregatecomplaintRateover a trailing window next to the bounce rate, the health tier (healthy | at_risk | poor), and the current list size — poll it during ramp and while you test a new segment.- The consolidated deliverability overview surfaces the same complaint signal in the Email tab’s KPI row, and contact deliverability health reads it per contact and segment, so the propagation from a recipient’s spam-folder click to a segment-level verdict is observable without Postmaster Tools.
Orbit’s suppression of a complaining recipient keeps the same
recipient from driving your rate up — it does not remove a complaint
that already counted. The rate is scored by Google against your
domain from recipient reports; Postmaster Tools is the measurement
the regime enforces against, and the Orbit surfaces are what you
watch between Postmaster check-ins. Cross-verifying both is the
posture.
Posture configuration
Three concrete knobs close the regime end-to-end.1. Read your DMARC posture from the DNS-status endpoint
The per-record traffic-light view reports the DMARC record’s health and its live value, so the policy you published is observable without a DNS lookup:dmarc entry in the records array carries both the status
(valid | warning | invalid | unknown) and the recordActual string
you actually published, e.g.
{ "kind": "dmarc", "status": "valid", "recordActual": "v=DMARC1; p=quarantine; ..." }.
Read recordActual not only for presence but for the p= policy —
that is the value the regime’s floor and the staged ramp above are
about. The response format is in
Email → Domain Setup.
2. Export the suppression ledger the complaint loop feeds
The suppression list that complaint events write is exportable as CSV or JSON, and the export run is itself audited — the trail an auditor or a deliverability consultant asks for. Both the ledger and its export are documented on consent-suppression-export; the email-side parameters (channel=email) filter the export to the
rows the regime’s threshold is computed from.
3. Let the transport layer carry the header pair
You do not attachList-Unsubscribe or List-Unsubscribe-Post
headers yourself; Orbit injects the signed URL and the one-click POST
signal on every outbound message. What you control at send time is
the in-body placement: keep an unsubscribe link in a shared footer
block so every campaign template carries it, keep the physical postal
address beside it for the CAN-SPAM layer, and send. The
template and merge-tag layer
resolves {{contact.unsubscribeUrl}} into the body at dispatch, so
the footer stays template-bindable rather than hand-pasted per send.
Worked pre-flight checklist
Run this the day you cross the 5,000-messages/day threshold and before any new bulk segment launches:- Domain verifies green. Poll
GET /api/v1/email/domains/:domainId/dns-statusand confirmoverallStatusisvalidand no record iswarning/invalid— especiallyspf,dkim, anddmarc. - DMARC policy is at least
p=quarantineon the ramp.recordActualon thedmarcrow shows the published policy; a still-p=nonedomain is compliant-but-unprotected today and one regime-escalation away from a gate tomorrow. - Templates carry the unsubscribe footer. The base template includes a footer block with the unsubscribe link (and the postal address for CAN-SPAM) — a template without the footer is a send-gate at the mailbox provider, not an Orbit error you will see locally.
- Header pair confirmed on a canary send. Send one message to a
seed Gmail address and inspect the raw headers — both
List-UnsubscribeandList-Unsubscribe-Post: List-Unsubscribe=One-Clickpresent — before you open the campaign to the segment. - Suppression list is seeded. Bulk-import any legacy opt-out
list from your previous ESP
(
POST /api/v1/email/suppressions/bulk-import) so recipients who already opted out elsewhere do not re-receive and re-complain on the new platform. - Complaint rate baseline is under 0.10%. Poll
GET /api/v1/email/suppressions/reputationfor a trailing-window baseline, and re-check after the first day of the ramp; pair it with Postmaster Tools as the regime’s authoritative read. - Warm-up before volume. A new domain’s reputation is zero, not good; ramp daily volume per Email → Warm-up posture before bulk traffic, and watch the health tier on the reputation endpoint rather than the send rate.
Related references
- US CAN-SPAM Compliance for Email — the statutory layer this regime sits next to; names the same one-click-unsubscribe surface but from the content side, and predates the mailbox-provider regime’s rejection gate.
- CASL — Canada’s Anti-Spam Legislation — the express-consent regime; its unsubscribe and identification rules compose with (and are stricter than) the bulk-sender requirements.
- Australia Spam Act — same statutory class for Australian recipients.
- Opt-Out & Suppression Lists — the ledger the complaint and unsubscribe events write into.
- Email — Domain Setup, suppression lifecycle, reputation endpoint, warm-up.
- Read the consolidated deliverability dashboard — the Email tab’s KPI row where the complaint signal surfaces day-to-day.
Localized variants (FR/AR/TR and further locales) are follow-ups:
the CAN-SPAM page already has fr/ar/tr mirrors to use as the
pattern; this page ships in English first and mirrors next.