Skip to content

Data protection and your responsibilities

Every Cowliss organization is the controller of its own data: you decide what your users’ data is for, you establish the lawful basis (GDPR Art. 6), and you answer to your users. Cowliss is the processor (Art. 28): it stores and moves personal data only on your documented instructions. The contract layer lives under Legal; this page is the practical half — the defaults you accept by using Cowliss, and the tooling you get for data rights.

Each default below is a documented instruction: it reads as something you instruct Cowliss to do, not a policy Cowliss imposes on you.

Section titled “Default 1: ingestion is unconditional, consent gates sends”

Cowliss ingests every event you send it, regardless of the profile’s consent state. Consent is enforced at the moment of action: the send activity checks the consent map before a marketing email or webhook goes out and records skipped_consent in the delivery log when revoked.

The split is deliberate. Storing what your apps observed is a different act from contacting the person, and gating at send time means a consent change takes effect everywhere at once — including for journeys already in flight. If your lawful basis requires not storing someone’s events at all, don’t send them.

One carve-out, also part of this default: templates that declare the transactional send class (a receipt, an export-is-ready notice) bypass consent by design — a receipt must not vanish because someone once left a newsletter — but still stop on suppression, quota, and a sending pause.

Section titled “Default 2: consent purposes are fixed names with your meaning”

The consent map has exactly two purposes, emailMarketing and dataProcessing, enforced mechanically by the send gate. What each purpose means is controller-defined: emailMarketing might be “product updates” for one org and “all non-transactional email” for another. Publish that meaning to your users; Cowliss never interprets it, it only honors the flags.

Set consent per user through the consent endpoint or the dashboard’s consent editor. Two automations revoke email on your behalf — a spam complaint and the one-click unsubscribe link every marketing send carries — and both write a system.consent_revoked system event, so the user timeline always answers “when and why did sends stop”.

Art. 7(1): where processing is based on consent, the controller must be able to demonstrate it. Cowliss stores the consent state you supply opaquely — it does not know what your user saw or agreed to. Capturing the agreement (your form, your wording, your timestamp) is yours; the consent map plus the system.consent_revoked event stream is the storage Cowliss contributes to your proof.

Data-rights requests land on you; Cowliss’s job is making each one call:

  • Erasure: DELETE /v1/users/{profileId} removes a person across Postgres, ClickHouse, and Temporal, identifiers and quarantine queue included, within the selected environment. Also a dashboard action on the user page.
  • Export: GET /v1/users/{profileId}/export returns one JSON document: profile, identifiers, traits, consent, suppressed addresses, event history, held quarantine entries, and journey/delivery history.
  • Retention: a per-environment “keep events N days” setting (18 months at most in production, 30 days in development), applied as a ClickHouse TTL computed at insert. Writes carrying a timestamp older than the window are refused with 422. See the settings reference.
  • Self-service for your users — signed one-click unsubscribe and preference endpoints, carried in every marketing send’s headers.

All of it is in the users API reference. Erasure, export, and retention are API-and-dashboard operations; the CLI and MCP cover the read side plus consent edits.

Sign-up asks for express acceptance of the terms of service and privacy policy, which incorporate the DPA — so the controller/processor split binds every organization from its first event.