Docs
Open in panel → /app · reputation
Reputation
On-box complaint / FBL / suppression pulse. No outbound calls. Honest SKIP: actual SNDS / Postmaster / Google Postmaster Tools API connectors require third-party sign-up that is out of scope for the appliance. Recorded in ECC_VERIFY Phase 3 and in the Honest SKIPs block of trust/security.
What ships (matrix M74)
GET /v1/panel/reputation/pulse— 30-day rollup of:complaints— FBLfeedback_type='abuse'plus suppression rows withreason='complaint'(summed; FBL hashes and suppression addresses are not cross-deduped)bounces— suppression rows withreason='bounce'fbl_events— total FBL hits in the windowsuppressions_active— total suppression rows in the windowtop_addresses[]— sorted by hit count, top 10
POST /v1/panel/reputation/suppression— operator adds a manual suppression ({address, note?}), upsert on(workspace_id, address, reason).
Both routes require admin role. The Reputation panel section fetches
the pulse on load and offers a simple add-suppression form.
On-box pulse loop
flowchart LR
Kumo[Kumo delivery / FBL ingest] --> FBL[fbl_events]
Webhook[Delivery webhooks] --> SUP[suppressions]
FBL --> SUP
FBL --> Pulse[GET /v1/panel/reputation/pulse]
SUP --> Pulse
Pulse --> Panel[/app Reputation section]
Panel -->|POST suppression| SUP
- Kumo posts FBL ARF to
POST /v1/fbl/ingest→fbl_events. - The FBL poller / webhook path may also write
suppressions. - The pulse endpoint aggregates the last 30 days locally.
- Operators react in-panel (manual suppression) or via policy / wallet controls.
FBL loop (operator)
- Ensure FBL ingest is configured per docs/build/fbl.md.
- Watch the FBL and Reputation panel tabs for rising
complaints. - On spike: pause sends, review
top_addresses, add manual suppressions, re-apply policy, or revoke API keys as needed.
CSV / Postmaster import (manual)
We do not ship SNDS or Google Postmaster API connectors. Operators can
still import third-party exports into suppressions on the appliance host
via the bundled CSV importer
scripts/postmaster-csv-import.ts — pipe
recipient,complaint_count rows on stdin and it upserts each address as
reason='complaint', source='reputation' against the unique index
(workspace_id, address, reason), so re-imports are idempotent and
--workspace-id=<uuid> (default seed) lets you attribute rows per tenant
without touching SQL.
Option A — psql one-liner (bounce CSV)
# columns: address (header row optional)
psql "$DATABASE_URL" -c "\copy tmp_bounces(address) FROM 'snds-bounces.csv' CSV HEADER"
psql "$DATABASE_URL" -c "
INSERT INTO public.suppressions (workspace_id, address, reason, source, note)
SELECT '<workspace-uuid>'::uuid, address, 'bounce', 'manual', 'snds import'
FROM tmp_bounces
ON CONFLICT (workspace_id, address, reason) DO NOTHING;
"
Option B — documented SQL (Postmaster-style complaint list)
-- Replace values per export row
INSERT INTO public.suppressions (workspace_id, address, reason, source, note)
VALUES
('<workspace-uuid>', 'user@example.com', 'complaint', 'manual', 'postmaster export 2026-07-13')
ON CONFLICT (workspace_id, address, reason) DO NOTHING;
For FBL-shaped rows, prefer fbl_events ingest via the HTTP contract rather
than hand-inserting hashes unless you are replaying a backup.
What does NOT ship (honest SKIP)
- SNDS (Microsoft) — account sign-up + daily CSV automation not bundled.
- Google Postmaster Tools — OAuth + domain verification API not bundled.
- Yahoo / Comcast / Apple private feedback loops beyond your own ARF mailbox.
Operators can attach outbound vendors via cron on the appliance host (write
into suppressions or fbl_events directly).
Fixtures / smoke
# JSON fixtures only (no secrets)
MOCK_REPUTATION=1 pnpm exec tsx scripts/seed-reputation-fixtures.ts ws-demo
# Live lab seed (service role required; keys never logged)
SUPABASE_URL=http://127.0.0.1:54321 \
SUPABASE_SERVICE_ROLE_KEY=... \
pnpm exec tsx scripts/seed-reputation-fixtures.ts <workspace-uuid>
Related
- apps/api/src/reputation/index.ts — pulse + suppression.
- apps/api/src/reputation/pulse.test.ts — 30-day aggregation.
- docs/build/fbl.md — FBL ingest contract.
Last verified: Sun Jul 12 2026 17:00:00 GMT-0700 (Pacific Daylight Time). Cross-link maintained byscripts/check-docs-drift.sh (M54).