Tracking Agent docs

User properties and identity in the Tracking Agent

The Tracking Agent treats user properties and identity calls like events: planned in the registry, sent through the typed tracker, checked on each PR. User properties live in _user_properties.yaml, and _identity.yaml says when your product identifies, resets and aliases users. The audit then checks both against your data.

By Ansh AgrawalUpdated

How is a user property defined in the registry?

yaml
# analytics/registry/_user_properties.yaml
properties:
  - name: plan_tier
    type: string
    example: free | pro | team
    operation: set                  # set | set_once | increment | append | unset
    set_via: server
    set_when: Plan purchase or change succeeds (payment webhook), and on login
    source: accounts.plan_tier      # the field it comes from
    question: Which plan are active users on, and how does usage differ by plan?
    pii: false
    status: implemented

A user property describes the person, not the moment, and stays on their profile until it's changed. Make something a user property when you'd segment every report by it: plan, role, company size, signup date, acquisition channel.

Which operation should a user property use?

OperationWhat it doesUse it for
setOverwrites the valueValues that change: plan_tier, role
set_onceKeeps the first valueFirst-time facts: signup_date, first_referrer, anything named first_*
incrementAdds to a numberRunning counts
appendAdds to a listLists that grow
unsetRemoves the propertyClearing a value that would now mislead

datalyze validate flags names that look like first-time values (starting first_, signup_, signed_up_, initial_ or acquisition_, or ending _at_signup) written with set instead of set_once. Set a property where the truth is: a plan tier is certain on the server after the payment webhook, not in the browser.

What goes in _identity.yaml?

yaml
identify:
  when: Sign-up completes and every login
  id_source: users.id      # an internal id, never an email or phone number
reset:
  when: Logout
alias: null                # null: deliberately not done

datalyze scan checks the file against the code and fails on identity calls the file doesn't declare, declared calls the code doesn't make, an email or phone number passed as the user id, and users who are identified but never reset. Write reset: null when the product has no logout.

When the Tracking Agent was installed on this site, the identity file recorded email addresses used as the user id on three forms. Replacing them with an internal id was the first real pull request the agent checked end to end, and the agent marked the change breaking because old profiles keyed by email won't merge with the new ones.

What does the PR check look for in user properties and identity?

SpecialistWhat it checks
CoverageNew fields on the user or account model that should become user properties
BreakageA property's source or timing moved, or identify now happens after events that need the user
Dead itemsA user property nothing sets any more, which leaves a stale value on every profile
Conventionsset where a first-time value needs set_once, and personal data in a property

When a property stops being written, the agent proposes deprecating it and, if the old value would mislead, an unset. Just deleting the call leaves the last value on every profile.

How do super properties and groups work in the Tracking Agent?

Super properties, sent on every event, are listed in _super_properties.yaml. Groups, for B2B products where events belong to a company or workspace, are listed in _groups.yaml with the properties set on each group. The typed tracker writes them with groups.company.set(companyId, { seat_count }) on the client and serverGroups.company.set(...) on the server, split by each property's set_via.

What does the audit check for user properties and identity?

  • How many active users have each user property, its type and its spread of values.
  • Stale values, where the tool can tell. The Mixpanel, PostHog and Amplitude recipes don't give staleness, so this check is skipped for them.
  • A property written from both the client and the server.
  • The share of events from identified users, flagged below 20%.
  • Duplicate profiles, where the tool reports them (the PostHog recipe does; Mixpanel's and Amplitude's don't), and a missing reset at logout.

Mixpanel documents how identify and user profiles behave, which is what these checks protect. The playbook chapter on identity stitching explains why one person counted as several breaks every per-user number.

Questions about user properties and identity

Why not just stop calling a user property we no longer need?

Because the last value stays on every profile and keeps showing up in reports. Deprecate the property, and unset it if the stale value would mislead.

Should we use the email address as the user id?

No. Use an internal id such as users.id. datalyze scan fails when an email or phone number is passed to identify, and email, name and phone belong on the profile, not in event properties.

Should user properties be set on the client or the server?

Where the truth is. Anything decided by a payment, a webhook or the database is set on the server with serverUser; a property written from both sides is flagged.

Can Datalyze check our identity setup?

Yes. Our analytics audit checks your identify and merge calls, so one person counts as one user.