Most systems model consent as marketing_opt_in: true. Then someone asks when it was given, and for what, and on which channel, and the answer is a shrug.

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.

What the boolean cannot tell you#

When. Consent ages. In several jurisdictions permission that has not been acted on for a long period is treated as stale.

For what. Agreeing to delivery updates is not agreeing to a weekend promotion. If both read the same flag, you cannot honour the difference even if you want to.

On which channel. Permission to email is not permission to message. This is the single most common modelling error in the category.

How. A ticked box at checkout, an SMS keyword, and a verbal yes on a call are different evidentiary weights. When a complaint arrives, "the flag was true" is not evidence.

And whether it was withdrawn. Withdrawal must be as easy as granting, and must take effect everywhere — including in the campaign that was already queued.

The shape that works#

Not a field on a contact. An append-only ledger of grants and withdrawals, each row carrying: the identifier it applies to, the purpose, the channel, the timestamp, the mechanism, and a reference to the evidence.

Current permission is then a query over that ledger, not a stored value. This sounds like extra work. It is less work than reconstructing history from application logs the first time someone asks you to.

What one row in the ledger has to carry

  1. Subject

    The contact identity, not the channel address. Addresses change; the person does not.

  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, inferred. Different evidentiary weights.

  5. Evidence reference

    A pointer to the artefact: submission id, recording id, inbound message id.

  6. Source system

    Where it originated. Matters enormously after an acquisition or a migration.

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

Why this is not only a compliance concern#

The ledger is what makes preference management possible — letting customers turn down the volume rather than turn you off entirely. A single boolean gives them one choice: everything, or nothing. Presented with that choice, a meaningful share of people choose nothing.

Granular consent, honestly offered, retains more reachable customers than a blunt opt-in ever does. The compliance benefit is real, but the commercial one is bigger and arrives sooner.

One forward-looking note#

From 2 August 2026 the EU AI Act's transparency rules require that a person be told when they are interacting with an AI system, clearly and at first interaction. If an automated agent handles part of your conversations, that disclosure sits in the same architectural place as consent — and is best stored the same way.

Where the ledger goes wrong in practice#

Three failures account for nearly all of them.

The import with no provenance. A list arrives from an acquisition, a partner or a spreadsheet, and every row is written with a mechanism of imported and nothing else. Six months later somebody asks where a particular permission came from and there is no answer. Record the source file, the date, and who asserted it — even a weak provenance is a fact; a blank field is a gap you cannot close later.

The withdrawal that only reaches one system. Someone unsubscribes in the email platform. The messaging platform never hears. This is the failure that generates complaints, and it is architectural: if suppression is stored per vendor rather than centrally, every vendor is a place a withdrawal can fail to arrive.

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

The retention question nobody asks early#

Consent records outlive the relationship, deliberately: you need to be able to demonstrate the basis for a message sent three years ago, which means keeping the record after the contact is gone.

That sits awkwardly with deletion obligations, and the resolution is a distinction worth writing into the design now rather than discovering later: the consent event is a record of what happened, not personal data held for a business purpose. Keep the minimum that evidences it, drop the rest with the contact, and be able to explain the split.

What to take away#

  • Consent is an append-only ledger of events, and current permission is a query over it.
  • Purpose, channel, mechanism and evidence are all load-bearing. None can be null.
  • Suppression must be central; per-vendor suppression is a withdrawal waiting to be missed.
  • Offer preference as well as consent, or the only choice you give people is to leave.

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