Skip to content

Track the events metrics read

Custom metrics are a lens over events. This page is about sending those events. Everything you track lands in one event store, and metrics aggregate them at analysis time, so you send raw events here and shape them into numbers there.

There are three ways to emit an event. They all reach the same store and are interchangeable.

For anything that happens in the page, use the tracker. It already knows the visitor and session, so you only pass the event name and props.

Track from the browser
window.statskit?.track("checkout", { value: 4999, plan: "pro" });

value is in minor units (cents), so a $49.99 checkout is 4999. See tracking events for declarative data-statskit-* attributes and autocapture.

For events that only your backend can see (a webhook-confirmed payment, a job that completes), post them from the server with a ssk_ server key or a vsk_ secret key.

Track a server-side event
curl -X POST https://statskit.ai/api/v1/track \
-H "Authorization: Bearer ssk_live_…" \
-H "Content-Type: application/json" \
-d '{
"unit": "user_8f21",
"event": "checkout",
"value": 4999,
"currency": "usd",
"props": { "plan": "pro" },
"url": "/pricing",
"eventId": "evt_2026_ord_10432"
}'
FieldMeaning
unitThe id you experiment on (visitor id, user id, account id). Ties the event to the right assignment. Required.
eventThe event name a metric aggregates. Required.
valueAmount in minor units (cents). Read by sum / mean metrics.
currencyISO currency for the value, for example usd.
propsFree-form properties object.
urlThe page or context the event belongs to.
tsEvent timestamp (ms). Defaults to now.
eventIdIdempotency key. See below.

The @statskit/sdk server client wraps the same ingest and batches events for you (POST /v1/events under the hood). See the SDK overview for setup.

Track with the server SDK
await client.track("user_8f21", "checkout", {
value: 4999,
currency: "usd",
props: { plan: "pro" },
url: "/pricing",
eventId: "evt_2026_ord_10432",
});

The signature is client.track(unit, eventName, { value?, currency?, props?, url?, ts?, eventId? }).

Everywhere you send money, send minor units. $49.99 is 4999. This keeps sum and mean metric math exact and lets the usd format render it correctly.

Server events often fire from retryable code: webhook handlers, queue workers, cron jobs. Pass a stable eventId derived from the thing that happened (an order id, a Stripe event id) and StatsKit de-duplicates repeat deliveries so a single payment is not counted twice.

  • The event is a UI action the visitor takes (click, view, scroll).
  • The visitor is present and the tracker is loaded.
  • You want autocapture and automatic visitor/session context.

For revenue specifically, tracking server-side after the payment settles is the reliable path. See the server revenue recipe.