Identifying users
Kilden separates events (immutable) from persons (mutable). Every event carries a distinct_id; identity resolution maps distinct ids to persons so that pre-signup and post-signup activity belong to the same human.
Anonymous by default
Section titled “Anonymous by default”On first visit the SDK generates an anonymous id — anon_ + UUID v7 — persists it, and stamps it on every event. A person is created for it on the first event. No call needed.
identify() on login or signup
Section titled “identify() on login or signup”When you know who the user is, call identify with your stable user id (a database id works better than an email — emails change):
This emits a $identify event that carries both ids (the user id as distinct_id, the anonymous id as $anon_distinct_id). The pipeline then does one of two things:
- Your user id is new (the common case, ~90%): it’s added as another distinct id of the anonymous visitor’s person. All the pre-signup history is already attributed — nothing moves.
- Your user id already has a person (login on a second device): the two persons merge.
Call identify on every page where the user is logged in, not just at login — it’s idempotent, and it’s what keeps new devices and cleared browsers linked.
What a merge does
Section titled “What a merge does”- The older person wins (its
created_at); the newer person’s distinct ids are re-pointed to it. - Traits: the winner keeps its values on conflict; the loser only fills gaps. A later
$setoverwrites either way. - Past events keep working in queries: person merges are resolved at query time, so historical events attributed to the losing person count toward the winner.
Updating traits
Section titled “Updating traits”kilden.setPersonProperties( { plan: 'enterprise' }, // $set — overwrites { signup_source: 'organic' }, // $set_once — only if absent);Traits live on the person and can change; events are frozen at capture time. If you need a value to be trustworthy (billing plan, revenue), send it server-side with a secret key or as signed traits — anything a browser sends can be forged by the browser’s owner.
reset() on logout
Section titled “reset() on logout”kilden.reset();Rotates the anonymous id, clears the identity token and super properties. Skip this and the next person to log in on that browser gets linked to the previous user’s anonymous trail.
Rules that protect you
Section titled “Rules that protect you”- Two known ids never merge automatically. If an identified user somehow gets identified as a different known id, Kilden refuses the merge (it’s almost always an instrumentation bug), logs it, and attributes the event to the user id’s person. The web SDK deliberately has no
alias()—identifycovers the browser flow completely;$aliasexists in the pipeline for server SDKs, where linking two known ids is legitimate. - Distinct-id cap per person (100 by default) prevents runaway id accumulation (“person bloat”); past the cap, events still attribute but new mappings aren’t created.
- With identity verification in
enforcemode, an unverifiedidentifyfrom a browser cannot create or modify identity mappings at all.