The tracker exposes a small JavaScript API on `window.purestats`.

## Track a pageview

```js
window.purestats?.('pageview');
```

## Track an event

```js
window.purestats?.('Signup Completed');
```

With properties:

```js
window.purestats?.('Signup Completed', {
  source: 'header'
});
```

## Identify a signed-in user

Use a stable, opaque internal ID to connect visits from the same signed-in user. PureStats transforms the value with a site-specific HMAC before storage.

```js
purestats('identify', 'internal-user-42')
// or, after the tracker has loaded
purestats.identify('internal-user-42')
```

Visitor-scoped custom properties can be supplied with the identity call after defining them in **Site settings → Custom dimensions**:

```js
purestats.identify('internal-user-42', {
  account_type: 'customer',
  trial_active: true
})
```

Call `purestats('resetIdentity')` or `purestats.resetIdentity()` when the user logs out or switches accounts. Never send names, email addresses, phone numbers, or other directly identifying values.

## Set consent

```js
window.purestats?.consent.grant();
```

Disable tracking after consent is revoked:

```js
window.purestats?.consent.revoke();
```

## Assign and expose an experiment

Create and start the experiment in **Analytics → More → Experiments**. PureStats then loads the optional experiment module from the server-side tracker configuration. Wait for the ready event before assigning a variant:

```js
window.addEventListener('purestats:experiments-ready', () => {
  const variant = purestats.assignExperiment('homepage_headline');
  document.documentElement.dataset.headlineVariant = variant;
  purestats.trackExposure('homepage_headline', variant);
});
```

`assignExperiment()` is deterministic for the browser and configured weights. It does not count an exposure until `trackExposure()` is called, so visitors who never see the tested UI do not enter the result. PureStats stores only a site-scoped hash and never stores the local assignment identifier.

## Load timing

Because `pf.js` is usually loaded with `defer`, the API may not exist immediately in inline scripts placed before it. Run custom tracking after the page is ready or after your application initializes.

## Data safety

Do not send personal data in event names, paths or properties.
