Skip to content
TraceItX Docs
Documentation

User identity

Who filed this? There are two answers, and only one of them is proof.

Updated

Self-declared

traceitx.setUser({ id: 'u_1042', email: 'jane@example.com', displayName: 'Jane' });
traceitx.setUser(null); // on sign-out

This is an unauthenticated claim. Anyone who can open a console can call it with any values — and on a script-tag install the handle is often in scope of the page. It is genuinely useful, because most reports come from your own QA and beta users, but it is not evidence.

Verified

To make it evidence, supply a token your backend signed:

traceitx.setIdentityToken(async () => {
  const res = await fetch('/api/traceitx-identity');
  return res.text();
});

setIdentityToken accepts either a token string or a function returning one, sync or async. Prefer the function: the SDK re-asks it as the token nears expiry, so a long-lived session keeps a valid token without you tracking the clock. Pass null to clear it.

It is a method rather than a config field because the token source usually depends on auth state that does not exist yet when init() runs. Call init() at startup and setIdentityToken once the user signs in.

The server verifies the token and resolves the person itself, rather than trusting anything the client asserted.

The three tiers

A webhook receiver sees data.reporter, resolved server-side:

tierMeaning
verifiedA valid identity token was presented. This is proof.
self_declaredsetUser was called; nothing was verified.
anonymousNo person was resolved at all.

Use data.reporter, not data.report.reporter.user. The latter is whatever the app passed to setUser — an unauthenticated claim in every case, even when a valid token was also presented.

And anonymous does not mean “unverified” — it means nobody was resolved. Treat the three as distinct states, not a confidence gradient. See Webhooks.

What actually reaches the report

Whatever you pass to setUser is projected down to id, email and displayName. Extra keys are dropped rather than carried, so passing a whole user object does not quietly ship your internal fields.