Most systems store consent as a single field: marketing_opt_in: true. Then a complaint arrives and someone asks when it was given, for what, on which channel and how — and the answer is a shrug.

Consent here means a person's permission for you to contact them for a given purpose. Handling it well is a legal duty in most places, and it is also good business.

Interactive figure

What consent actually permits

You may send

  • Order receipt
  • Delivery updates

You may not send

  • Promotional broadcast
  • Win-back campaign
  • Free-form conversation

Grant a permission and watch what becomes sendable.

Grant and revoke each basis, and watch which messages become sendable. Note that nothing is sendable with no basis at all.

Five questions a yes/no field cannot answer#

  1. When? Consent ages. Expectations about refreshing or re-confirming old permission vary by country and by industry code, but "they ticked a box in 2017" rarely ends a complaint well.
  2. For what? Agreeing to delivery updates is not agreeing to weekend promotions. If both read the same field, you cannot honour the difference even if you want to.
  3. On which channel? Permission to email is not permission to text or to message on WhatsApp. This is the most common modelling error in the category.
  4. How? A ticked box at checkout, a texted keyword and a verbal yes on a call carry different weight as evidence. "The field was true" is not evidence.
  5. Was it withdrawn? Under the EU's GDPR (Article 7), withdrawing consent must be as easy as giving it, and many other regimes have similar expectations. Withdrawal must take effect everywhere — including in a campaign that is already queued.

What a single "marketing_opt_in: true" cannot tell you

  • When?

    Consent ages, and "they ticked a box in 2017" rarely ends a complaint well

  • For what?

    Delivery updates are not weekend promotions

  • On which channel?

    Permission to email is not permission to text or to message on WhatsApp

  • How?

    A checkout box, a texted keyword and a verbal yes weigh differently as evidence

  • Was it withdrawn?

    Withdrawal must reach everything, including a campaign already queued

Five open questions, none of which a single field can close.

The shape that works: a ledger#

Not a field on the contact. An append-only ledger — a log you only ever add to — of grants and withdrawals. Your current permission is then a query over the ledger ("latest event for this person, channel and purpose"), not a stored value.

A few rows for one customer might look like this:

WhenIdentifierChannelPurposeEventMechanismEvidence
3 Mar+44 7700 900123SMSDelivery updatesGrantedCheckout formOrder 58213
3 Marana@example.comEmailNewsletterGrantedCheckboxForm submission 9912
18 Jun+44 7700 900123SMSDelivery updatesWithdrawnReplied STOPInbound message 77410

What one row in the ledger has to carry

  1. Subject

    The person, plus the exact address (number, email) the event applies to.

  2. Channel and purpose

    Never "all". A grant that cannot say where and what for cannot be enforced.

  3. Timestamp

    Of the event itself, not of when the row was inserted.

  4. Mechanism

    Web form, keyword, verbal, imported. Different weights as evidence.

  5. Evidence reference

    A pointer to the proof: form submission ID, call recording ID, inbound message ID.

  6. Source system

    Where it came from. Matters a great deal after an acquisition or a migration.

Append-only. A withdrawal is a new row, never an edit — the history is the asset.

This sounds like extra work. It is much less work than reconstructing history from application logs the first time someone asks.

Where it goes wrong in practice#

The import with no history. A list arrives from an acquisition, a partner or a spreadsheet, and every row is written as "imported" and nothing else. Record the source file, the date and who vouched for it. Weak provenance is still a fact; a blank field is a gap you cannot close later.

The withdrawal that reaches only one system. Someone unsubscribes in the email tool; the SMS platform never hears. This failure generates complaints, and it is architectural: if suppression lists live in each vendor rather than centrally, every vendor is a place a withdrawal can fail to arrive. Keep one central suppression list that every sending system checks.

The consent that outlives its purpose. Permission for delivery updates gets read, two years later, as permission to market. Nobody decided that; the data model simply could not tell the difference.

How long to keep the records#

You may need to prove the basis for a message sent years ago, so consent records often need to outlive the customer relationship. That sits awkwardly with deletion duties. A common resolution: treat the consent event as a record of what happened, keep only the minimum needed to evidence it, delete the rest with the contact, and document the reasoning. Take local legal advice on retention periods.

The same place for AI disclosure#

Since 2 August 2026, Article 50 of the EU AI Act requires that people be told, clearly and at the first interaction, when they are dealing with an AI system rather than a person. If an automated agent handles part of your conversations with people in the EU, that disclosure belongs in the same part of your architecture as consent — recorded per conversation, with evidence — and is worth doing everywhere. See AI Act Article 50 for messaging.

What to ask a provider#

  • Can I see consent and opt-out events per contact, per channel and per purpose, with timestamps?
  • When someone replies STOP, how quickly is it reflected, and can I receive it by webhook to update my own ledger?
  • Can I export the full consent history if I leave?

Where to go next#

Sources

Every claim worth checking, with somewhere to check it.

  1. Safer and more transparent AIEuropean Commission · 2 August 2026
  2. AI Act Article 50: transparency rulesartificialintelligenceact.eu
  3. Regulation (EU) 2024/1689 (Artificial Intelligence Act)EUR-Lex
  4. Regulation (EU) 2016/679 (General Data Protection Regulation)EUR-Lex