Self-hosted email marketing with full source code. Pay once, own forever. Get AcelleMail — $74 →

Setting up Feedback Loops (FBL) for AcelleMail

A complete FBL setup walkthrough — registering with Gmail/Microsoft/Yahoo/Comcast/SES, configuring AcelleMail FeedbackLoopHandler, ARF parsing, and the operational gotchas.

A Feedback Loop (FBL) is the formal channel by which an ISP forwards spam complaints back to the sender. Without one, the recipient's "Report Spam" click is invisible to you — the complaint hurts your reputation but you can't suppress the complaining address, you can't audit which campaign caused the surge, and you can't honor the implicit "stop sending" the recipient just expressed. An FBL-less sending program is operating blind on the most actionable deliverability signal.

AcelleMail ships an App\Model\FeedbackLoopHandler model that ingests FBL reports via IMAP, parses the Abuse Reporting Format (ARF) per RFC 5965, and adds the complaining address to the customer's complaint_list (the per-tenant suppression table). This article covers (a) how to register with each major FBL provider, (b) how to configure the AcelleMail handler, (c) the ARF parsing details that matter when something goes wrong, and (d) the operational gotchas that catch every operator on first FBL deployment.

What an FBL actually delivers

When a Gmail recipient clicks "Report Spam" on your message, Gmail's mail-protection layer routes a copy of the report message to a postmaster mailbox you registered. The message body is in ARF format:

From: complaints@gmail.com
To: fbl@example.com
Subject: FW: [...]
Content-Type: multipart/report; report-type=feedback-report

--boundary
Content-Type: text/plain
This is a feedback report from Gmail.
--boundary
Content-Type: message/feedback-report
Feedback-Type: abuse
User-Agent: ...
Original-Mail-From: <bounce@example.com>
Original-Rcpt-To: <user@gmail.com>
Reported-Domain: example.com
Source-IP: 1.2.3.4
Arrival-Date: ...
--boundary
Content-Type: message/rfc822
[the original message that the user reported, full headers + body]
--boundary--

AcelleMail's FeedbackLoopHandler::processMessage() parses the multipart structure, extracts Original-Rcpt-To (the complainer), Feedback-Type (one of abuse, fraud, virus, other, not-spam per the model's FEEDBACK_TYPES constant), and the embedded original Message-ID. It then:

  1. Records a BounceLog row with bounce_type = unknown and the ARF body in raw.
  2. Adds Original-Rcpt-To to the customer's complaint_list — future sends suppress this address.
  3. Skips processing if Feedback-Type = not-spam (per EXCLUDED_FEEDBACK_TYPES).

Provider-by-provider registration

1. Gmail / Google Workspace

Gmail's FBL is delivered through their Postmaster Tools product. The flow:

  1. Verify your sending domain at postmaster.google.com — DNS TXT record at google._domainkey.example.com (yes, it reuses your DKIM selector path; Google requires DKIM-authenticated traffic before granting Postmaster access).
  2. Once verified, Gmail begins logging spam complaints in the Postmaster dashboard. Note: Gmail does not deliver per-message FBL reports to a mailbox — only aggregated graphs.
  3. Configure AcelleMail to use Postmaster's spam-rate as a reputation signal manually (no automatic ingestion of per-recipient suppressions from Gmail).

The implication: for Gmail, you can't suppress per-recipient via FBL the way you can with other providers. The defense is DMARC alignment + engagement segmentation — Gmail will suppress reputation impact if your authentication is tight and your audience is engaged.

2. Microsoft (Outlook / Hotmail / Live / MSN) — JMRP

Microsoft's Junk Email Reporting Program (JMRP) delivers per-complaint ARF messages. Sign up at sendersupport.olc.protection.outlook.com/snds/JMRP.aspx:

  1. Provide the IP range you send from (must be IPs you own; SES/Mailgun shared-pool IPs are managed by them — see "Shared-IP edge case" below).
  2. Provide the mailbox where ARF reports should land (e.g. fbl@example.com).
  3. Wait for confirmation (typically 24-48 hours).

JMRP delivers a high volume of reports — Microsoft sees a lot of complaints. Plan IMAP poll frequency every 5 minutes; queue-process the ingestion.

3. Yahoo / AOL — combined FBL

Yahoo + AOL share an FBL administered by Verizon Media. Sign up at postmaster.yahooinc.com/feedback-loop/:

  1. Provide the sending domain + DKIM selector.
  2. Provide the mailbox for reports.
  3. Yahoo's FBL is DKIM-keyed — only authenticated mail can be reported back. If your DKIM is intermittently failing, Yahoo silently doesn't deliver reports for those messages.

4. Comcast — XFi FBL

Comcast (residential ISP, large US share) runs its own FBL at feedback.comcast.net:

  1. Provide IP range, sending domain, and target mailbox.
  2. Approval is faster than Microsoft (usually 24h).

5. AWS SES — built-in complaint webhook

If you send via SES, don't use IMAP-based FBL — SES converts the underlying ARF reports into structured complaint events delivered via SNS, which AcelleMail can ingest as a webhook. The AcelleMail SES driver auto-configures the SNS topic when you set up the sending server. Verify by:

