Gleap only knows what your product tells it. Identifying your users, and sending along the handful of attributes you already have, is what turns a list of anonymous chats into something you can segment, route and personalise.
Call this once you know who someone is — after login, and again on a page reload while they're still signed in:
Gleap.identify("user-123", {
name: "Ada Lovelace",
email: "[email protected]",
plan: "pro",
company: { id: "acme", name: "Acme Inc." },
});The first argument is your own user id. Keep it stable — it's what ties a person's conversations together over time, so an id that changes between sessions produces a new contact each time.
Use Gleap.clearIdentity() on logout, or the next person at that browser inherits the session.
When something changes mid-session — they upgrade, they complete setup — send just that:
Gleap.updateContact({ plan: "enterprise" });Passing null for a field clears it.
Some names have a meaning: name, email, phone, avatar, plan, value, sla, createdAt, tags and the company object. They land in the right places in the dashboard — the email is the address you reply to, the avatar is the picture your agents see.
Anything else you send becomes custom data: seats, trial end date, the feature flags you care about.
Gleap.identify("user-123", {
name: "Ada Lovelace",
email: "[email protected]",
customData: {
seats: 25,
trialEndsAt: "2026-09-01",
hasBilling: true,
},
});Attribute keys are case-sensitive. trialEndsAt and trialendsat are two different attributes, and filters, audiences and segments match the exact casing — so a rule built on one silently ignores everything sent under the other.
The attribute editor warns you about this: if your recent contact data uses a different spelling than the field ID you're configuring, it says so. Take the warning seriously; it's the difference between a segment that works and one that quietly returns nobody.
Text, a number, true/false, a date, or an array of those. Nested objects aren't stored — flatten them first (billingPlan rather than billing: { plan }), and turn an object you need into a couple of separate attributes.
Send the few attributes you'd actually filter or segment on. There's a limit on how many custom attributes one contact can carry, and a contact page with fifty of them is harder to read than one with six.
Attributes say what someone is. Events say what they did:
Gleap.trackEvent("invited-teammate", { count: 3 });Events show up on the contact's page, and they're what outbound messages and workflows can react to — a checklist that advances when someone finishes setup, a survey after a first successful export.
Name them for what happened, in one consistent style. “invited-teammate” and “Invite Sent” and “invite_teammate” are three different events, and only one of them will match the rule you write six months from now.
Gleap already tracks page views on its own, so you don't need to send those.
Trigger it in your own product, then open your own contact in Gleap. Attributes appear under custom data in the sidebar; events appear in the contact's activity. If nothing shows up, check that identify ran at all — a contact still marked as a guest is the usual explanation.