# JavaScript API

> Every method on window.statsy: goals, identify, properties, consent, the visitor id and manual pageviews.

Section: Tracking script  
Canonical page: https://statsy.co/docs/tracking-script/javascript-api  
Last updated: 2026-09-15

The script defines `window.statsy`. Everything below is safe to call from anywhere on the page once the script has loaded.

## Methods

| Call | What it does |
| --- | --- |
| `statsy.goal(name, props?)` | Records a custom event or goal completion. Properties are strings, numbers or booleans. |
| `statsy.identify(props)` | Links the visitor to an identity such as email, name or id, so journeys show who they are and payments can be matched by email. Needs full mode. |
| `statsy.set(props)` | Adds properties to every later event sent from this page. |
| `statsy.consent('granted' \| 'denied')` | Passes a consent choice: granted switches to full mode, denied to cookieless and clears the cookie. Remembered in local storage. |
| `statsy.visitorId()` | Returns the visitor id in full mode, or undefined in cookieless mode. Use it to pass the visitor to a server-side checkout. |
| `statsy.pageview()` | Records a pageview by hand, for routers that do not use the History API. |
| `statsy.revenue(...)` | Kept for compatibility. Records a purchase conversion only; the amount is ignored, because revenue is counted from payment webhooks. |

```js
statsy.goal('signup', { plan: 'pro' });
statsy.identify({ email: 'ada@example.com', name: 'Ada' });
statsy.set({ workspace: 'acme' });
const vid = statsy.visitorId();
```

> **Watch out.** Amounts sent from a browser can be forged, so `statsy.revenue()` never sets a value. Real revenue comes from the payment provider webhooks you connect under **Site settings › Integrations**.

## Calling before the script loads

The tag is deferred, so a call at the top of your page may run first. Queue it instead: the script drains the queue as soon as it starts, and afterwards pushes run immediately.

```js
window.statsyq = window.statsyq || [];
statsyq.push(['goal', 'signup', { plan: 'pro' }]);
statsyq.push(['identify', { email: 'ada@example.com' }]);
```

Each entry is the method name followed by its arguments. Unknown names are ignored.

## Goals without JavaScript

Any element can record a goal on click, with no code at all. Each `data-statsy-prop-*` attribute becomes a property.

```html
<button data-statsy-goal="signup" data-statsy-prop-plan="pro">Start</button>
```

Click goals defined in the dashboard by CSS selector, scroll-depth goals and page-visit goals need no markup either. Page-visit goals are completed on the server, so they count for cookieless visitors too.

## Opting a visitor out

Setting the local storage key `statsy_optout` to `1` stops the script sending anything from that browser. An opt-out button on your site is one line:

```js
localStorage.setItem('statsy_optout', '1');
```

See [Exclude your own visits and bots](https://statsy.co/docs/tracking-script/exclude-visits) for the other ways to keep traffic out.

Previous: [Script reference](https://statsy.co/docs/tracking-script)  
Next: [Tracking modes and cookieless](https://statsy.co/docs/tracking-script/tracking-modes)