Skip to content
PostMTA Hosted
StatusSign inOpen panelRequest access
Open menu

Docs

Open in panel → /app · fbl

Suppressions

The suppressions table (added in supabase/migrations/20260712173000_suppressions.sql) is the durable store of addresses that the appliance should not deliver to. Sources:

source When
fbl upserted by scripts/fbl-poll.ts (Release B poller) or addSuppressionFromFbl
webhook Kumo delivery-webhook events (Release C)
manual operator entry from the panel
reputation SNDS / Postmaster integrations (Release C, honest SKIP)

Schema

create table public.suppressions (
  id uuid primary key default gen_random_uuid(),
  workspace_id uuid not null references public.workspaces (id) on delete cascade,
  address text not null,
  reason text not null check (reason in ('bounce', 'complaint', 'manual', 'fbl', 'reputation')),
  source text not null check (source in ('fbl', 'webhook', 'manual', 'reputation')),
  fbl_event_id uuid references public.fbl_events (id) on delete set null,
  note text,
  created_at timestamptz not null default now(),
  expires_at timestamptz,
  unique (workspace_id, address, reason)
);
create index suppressions_workspace_address_idx
  on public.suppressions (workspace_id, address)
  where expires_at is null or expires_at > now();

The partial index keeps the admission check sub-ms even at scale.

Admission path

@postmta/shared/suppressions exposes:

Both the API send path and the SMTP path call checkSuppressed before issuing a credit hold; a hit returns 422 SUPPRESSED (HTTP) or 550 5.7.1 (SMTP).

Provider split

Env Behaviour
SUPPRESSION_PROVIDER=mock (default) never blocks unless MOCK_SUPPRESS_ADDRESS=<addr> is set
SUPPRESSION_PROVIDER=live hits the partial index

Migration rollback

A sibling *.down.sql is committed (Phase 14 hardening will exercise forward+backward round-trip for every migration).

Last verified: Sun Jul 12 2026 17:00:00 GMT-0700 (Pacific Daylight Time). Cross-link maintained byscripts/check-docs-drift.sh (M54).

← All docs