---
title: "Keep personal data out of events · Agent Wranglers"
url: https://agentwranglers.se/playbook/analytics/privacy-and-consent/events-without-personal-data
id: ANA-8
level: Required
risk: data
updated: 2026-10-27
build: a2a6bdfed830
tokens: 850
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Keep personal data out of events

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Privacy and consent](https://agentwranglers.se/playbook/analytics/privacy-and-consent.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: ANA-8
- Level: Required
- Chapter: [Privacy and consent](https://agentwranglers.se/playbook/analytics/privacy-and-consent.md)
- Rule: Never put names, email addresses, phone numbers, free text or full URLs with query strings in event properties. Use an internal ID that analytics cannot turn back into a person.
- Check: A query over one day of events finds no `@`, no run of 8 or more digits and no `?` in any property value. The schema test fails on any property of type free string not marked as an ID.
- Risk: Data leaked or lost
- How: Give each user a random analytics ID that is separate from the account ID. That ID still singles out one person, so its events stay pseudonymised personal data. Consent, retention and access requests still apply to them. A hash of an email address is still personal data under GDPR Recital 26, because anyone with the address can match it. Strip query strings and fragments from page addresses before sending. Allow only enumerated values or numbers in properties, and no open text fields. Logs follow the same idea in [keep personal data out of logs](https://agentwranglers.se/playbook/operations/logs/logs-without-personal-data.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### SQL example

```sql
-- PostgreSQL: must return 0 rows
SELECT name, properties FROM events
WHERE received_at > now() - interval '1 day'
  AND properties::text ~ '@|[0-9]{8,}|\?';
```

### JavaScript example

```js
export const cleanPath = href => new URL(href).pathname;
```

### Python example

```python
from urllib.parse import urlsplit

def clean_path(href: str) -> str:
    return urlsplit(href).path
```

## Sources

- [GDPR Recital 26 on pseudonymised data](https://eur-lex.europa.eu/eli/reg/2016/679/oj)

## Related rules

- DEN-24 [Swap direct identifiers for keyed pseudonyms](https://agentwranglers.se/playbook/data-engineering/personal-data-in-the-warehouse/warehouse-pseudonyms.md) in Data engineering
- OPS-9 [Keep personal data out of logs](https://agentwranglers.se/playbook/operations/logs/logs-without-personal-data.md) in Operations and observability

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/analytics/privacy-and-consent/events-without-personal-data">Agent Wranglers product analytics and experiments playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Track only after consent](https://agentwranglers.se/playbook/analytics/privacy-and-consent/analytics-consent.md)
- Next: [Hide personal data from session recordings](https://agentwranglers.se/playbook/analytics/privacy-and-consent/session-recording-privacy.md)
- [Privacy and consent](https://agentwranglers.se/playbook/analytics/privacy-and-consent.md)
