privacy + DSAR.
we hold three classes of data: your account data, your fans’ data, and analytics events. each one’s handled differently. all of it is exportable; most of it is erasable.
your account data.
- email + password (hashed via supabase auth, bcrypt-style).
- workspace memberships, roles, audit log entries.
- api keys (we store SHA-256 hashes only; never plaintext).
- stripe customer id (no card data ever touches our servers).
you can delete your account from settings. that erases the owned workspaces (links + destinations + redirects) and removes you from any workspace where you’re a member.
your fans’ data.
when fans interact with your links — pre-save, email capture — we hold:
- their email + (sometimes) first name.
- consent IP + user-agent + timestamp.
- for pre-save: spotify user id + display name + encrypted refresh token (AES-256-GCM, decryptable only inside the worker process at release-day-fire time).
- a per-row unsubscribe / revoke token.
DSAR — export + erasure.
GDPR Art. 15 (right of access) and Art. 17 (right to erasure). two paths: fans go to yala.la/dsar and submit their email + the action; we send a verification link, they click, the action runs across every workspace that holds their data. admins fulfil per-workspace requests from workspace → settings → privacy:
- export — type the fan’s email, click export. yala downloads a structured JSON file with every email-capture row + every pre-save row tied to that email in your workspace. you hand it to the fan via whatever channel you verified the request through (support email, signed letter, etc).
- erase — soft-deletes both rows + redacts PII (email, first name, consent IP/UA, refresh token overwritten with [erased]). aggregates (release-day blast counts) stay; the data subject is gone.
both actions are also exposed via the public API — see public API + webhooks.
analytics events.
IPs are SHA-256 hashed and truncated to 24 bytes at the edge worker. the original IP never leaves the worker; only the hash lives in postgres. that means:
- we can’t reverse a fan’s IP to identify them.
- we can’t enumerate analytics events by fan email — the two are not joined.
- DSAR for analytics events is therefore "we don’t hold identifiable data here." that’s the GDPR-correct answer.
cookies + consent.
landing pages drop cookies only when retargeting pixels are configured for the workspace AND the fan opts in via the consent banner. EU IPs get the banner by default; rest-of-world depends on workspace settings. consent state stored in a first-party cookie scoped to the landing.
subprocessors.
- cloudflare — edge redirect engine + KV + custom domain SSL. handles every fan request.
- supabase — postgres + auth + storage. holds workspace + link + analytics data.
- upstash QStash — async event ingest queue.
- stripe — billing.
- resend — transactional + broadcast email.
- odesli — DSP aggregator (fan-side scans).
security in plain english.
- all traffic is TLS. no plaintext on the wire.
- API keys are hashed; refresh tokens are envelope-encrypted; passwords are hashed by supabase.
- row-level security is on for every public table; we use a BYPASSRLS service role server-side, never the public anon key for anything sensitive.
- a security report? email security@yala.la. we read every report. honest disclosure = honest fix.