GDPR Compliance

This is not legal advice. This guide explains how Pactorio works in relation to GDPR requirements. Consult a qualified legal professional for advice specific to your situation.

What Pactorio handles for you

RequirementArticleHow Pactorio satisfies it
Consent must be freely given, specific, informed, and unambiguous Art. 4(11) Banner requires an active click to accept. Non-essential categories default to unchecked. No dark patterns.
No pre-ticked boxes Art. 4(11), Rec. 32 The Admin UI enforces defaultValue: false for all non-required categories.
Scripts must be blocked until consent Art. 5(1)(a), Art. 6 The snippet intercepts document.createElement before the page parses. Matching scripts are held until the user decides.
Withdrawal must be as easy as giving consent Art. 7(3) A "Cookie Preferences" link re-opens the banner at any time. Withdrawal immediately stops relevant scripts.
Proof of consent must be kept Art. 7(1) Every consent and withdrawal is recorded as an audit event in the database with a timestamp and decisions snapshot.
Right of access to consent record Art. 15 GET /v1/consent/history returns the full event log for a user token.
Right to erasure Art. 17 DELETE /v1/consent/permanent hard-deletes a consent record. Requires DPO API key.
Consent records must not include raw IP addresses Art. 5(1)(c) data minimisation Only a country code derived from Cloudflare's CF-IPCountry header is stored. The raw IP is never logged.

Your obligations

Pactorio handles the technical mechanics of consent capture and script blocking. The following remain your responsibility:

Granularity

GDPR requires separate consent for each purpose. Use distinct categories (e.g. "Analytics" and "Marketing") rather than a single "All cookies" toggle. Users must be able to accept analytics but reject marketing.

Essential cookies

Cookies strictly necessary for the site to function (session IDs, CSRF tokens, user preferences) do not require consent under GDPR Rec. 47. Set required: true on the "Essential" category — the toggle will be locked and always on.

Re-consent on config changes

When you save changes in the Admin UI, the config version number increments. Returning visitors whose stored consent is from an older version will be asked to consent again. This ensures re-consent is collected when you add new purposes.

Right to withdraw (Art. 7(3))

Users can withdraw consent at any time by clicking "Cookie Preferences" in your footer (or wherever you surface the link). This re-opens the banner's preferences panel.

When the user withdraws:

  1. The stored consent state is cleared from localStorage.
  2. A DELETE /v1/consent request sets withdrawn_at on the consent record.
  3. A withdrawn event is appended to the audit log.
  4. The SDK fires a cc:consent DOM event with detail: null so your code can react (e.g. unload analytics).

To re-open the preferences banner from your own code:

window.__cc.showBanner();

Right of access (Art. 15)

If a user requests a copy of their consent data, retrieve it via the consent service API using their cc_token cookie value:

GET /v1/consent/history?customerId=YOUR_ID&token=USER_TOKEN

Response:
{
  "events": [
    { "event_type": "granted", "decisions": { "essential": true, "analytics": true }, "occurred_at": "2026-01-01T10:00:00Z" },
    { "event_type": "withdrawn", "decisions": { ... }, "occurred_at": "2026-01-15T09:30:00Z" }
  ]
}

The user's cc_token is stored in the cc_token first-party cookie on your domain. You can read it server-side to look up their history.

Right to erasure (Art. 17)

To permanently delete a user's consent record, use the DPO endpoint. This requires the X-Dpo-Api-Key header — keep this key secure and only use it in response to verified erasure requests.

DELETE /v1/consent/permanent?customerId=YOUR_ID&token=USER_TOKEN
X-Dpo-Api-Key: your-dpo-key

Response:
{ "ok": true, "erased": true }

This hard-deletes the consent record and all associated audit events from the database. The deletion itself is not logged (there is no record to attach a log entry to after deletion).

Audit trail

Every consent action creates an immutable event in the consent_events table:

Event typeTriggered when
grantedUser accepts (or updates) their consent choices
withdrawnUser withdraws all consent

Each event records the full decisions snapshot, the timestamp, and the IP-derived country code. Events are retained for 3 years to satisfy Art. 7(1) accountability requirements, after which they are automatically purged.

Data retention

DataRetention periodBasis
Active consent records1 year from consent dateConsent expires; re-consent required annually
Withdrawn consent recordsFlagged immediately; excluded from all processingArt. 7(3)
Consent audit events3 yearsArt. 7(1) accountability
IP-derived country codeWith the consent recordMinimal; country only, not raw IP