Attribution
A user arrives from a Google ad, browses anonymously, creates an account two days later, and books on day four. Every major A/B platform counts that as three separate users. Tamda counts it as one.
See it in actionThe problem
A/B tools like Amplitude Experiment and LaunchDarkly assign users to variants at flag evaluation time. If the user isn't logged in, they either get a random anonymous bucket or they're excluded entirely.
The result: your experiment data doesn't reflect reality. A user who saw the treatment variant while anonymous and converted after login gets counted as two users: one anonymous exposure with no conversion, one new user with an unexplained conversion.
Your conversion rates are understated. Your attribution is wrong. Your Ship / Kill decisions are based on broken data.
User clicks Google ad
anonymousId: anon-7f3c
User sees treatment variant
Exposed, other platforms lose this
User browses for 2 days
Sessions tracked but not linked
User creates account
userId: usr_924, identity stitched
User completes booking
Conversion attributed to treatment
Red = dropped by other platforms. Tamda keeps the full chain.
The solution
On first page load, a device ID is assigned and stored. This ID follows the user across sessions before they log in, capturing every experiment exposure, UTM source, and page event from the very first visit.
anonymousId: "anon-7f3c"When a user logs in, creates an account, or completes a purchase, you fire one identify call. Tamda links the anonymous ID to the known user ID and retroactively attributes all prior sessions and experiment exposures.
POST /api/identifyUTM parameters are captured at the anonymous session level. When identity is stitched, the UTM data travels with it, so the booking that happened on day four is correctly attributed to the Google CPC click on day one.
utm: { source, medium, campaign }API reference
/api/eventsTrack an exposure or conversion. Accepts either anonymousId (before login) or userId (after login), or both.{
anonymousId?: string // persistent device ID
userId?: string // authenticated user ID
sessionId?: string // optional session grouping
flagKey: string // experiment identifier
variant: string // "control" | "treatment"
type: "exposure" | "conversion"
eventName?: string // required for conversion
utm?: {
source?: string
medium?: string
campaign?: string
content?: string
term?: string
}
}/api/identifyLink an anonymous ID to a known user. Call this on signup, login, or purchase. All prior anonymous sessions are retroactively stitched.{
anonymousId: string // the device ID to link
userId: string // the known user ID
criteria?: string // "signup" | "login" | "purchase"
}/api/experiments/:id/attributionReturns first-touch UTM attribution for an experiment, grouped by source, medium, and campaign, with exposure and conversion counts.// Response
{
byChannel: [
{
source: "google",
medium: "cpc",
campaign: "brand",
exposures: 1240,
conversions: 89,
conversionRate: 0.0718
},
...
]
}Three API calls. No SDK. Works with your existing event system.
Read the docsGet started free