Identify and traits
Attach a person to a visitor, and keep your onboarding answers on them.
When someone logs in or gives you their details, say so. Everything that visitor did before is attached to them, and everything after.
identify alone does not send a network request. It stores the user id and
contact details on the tag; the next track (usually sign_up or login)
carries them. Call identify first, then the event. Without
advertising consent, contacts are dropped even when
you pass them.
vibiz.setConsent({ advertising: true }); // or from your CMP
vibiz.identify('cust_8842', {
email: 'mario.rossi@example.com',
phone: '+39 333 123 4567',
});
vibiz.track('sign_up', { method: 'email' });This closes the gap between browsing and buying. Someone browses anonymously for a week, logs in once, and buys a month later. The login is the only moment they say who they are, and it is rarely the moment that matters commercially.
Contact details accumulate rather than replace. A login gives an email, a checkout later adds a phone and an address, and both are kept.
Each contact detail is stored twice: hashed, which is the form Meta and Google match on, and readable, which is what lets you answer who signed up rather than only how many. Both come from the same normalised value, so the two can never disagree. Nothing is stored at all without advertising consent.
Traits
Pass anything else you know about someone in the same call. Onboarding answers are the usual case, and the most useful: they are first party, structured, and given deliberately by the person answering.
vibiz.identify('cust_8842', {
email: 'mario@agency.com', // recognised: hashed for matching, kept readable
business_type: 'agency', // anything else becomes a trait
team_size: 12,
goals: ['leads', 'sales'],
plan: 'free',
});One bag on the wire, split for you. Trait names are yours: there is no list to
pick from. Keys are levelled first, so businessType, business_type and
Business Type are one trait rather than three rows that each hold part of the
answer.
Traits live on the person, so an answer given at signup is still there on a purchase a month later. They accumulate, and a newer value replaces an older one:
// at signup
vibiz.identify('cust_8842', { plan: 'free', business_type: 'agency' });
// a month later, on upgrade
vibiz.identify('cust_8842', { plan: 'pro' });
// stored: { plan: 'pro', business_type: 'agency' }A multi step onboarding
Send each step as it is answered rather than collecting everything and sending it at the end. People abandon onboarding halfway, and the answers they did give are the ones that explain why.
// step 1, who they are
vibiz.identify(user.id, { email, business_type: businessType });
// step 2, what they want
vibiz.identify(user.id, { goals, team_size: teamSize });
// step 3, budget
vibiz.identify(user.id, { monthly_budget: monthlyBudget });
vibiz.track('sign_up', { method: 'email' });Each call adds to the profile. Nothing needs resending, and a visitor who stops at step two still carries the two answers they gave.
This is what lets a question be answered that neither analytics nor an ad platform can answer alone: which creative brings the customers who say they are an agency, and are they the ones who upgrade.
Traits are attributes, not notes
Strings, numbers, booleans and lists of strings, up to 50 of them. Nested objects are dropped, because an answer that cannot be grouped by cannot segment anything. Traits are never forwarded to an ad platform, so do not use them as a place to keep free text about a person.