Skip to main content

Receiver-side deliverability loop

Everything Orbit checks before a send is a projection: DNS verification grades the records you published, the Deliverability Lab scores the content you are about to send, and test sends measure where synthetic mail lands. None of it tells you what Google, Yahoo, and Microsoft actually did with your real traffic. Two stateless analyzers close that gap:
  • POST /api/v1/email/dmarc/reports/analyze folds the DMARC aggregate (RUA) reports receivers mail to your rua= address into authentication pass ratios, applied dispositions, and a ranked list of sources failing DMARC as your domain.
  • POST /api/v1/email/postmaster/reputation/analyze folds Google Postmaster Tools TrafficStats snapshots and feedback-loop (FBL) complaint records into one reputation readout with a healthy flag and severity-ordered recommendations.
Both accept what you collected, compute an analysis, and persist nothing. Your cron or connector owns the collection; the analyzers own the math. You will:
  1. Understand which receiver-side feed answers which question
  2. Wire the RUA mailbox and submit report batches
  3. Read the analysis and decide when to advance policy
  4. Fold in Postmaster Tools and feedback-loop data
  5. Pair the loop with your sender-side gates

1. Why receiver-side data

A test send proves a path works; it is signed with the platform’s test key, not your domain’s, and it samples a handful of seed inboxes. Your production traffic is graded on evidence you can only get from the receivers themselves: RUA is the universal feed: it exists for any domain that publishes a rua= tag, at any volume, and it is the only evidence that makes advancing none → quarantine → reject defensible. Postmaster adds Google’s reputation grading on top, and FBL tells you why. Orbit already acts on the sender side of complaints (hard bounces, exhausted soft bounces, complaints, and unsubscribes are suppressed automatically), but suppression hides the campaign that caused the complaint; the FBL fold surfaces it. The mechanics of the RUA report format itself are covered in DMARC aggregate reports (RUA): ingest and analysis; this guide is the operations loop around it.

2. Wire the RUA mailbox

1. Point rua= at a mailbox you control. The address lives in your _dmarc TXT record next to the policy:
Publish it from day one, at p=none. Receivers only start mailing aggregates after they see the tag, and a capture mailbox for infrastructure reports should never double as a human inbox. The record-level rules (one record, never two; keep rua= through every policy step) are in Publishing the rua= record. 2. Run a cron or connector against that mailbox. Orbit does not read your mailbox for you; the analyzers are stateless by design, so collection is a tenant-owned control. A daily job is the natural cadence because providers roll up one UTC day per report. For each attachment, classify the transport shape: 3. POST batches of up to 20 reports. Each content is capped at 1 MiB as submitted, and a single request may mix encodings. Corrupt payloads (bad base64, malformed XML, a gzip stream that will not decode) are skipped and tallied; they never fail the batch.
4. Read the tally before the analysis. The response reports an honest split of what you submitted versus what was actually analyzed:
A nonzero skippedReports is not an error; it is the decoder telling you a payload was unreadable. If it stays high, your connector is misclassifying an encoding or forwarding truncated attachments.

3. Read the analysis

Work through the response in this order:
  1. The tally. submittedReports should match what your connector fetched for the window; parsedReports plus skippedReports equals it.
  2. The alignment ratios. dmarcSuccessRatio is the headline: the share of received volume that passed DMARC (either aligned SPF or aligned DKIM, per RFC 7489). spfSuccessRatio and dkimSuccessRatio tell you which mechanism is carrying your mail when the headline dips.
  3. The dispositions. The none/quarantine/reject counts are what receivers applied to your mail, not what you published. A block of failures already at quarantine or reject means enforcement is catching something; a spike of none-disposition failures at unfamiliar sources means it is flowing unimpeded.
  4. The ranked spoofing sources. Every entry is one of two things: a legitimate sender you never aligned (a marketing tool, a helpdesk, a payroll service sending with your header-from but outside your SPF and DKIM), or an actual spoofer. Onboard the first; enforce against the second. The optional topSpoofingSources request bound (1 to 200) controls how long that ranked list may be.
  5. The recommendation. Given your published policy and the observed pass ratios over the sample, the analyzer returns advance, hold, or investigate, with a confidence level and the specific blocker to fix first (a weak SPF-alignment rate, a weak DKIM-alignment rate, or a top failing source to identify).
When to advance policy. Start at p=none and stay there until the DMARC pass ratio is healthy over a meaningful sample and every failing source on the ranking is either onboarded or accepted as a spoofer. Then move to p=quarantine with a pct sample (for example pct=25), raise pct while the ratio holds, and finish at p=reject. Re-run the same analysis after every republish; each batch of aggregates confirms the stricter policy is only catching mail that deserves it. Advance on a hold or investigate recommendation and you turn a monitoring problem into a blocking problem.

4. Fold in Postmaster and feedback-loop data

RUA tells you how your mail authenticated; Postmaster Tools tells you how Google grades you regardless, and FBL records tell you who complained. Pull both on the same cron that collects RUA:
  • Google Postmaster Tools — fetch the daily TrafficStats resources for your domain from the Postmaster Tools API and pass them raw in google (up to 200 snapshots): domain and IP reputation, the user-reported spam ratio, SPF/DKIM/DMARC success ratios, and the delivery-error breakdown.
  • Feedback loops — pass complaint records from Yahoo, Microsoft, and AOL in feedback (up to 200).
At least one record across the two arrays is required; an empty body returns 422.
The response folds every snapshot into one readout:
Read it top to bottom: the healthy flag first, then recommendations in the order returned (most severe first), then the ratios and reputation bands to see which input drove the verdict. The perProvider breakdown separates Google’s view from the FBL view when the two disagree, and problemIps names the addresses dragging the IP-reputation buckets so you can check them against your own sending infrastructure before assuming an external spoofer.

5. Pair with sender-side gates, and troubleshoot

The receiver-side loop never replaces the sender-side gates; it completes them. Before volume, the order of operations is still:
  1. Verify DNS and keep it green under Channels → Email → Domains, as walked through in the email lifecycle guide. A drifted DKIM record shows up in RUA aggregates a day later as a collapsing dkimSuccessRatio.
  2. Score content in the Deliverability Lab before each send. The Lab grades what you are about to send; the analyzers grade what you already sent. When inbox placement dips, the Lab tells you whether content changed and the RUA fold tells you whether authentication or reputation did.
When something looks wrong, the common causes in order:
  • 422 on an empty batch. reports accepts 1 to 20 payloads and the Postmaster body needs at least one record in google or feedback. A 422 right after a quiet weekend usually means the connector fetched an empty mailbox and POSTed anyway; have it skip empty windows.
  • 403 on a valid key. Both analyzers require an owner or admin role. A key minted for a member or viewer role fails here even when it sends fine.
  • 422 on an oversize payload. Each content is capped at 1 MiB as submitted. A report over the cap should be split at the collector (submit fewer reports per call) rather than truncated.
  • High skippedReports. The payload decoded as nothing readable: an encoding mislabeled (a gzip stream declared utf8), a truncated attachment, or a gzip stream past the platform’s decompression ceiling. The tally is the diagnosis; fix the connector, resubmit the window.

Next steps