Docs · Guide

Identifying users

Out of the box Statlark counts anonymous visitors — one id per browser. Call identify once you know who someone is, and Statlark ties that browser to a durable person: their activity and revenue follow them across devices and sessions, and they show up on your People view with a lifetime value and a full cross-device journey.

Identify a user

Once the tracker snippet is installed, call statlark.identify() from your app the moment a visitor becomes known — typically right after login or signup:

// Call this once your user is known — right after login or signup.
statlark.identify({
  user_id: "user_123",          // your app's stable id (set once, never reused)
  user_email: "jo@example.com", // lets Stripe payments stitch to this person
  user_name: "Jo Rivera",
  traits: { plan: "pro" },
});

Every field is optional. The ones that matter:

  • user_id— your app’s stable id for the person. This is the anchor for cross-device merge, so pick something that never changes and is never reused(a database id, not an email or username). It’s write-once: once a person has a user_id, later calls won’t reassign it.
  • user_email — stored lower-cased. Unlike user_id it can change over time (latest wins). Sending it also lets payments that carry only a customer email — like Stripe charges — attach their revenue to this person.
  • user_name and user_image — a display name and avatar URL, shown on the People view.
  • traits — any extra key/values you want to keep on the person (plan, company, signup source…). Capped at 20 keys with primitive values, same as goal properties.

Calls are a merge, not a replace: only the fields you pass are updated, so a later call carrying just new traits won’t wipe an email or name set earlier.

// Only the fields you pass are updated — this won't clear the email or name
// set by an earlier call. Good for keeping traits fresh as things change.
statlark.identify({ traits: { plan: "enterprise" } });

How cross-device merge works

A person is keyed by their user_id and/or their user_email. When the same user_id shows up on a second device — your user logs in on their phone as well as their laptop — the two browsers roll up into one person, and their sessions, revenue and timeline combine. The People view shows how many devices are merged into each person.

Merging also reaches back through email. A payment that carries only a customer email (the usual case for Stripe and other providers) is stitched to the matching person even if that browser never called identify — so revenue lands on the right person whether it came from the client or a server-side webhook. If a user_id and an email each already point at different people, Statlark merges them into one, keeping the older record.

Lifetime value

Each person’s lifetime value is the sum of their payments in your site’s currency — recomputed from the payments themselves, so it can never drift out of step with your Overview revenue. Payments in a different currency are recorded but excluded, and refunds aren’t subtracted, exactly matching how the rest of Statlark totals revenue.

Identifying from your server

You can do the same thing server-side with POST /api/v1/identify. It’s the ad-blocker-immune twin of statlark.identify() — pass the person’s visitor_id plus the same identity fields. It has the same merge semantics: only the fields you send are updated.

The People view

Identified people appear under People, ranked by lifetime value — each row showing whether they’re a customer, the channel that first brought them in, their sessions, when you last saw them, and how many devices are merged. Open anyone to see their full cross-device journey: every pageview, goal and payment in order, wherever it happened.

Identity is entirely opt-in — Statlark only knows what you choose to send. If you track cookielesslyor need to honor a deletion request, nothing here changes that: don’t call identifyfor visitors you shouldn’t, and personal data stays out.