---
url: https://simpledatalogs.com/docs/reference/privacy.md
description: >-
  What senders should never send, what simpledatalogs masks or drops for you,
  how emails in identity fields become pseudonyms, and how to erase data.
---

# Privacy for senders

You decide what leaves your app. simpledatalogs adds a safety net, but the cleanest data is data you never sent. This page covers what to keep out, what we do for you, and how to erase what slipped through.

Under data-protection law, you are the controller of your users' data and simpledatalogs is your processor. See the [privacy policy](https://simpledatalogs.com/privacy) and the [data processing terms](https://simpledatalogs.com/data-processing).

## Never send these

* Email addresses, names, usernames and phone numbers.
* IP addresses, precise locations and advertising ids.
* Passwords, tokens, API keys and session cookies.
* Free text a user typed: search queries, messages, form fields.
* URLs with personal data in them, such as `/users/jane@example.com` or `?token=…`.

```js
// Avoid
sdl.track('signup', { email: user.email, referrer_url: document.referrer })

// Prefer
sdl.track('signup', { plan: 'pro', referrer: 'newsletter' })
```

::: warning JSON is stored as sent
Events and log objects you send as JSON, NDJSON or OTLP are structured data you chose to send, so they are **stored exactly as sent**. Masking only runs on text log lines. Filter personal data out before it leaves your app.
:::

## Identify devices, not people

To count active devices, send a **random install id** as `device_id`: a UUID generated on first launch and kept in local storage. It identifies an installation, not a person, and it resets on reinstall.

For apps that must avoid persistent identifiers, such as games aimed at children, don't send an identity field, and turn on **No device IDs** in the project's settings (owners only). Then, for new events:

* `device_id`, `install_id`, `anonymous_id`, `user_id` and `session_id` are dropped, from the columns and from props.
* The raw User-Agent is dropped; only the browser, OS and device type read from it are kept.
* Websites get no daily visitor hash, so the **Sessions** tab counts no visitors or visits.

Event counts, log lines, countries and browsers still work; device counts, device pages and visits don't. Events stored before the change keep what they had.

### Emails in identity fields become pseudonyms

If an email address does arrive in an identity field (`user_id`, `device_id` and the others, or OTLP's `user.id`), it isn't stored. It becomes a stable pseudonym:

```text
jane@example.com  →  email:3f9a1c0be27d4a6f81c2
```

The pseudonym is `email:` plus a keyed hash of the environment and the lower-cased address. Each user still counts once, and we never hold the address. The same email gives a different pseudonym in each environment.

A project's owner can choose to keep emails readable, in the New project dialog or the project's settings, after a warning. That applies to new events only, and means simpledatalogs then stores those addresses.

### Share links and installs

If your share page sends events with a `share_id`, ingest keeps a daily hash of the visitor's IP address for two days, so a later `app_installed` from the same address can be matched to that share. The address itself is never stored, and the hash never reaches your events. See [Share links and installs](/guide/share-links).

## What we mask or drop for you

### Text log lines

Before a text line is stored, these are masked in the message and in string props:

| Found | Stored as |
|---|---|
| Public IPv4 and IPv6 addresses | `[ip]` |
| Email addresses | `[email]` |
| Bearer credentials, JWTs, well-known API keys, values under secret names (`password`, `api_key`, `token` …) | `[token]` |
| Card numbers | `[card]` |
| Phone numbers | `[phone]` |

Access logs never keep the client IP, the user fields or any query string. The same masking applies to the Datadog, Loki and Splunk drop-ins, and to values captured by [text templates](/api/templates).

### Vendor payloads

* **Segment, PostHog, Mixpanel, Amplitude:** client IPs (`context.ip`, `$ip`, `ip`) and the vendor's keys (`writeKey`, `api_key`, `token`) are never stored.
* **Sentry:** the user's IP address, email and username, request headers, cookies, query strings, breadcrumbs and `extra` are never stored.
* **Datadog:** `usr.email` and `usr.name` are dropped.

### Request metadata

Ingest never stores your users' IP addresses. The address a request comes from is used in memory for rate limiting and a country lookup; only the country is kept. The `User-Agent` header is kept with each request.

The country comes from [IP Geolocation by DB-IP](https://db-ip.com), used under the CC BY 4.0 license.

## Erasing data

An organization owner can erase data from the dashboard:

* **One device:** open its page under **Devices** and erase every row of that identity.
* **One event name:** open the event's page and erase every event of that name.

Both need a recent sign-in and the exact id or name typed again, and both are audited. Rows go at once; copies in the 3-day recovery log and the 14-day backups age out, so an erasure is complete within 14 days.

## Your own users' consent

simpledatalogs uses no cookies. The script tag stores nothing in the browser: unsent events wait in memory and go out when the page is hidden. The npm package keeps unsent events in `localStorage` until they are delivered, and a session id in the tab's `sessionStorage`. Neither stores an identifier of its own; a `device_id` is only sent if you set one. Whether your site or app needs consent depends on what you send and where your users are, so check with your own counsel.

Use the opt-out in the [JavaScript](/sdks/javascript#opt-out), [Swift](/sdks/swift#the-opt-out), [Flutter](/sdks/flutter#the-opt-out), [Android](/sdks/android#the-opt-out), [Unity](/sdks/unity#the-opt-out), [Python](/sdks/python#the-opt-out) and [Go](/sdks/go#the-opt-out) SDKs to honour an opt-out. It also deletes everything not yet sent.

## Next steps

* [AGENTS.md snippet](/agents/agents-md): put these rules where your coding agents read them.
* [Laravel SDK](/sdks/laravel#keep-personal-data-out): drop context keys before they leave your server.
