Mail ARF

RFC 5965 Abuse Reporting Format ingest. ESPs (Yahoo, AOL, Microsoft, Google, etc.) post these via webhook when a user marks one of the operator's messages as spam. The format is multipart/report with three required parts:

1. text/plain — human-readable description (ignored) 2. message/feedback-report — the structured report itself, a block of header:value lines (Feedback-Type, User-Agent, Original-Mail-From, Source-IP, Reported-Domain, Arrival-Date, Authentication-Results, Auth-Failure, etc.) 3. message/rfc822 (or text/rfc822-headers) — the original message being reported, in full or just the headers

b.mailArf.parse consumes the raw multipart/report bytes and returns a normalized event shape suitable for an abuse-reconciliation pipeline (suppression list, abuse-score tracking, complaint-rate dashboards). Required fields per RFC 5965 §3.1 are Feedback-Type and User-Agent — parse refuses anything missing them. Reports without a message/feedback-report subpart are also refused.

This is a parse-only primitive — operators wire it into their own webhook endpoint and emit the audit trail / suppression-list updates from there. The framework's b.mailBounce.handler is the reference shape for the surrounding plumbing; ARF rides alongside it because the wire format and lifecycle differ (multipart/report vs JSON; no vendor-specific parser needed).

b.mailArf.parse(rawMessage, opts) #

stable0.8.53
{
  maxBytes:  number,    // default: 8 MiB
  audit:     boolean,   // default: true
}

Parse an RFC 5965 Abuse Reporting Format multipart/report payload into a normalized abuse-event shape. Refuses on missing message/feedback-report subpart, missing required Feedback-Type or User-Agent fields, or report bytes exceeding the 8 MiB ceiling.

Returns:

{ feedbackType, // "abuse" | "auth-failure" | "fraud" | … userAgent, // "SomeESP-Feedback/1.0" version, // "1" (default) — per RFC 5965 §3.1 originalFrom, // string — Original-Mail-From originalRcptTo, // [string] — every Original-Rcpt-To arrivalDate, // ISO 8601 string when parseable, else raw reportedDomain, // string — Reported-Domain sourceIp, // string — Source-IP authenticationResults, // string — verbatim Authentication-Results authFailure, // "dkim" | "spf" | "dmarc" | … (optional) reportedUri, // string — Reported-URI (phishing reports) incidents, // number — Incidents (when present) originalMessage, // string — the message/rfc822 part body extraFields, // { [name: string]: string } — operator- // visible fields the spec doesn't // normalize }

Audit emission: the framework emits system.mailarf.parsed on success and system.mailarf.malformed on refusal. Operators wire audit: false to suppress when the upstream webhook handler emits its own audit row.

var b = require("@blamejs/core");
var event = b.mailArf.parse(rawWebhookBody);
if (event.feedbackType === "abuse") suppressionList.add(event.originalFrom);
// → typeof event.userAgent === "string"

Last updated 2026-08-08T16:39:49.652Z by seeder.