> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bily.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Keep browser event data safe

> Collect only the customer data you need and keep secrets out of every browser tracking payload.

Browser events are visible to the person using the browser and to software running on the page. Treat every event field as public client data.

## Keep secrets out of events

Never send:

* Passwords or password-reset values
* Session cookies or authorization headers
* Access tokens, refresh tokens, or private API keys
* Payment card or bank-account details
* Private message bodies or document contents
* Full keystrokes or unredacted form submissions
* Raw error objects, request objects, or stack traces

The Bily tracking URL is public installation data. It does not need a private token.

Preserve the exact URL. Never add a private credential to it.

## Send only the customer data you need

Add a `client` field only when the event needs it and the visitor's consent state permits it.

```typescript theme={null}
track("user_signed_in", {
  client: {
    userId: "user_123",
    userGroup: "growth",
  },
});
```

Prefer a stable internal user ID over extra contact fields. Add email, phone, address, date of birth, or gender only when you have a documented purpose and permission.

## Reduce errors to safe codes

Map internal failures to a small, reviewed vocabulary.

```typescript theme={null}
type SafeErrorCode =
  | "validation_failed"
  | "network_unavailable"
  | "permission_denied"
  | "unknown";

track("product_error_encountered", {
  operation: "campaign_launch",
  error_code: toSafeErrorCode(error),
});
```

Do not attach `error`, `error.message`, request bodies, or user-generated content to the event.

## Honor consent and deletion choices

* Start optional customer-data tracking only after you know the required consent state.
* Stop sending optional fields when consent changes.
* Keep your event catalog and privacy notice consistent.
* Apply your retention and deletion process to every identifier you send.
* Review new custom properties before releasing them.

## Use browser identity only as context

`getBilyTrackingId()` returns a browser identifier. It does not prove account identity.

Never use it for authorization. Use a verified server session for protected actions.

## Apply your content security policy

`init({ nonce })` can copy your server-generated nonce to the script element. A nonce is a browser policy control, not an event property.

Never send it through `track()`.

## Review every tracking release

Before shipping a tracking change:

1. Inspect the exact event payload in a development environment.
2. Remove fields that are not required for the stated analysis.
3. Confirm no secret can enter through object spreading.
4. Test signed-out, signed-in, and consent-denied states.
5. Search the built browser assets for private tokens and credentials.

<CardGroup cols={2}>
  <Card title="Client data guide" icon="user-shield" href="/guides/client-data">
    Choose supported customer fields and respect identity boundaries.
  </Card>

  <Card title="Privacy governance" icon="shield-check" href="/guides/privacy-governance">
    Put ownership, classification, credential, and production controls in place.
  </Card>
</CardGroup>
