Consent Management
The consent ledger at the heart of Pact — channels, purposes, capture, withdrawal, and the gate every send passes.
Consent is not a checkbox bolted onto Pact — it's the core. Every outbound message passes a consent gate, and every consent decision is written to an append-only ledger you can audit and export.
The model
Consent is recorded per channel and purpose:
- Channels: email, SMS, voice, tracking
- Purposes: marketing, transactional, analytics, profiling, product updates
A contact's state on any channel/purpose pair is one of granted, withdrawn, pending, expired, or unknown. Pact infers the governing jurisdiction (GDPR, CCPA, CASL, and others) from the contact's location and applies the right defaults — for example, marketing email is pending-until-opted-in under GDPR but implied under CCPA.
Capturing consent
Consent enters Pact several ways:
- A preference center form, where a person manages their own choices.
- Double opt-in, which records a
doi_startedevent and confirms withdoi_confirmed. - Imported consent from another system, stamped with its source.
- One-click unsubscribe (RFC 8058) on outbound email.
Every change appends an event — granted, withdrawn, updated, imported, expired, and more — with the actor, a hashed IP, the user agent, and proof text.
Withdrawal and suppression
A withdrawal is just another event; the contact's state flips immediately and future sends stop. Beyond consent, a suppression list hard-blocks an address or number regardless of consent. Suppression entries carry a reason (bounce, complaint, stop, admin, legal) and a severity (hard or soft), and take precedence over everything else.
The consent gate
Before any send, Pact calls the gate, which returns whether the send is allowed and, if not, why — suppressed, withdrawn, expired, still pending, or blocked by a jurisdiction rule.
// POST /v1/consent/check →
{ "allowed": false, "reason": "withdrawn", "state": "withdrawn", "suppressed_by": null }
Consent is checked at send time, every time
A grant today is not a permanent pass. Sequences and journeys re-check the gate on every step, so a withdrawal mid-flight stops the very next message.
Audit and erasure
The ledger is append-only — records are never edited in place, which makes it a defensible audit trail and exportable to your SIEM. Erasure is itself an event (erasure_executed), so the act of forgetting a subject is provable even after their data is gone. See DSAR.