Docs

How it works

The five ideas behind the API: subjects, purposes, the vault, current state, and idempotency.

You only need five concepts to use Tripticonsent well. Everything in the API is one of these.

Subject — the person

A subject is one individual. You never send us a name — you reference them by an identifier they already have in your system:

email:sam@example.com
external_id:u_9241          (your own user id)
phone:+34600111222
cookie_id:ck_a1b2           (a first-party cookie, for anonymous visitors)

One person can have several identifiers — a cookie_id before they sign up, an email after. You can merge the two later so their earlier choices follow them (see the anonymous → identified guide). Identifier values are encrypted at rest; we can still look a subject up without decrypting, and an erasure request destroys the key so they become unfindable.

Purpose — the thing they decide about

A purpose is one yes/no decision — marketing_email, analytics, personalization. It carries a category and a legal basis, and its wording is versioned. Full detail: Consent statements.

The vault — an append-only history

Every decision is a new row that is never edited or deleted. Withdrawing consent doesn’t erase the earlier “granted” — it adds a “withdrawn” row that points back at it. So you can always reconstruct exactly what a person had agreed to at any moment in the past, which is what makes it defensible evidence.

2024-01-10  sam@example.com  marketing_email  GRANTED    (banner, v1)
2024-06-02  sam@example.com  marketing_email  WITHDRAWN  (preference centre, v1)
2024-09-15  sam@example.com  marketing_email  GRANTED    (re-opt-in, v2)

Current state — the fast read

You rarely want the whole history — you want “can I email Sam right now?”. GET /v1/subjects/{ref}/consent gives you just the latest state per purpose, computed from the vault and cached. It’s the endpoint your app calls on every page load.

StateMeaning
GRANTEDThey said yes and it still holds.
DENIEDThey said no.
WITHDRAWNThey said yes, then took it back.
EXPIREDAn expiry policy aged it out — treat as “ask again”.
NOT_GIVENThey’ve never been asked. Purposes with no record report their default state.

Idempotency — safe retries

Network calls fail and get retried. Send an Idempotency-Key header (any unique string, e.g. a UUID) on every write. If the same key arrives twice with the same body, you get the original response back — no duplicate row. Same key with a different body is rejected with 409, which catches a bug where you reused a key by mistake.

curl -X POST $API/v1/consent \
  -H "authorization: Bearer sk_live_…" \
  -H "idempotency-key: 7c9e6a1b-4f2d-4a10-9c3e-1b2a3c4d5e6f" \
  -d '{"subject":"email:sam@example.com","purpose":"analytics","state":"GRANTED"}'