Admin → Sending Servers → <SES Server> → Edit → "AWS SES SNS Settings"
   Confirm: Bounce + Complaint topics are subscribed

The SNS path is faster (near-real-time) and more reliable than IMAP polling.

Configuring AcelleMail's FeedbackLoopHandler

In Admin → Feedback Loop Handlers → New:

Name:          gmail-fbl, msft-jmrp, yahoo-fbl (one per provider)
Server:        imap.example.com (your FBL mailbox host)
Port:          993 (IMAP-SSL)
Username:      fbl@example.com
Password:      <strong password>
Encryption:    SSL/TLS
Folder:        INBOX
Move to:       Processed (a folder for already-handled messages)
Delete after:  30 days

Per-provider mailboxes are recommended — keeps reports separated, makes per-provider diagnostics straightforward, and isolates failures (one provider's malformed report doesn't break ingestion for the others).

After creating, AcelleMail polls the mailbox via the queue worker. Each successful poll records:

  • BounceLog rows (bounce_type = unknown, complaint addresses)
  • Suppression-list additions
  • Log entries to storage/logs/feedback-loop-handler-YYYY-MM-DD.log (the model's $logfile is feedback-loop-handler)

Operational gotchas

Gotcha 1 — DKIM key rotation breaks Yahoo + Comcast FBL

Both Yahoo and Comcast key the FBL on DKIM signature. When you rotate keys (per the DKIM rotation playbook), update the FBL provider's record with the new selector — otherwise reports stop arriving silently. Check at the start of every key rotation cycle.

Gotcha 2 — IMAP poll rate must keep up with volume

Microsoft JMRP can deliver 100-1,000 reports per day for a high-volume sender. Set the AcelleMail bounce-handler polling cron to every 5 minutes (or use the queue-worker's continuous mode). Reports older than the IMAP server's auto-delete window will silently disappear.

Gotcha 3 — not-spam reports must be honored

When a recipient clicks "Not Spam" in their inbox (after a previous complaint), the ARF report has Feedback-Type: not-spam. AcelleMail's EXCLUDED_FEEDBACK_TYPES array excludes these — but it doesn't remove the address from the complaint list. If a recipient was previously suppressed and is now saying "actually I do want this," your operations need to manually remove them. Build a UI/admin task for this; otherwise you're disrespecting the recipient's correction.

Gotcha 4 — Shared-IP FBL doesn't reach you

If you send via shared-IP services (SES default, SendGrid free, Mailgun shared), the FBL reports go to the provider, not you. The provider may aggregate complaint metrics; per-message ARF doesn't reach AcelleMail. The defense:

  • For SES, switch to a dedicated IP ($24.95/month per IP) when complaint-scale matters (typically > 100k sends/month).
  • For SendGrid/Mailgun, upgrade to dedicated-IP plans.

The complaint-handling-per-message capability is one of the operational reasons to move to dedicated IPs as you scale.

Gotcha 5 — IMAP timezone mismatches

A known annoyance: some FBL providers send reports with Arrival-Date: in their local timezone (PST or whatever Yahoo's data center uses), while AcelleMail records created_at in your server's timezone. The complaint timestamp in your dashboard may be off by hours. Don't try to "correct" this in the database — AcelleMail's reports use created_at consistently.

Verifying the FBL is working

After 24 hours:

SELECT
  DATE(created_at) as day,
  COUNT(*) as complaints,
  COUNT(DISTINCT customer_id) as affected_customers
FROM bounce_logs
WHERE bounce_type = 'unknown'
  AND created_at > NOW() - INTERVAL 7 DAY
GROUP BY day
ORDER BY day DESC;

If you have complaint volume but no new bounce_type = unknown rows in 24 hours after a campaign, the FBL ingestion is broken — check:

  1. IMAP credentials valid (telnet imap.example.com 993 to test connectivity)
  2. AcelleMail bounce-handler cron is running (per the post-install hardening checklist)
  3. Provider-side registration is still active (some FBLs lapse if traffic stops, then have a re-onboarding step)

Related reading

FAQ

Why doesn't Gmail send per-message FBL reports?

Privacy. Gmail decided per-message ARF reports leak too much recipient identity. The aggregated dashboard (Postmaster Tools) is their compromise.

Can I get FBL reports from smaller ISPs?

Most regional ISPs (Comcast, Cox, Spectrum) run FBLs but registration is per-ISP and tedious. Prioritize the four big ones (Gmail proxy, Microsoft, Yahoo, Comcast) and only chase smaller ones if you have specific deliverability complaints there.

How do I know if a "report spam" complaint actually came from the recipient vs. ISP automation?

ARF doesn't distinguish — both are reported as Feedback-Type: abuse. Treat all complaints as recipient-driven for suppression purposes; don't try to second-guess.

Is there a cost to registering for FBLs?

No. All major FBLs are free (the cost is engineering time). Gmail Postmaster Tools, Microsoft JMRP, Yahoo + AOL, Comcast — all no-cost.

More in Sending & Deliverability