A Contact has independent opt-in status for each channel — WhatsApp, Email, SMS, Web Push, Voice. Status is a four-state enum: subscribed (active, can be messaged for marketing), service-only (only transactional messages, common for WhatsApp 24-hour service window), opted-out (no messaging of any kind), unknown (no consent captured yet). The send pipeline checks current status before every outbound. A marketing template to an opted-out contact fails fast with a logged "consent block" event, never reaching the BSP.
Capture is multi-source. Web forms with a consent checkbox component record the IP, user agent, form ID, page URL, and the exact consent text shown. WhatsApp opt-in via interactive button (the customer clicks "Yes, subscribe me") records the message ID and timestamp. Imports support a consent-source column for backfilling historical permissions with attribution. API endpoints accept consent metadata on every write. Every capture path produces the same auditable artifact.
Updates are bidirectional. Outbound: a contact who replies STOP to a WhatsApp broadcast triggers an automatic opt-out across the channel, confirmation message, and DLQ block for any in-flight sends to that contact. Outbound email unsubscribe link does the same for email. Inbound: a contact who messages "subscribe" or clicks an explicit re-opt-in button gets status flipped back with a fresh attribution record. The preference center (a hosted page or embeddable widget) lets contacts manage their own consent across all channels with a single link, audited.
Compliance export is built in. The audit endpoint returns every consent state change for a contact, with full attribution, on demand. Bulk export for tenant-wide audits runs as a background job and produces a regulator-ready CSV or PDF with the timestamps, sources and consent text. For India, the DLT registration ID can be attached to each capture. For EU, lawful basis (consent, legitimate interest, contract) is selectable per capture. For California (CCPA), do-not-sell flags are first-class. The compliance team should never need to ask engineering for a query again.