PPactDocs
Compliance & Privacy

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.

Consent enters Pact several ways:

  • A preference center form, where a person manages their own choices.
  • Double opt-in, which records a doi_started event and confirms with doi_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.

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.

json
// 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.

What's next