GDPR & retention
Right to erasure
DELETE /v1/actors/:id
Anonymizes all events for a given actor in the calling project. The rows are kept so the chain link to surrounding events stays intact, but actor_name, actor_email, metadata, ip_address and user_agent are nulled. actor_id is replaced with [deleted] and anonymized_at is stamped with the erasure time.
curl -X DELETE "https://api.recalled.dev/v1/actors/user_123" \
-H "Authorization: Bearer $RECALLED_API_KEY"Pass an optional organization query param to scope the erasure to a single tenant:
curl -X DELETE "https://api.recalled.dev/v1/actors/user_123?organization=org_acme" \
-H "Authorization: Bearer $RECALLED_API_KEY"Verification knows about this: rows with anonymized_at are skipped when recomputing the hash (the payload no longer matches the stored hash by design), while the chain link from the event BEFORE and the event AFTER is still enforced. So GDPR erasure satisfies Article 17 without creating a tampering blind spot.
Retention
Each plan has a default retention:
- Free, 7 days
- Starter, 90 days
- Pro, 1 year (configurable per event with custom rules)
- Scale, unlimited (configurable per project)
On the Pro and Scale plans, you can define retention rules per event pattern from the project settings. user.delete at 10 years, user.login at 30 days, * at 1 year, whatever your compliance team asks. On Pro, anything not matched by a rule falls back to the 1-year plan retention. On Scale, anything not matched stays forever.
Proof of purge
Every time a batch of events is deleted, a row is written in retention_checkpoints with the last deleted hash, the count, the date range, and the reason (plan_retention, rule:<id>, or project_deleted when a whole project is removed). The verify endpoint reads these checkpoints so chain gaps created by legitimate purges do not look like tampering.