Identify
activeThe Identify call ties an identity to a set of traits — everything you know about a person: their name, email, plan, or any custom attribute your business tracks. Together with Track, it is the whole tracking contract: Track records what someone did, Identify records who they are.
Binoban recommends calling Identify:
- After a user first registers
- After a user logs in
- When a user updates their info (for example, they change or add a new address)
Calling Identify is one of the first steps in integrating a Binoban library. Refer to the library-specific SDK pages for the exact call shape.
Example
A minimal Identify call needs only an identity and one or two traits:
{
"type": "identify",
"userId": "97980cfea0067",
"traits": {
"name": "Peter Gibbons",
"email": "peter@example.com",
"plan": "premium",
"logins": 5
}
}
The matching Web SDK call:
Binoban.identify("97980cfea0067", {
name: "Peter Gibbons",
email: "peter@example.com",
plan: "premium",
logins: 5,
});
A fuller payload, showing the fields you'll see on most real calls:
{
"type": "identify",
"userId": "97980cfea0067",
"anonymousId": "b7e1c9f0-6b2a-4e9a-9c3d-2f6a1d9e4b71",
"timestamp": "2026-07-26T14:32:00.000Z",
"traits": {
"firstName": "Peter",
"lastName": "Gibbons",
"email": "peter@example.com",
"plan": "premium",
"logins": 5
},
"context": {
"ip": "8.8.8.8",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36"
}
}
Identities
Every Identify call carries userId, anonymousId, or both — the same rule
that governs Track, since both calls validate
identity the same way:
| Field | Required? | Max length | Allowed characters |
|---|---|---|---|
userId | At least one of userId / anonymousId | 64 | a–z A–Z 0–9 _ - . @ : |
anonymousId | At least one of userId / anonymousId | 64 | a–z A–Z 0–9 _ - . @ : |
Omitting both rejects the call with error.sdk.missing.id. A value using
disallowed characters rejects it with error.sdk.user.id.pattern /
error.sdk.anonymous.id.pattern; a value over 64 characters also rejects the
call, but the exact code that response carries isn't confirmed — the length
check runs through generic validation, not the pattern check that's wired to
those codes. See Limits & validation
for the full rejection table.
Anonymous ID
There are cases where you don't know who the user is according to your database, but you still want to tie them to traits, events, or page views — for example, tracking a newsletter signup or an anonymous page view before sign-in.
In these cases, use an Anonymous ID. It can be any pseudo-unique identifier — a session id, for example. If you don't have one readily available, generate a new random one; Binoban recommends UUIDv4 format.
Binoban's browser and mobile libraries automatically manage Anonymous IDs as users navigate your site or app, so you don't need to generate or persist one yourself when using those libraries.
Here's an example Identify call for an anonymous user:
Binoban.identify({
subscriptionStatus: "inactive",
});
User ID
User IDs are a more permanent identifier, like a database ID. Since they're consistent across a customer's lifetime, Identify calls should include a User ID as often as possible.
A User ID is usually the identifier you already recognize a user by in your
own database — for example, a MongoDB document id like
507f191e810c19729de860ea.
Binoban recommends using a database ID as the User ID rather than an email address or username, because a database ID doesn't change even if the person later changes their email or username — so you can keep recognizing them as the same person across every tool that reads Binoban data.
Instead of using an email address or a username as the User ID, send them along as traits.
Traits
traits is an optional, free-form dictionary describing the person — name,
plan, logins, or any custom attribute your business tracks. This is the
point of Identify: give Binoban traits once, and every event tied to that
identity can be understood in terms of them.
Trait names (keys) follow the same rule as event and property names:
| Rule | Value |
|---|---|
| Max length | 64 characters |
| Allowed characters | a–z A–Z 0–9 _ - . |
A trait name over the limit or with disallowed characters rejects the whole
call (error.sdk.attribute.name.length / error.sdk.attribute.name.pattern).
Reserved traits
Binoban recognizes a small set of trait names as reserved: sent under these exact keys, they map onto known fields on the person's profile instead of being stored as an arbitrary custom attribute. Five of them also carry an enforced length limit at ingestion — a value over the limit is silently dropped from the call, the same as any other out-of-range trait value (see Limits & validation → System traits):
| Trait | Type | Max length |
|---|---|---|
firstName | String | 32 |
lastName | String | 32 |
email | String | 64 |
company | String | 64 |
jobTitle | String | 64 |
If you've integrated Segment-style tools before, two things differ here:
company is a plain string (a name), not an object with sub-fields, and the
job-title trait is named jobTitle, not title.
Binoban's profile model recognizes four more scalar reserved traits, but none of them carry a length limit of their own — an out-of-range value falls back to the generic value rules in Limits & validation → Value limits:
| Trait | Type |
|---|---|
phone | String |
gender | One of MALE, FEMALE, OTHER — matched case-insensitively, so "female" also works |
birthday | Date — stored as a timestamp, not a free-form string; send an ISO 8601 date |
timezone | String |
Five last reserved traits are booleans that each gate whether
Engage may contact this person on one channel — set
one to false to opt the person out of that channel, or true to opt them
back in. An unset flag behaves as opted-in.
| Trait | Engage channel |
|---|---|
smsOptIn | SMS |
emailOptIn | |
pushOptIn | Push |
webPushOptIn | Web push |
customOptIn | Custom channel |
SMS and email sends also require the person to actually have a phone or
email trait set — opting someone in on a channel with no contact info on
file still won't reach them.
Every other trait name — including some you may expect from other analytics
tools, like name, id, address, avatar, age, createdAt,
description, title, username, or website — is a plain custom trait to
Binoban. Send them if they're useful for your own reporting; Binoban stores
them, but attaches no special meaning or handling to the name itself.
Only send firstName, lastName, email, company, jobTitle, phone,
gender, birthday, and timezone when the value actually means what the
name says, and only flip an opt-in trait when you mean to change that
person's consent for that channel — Binoban's profile model and Engage act
on these values directly.
Any trait — reserved or custom — can also be configured as an identity matching key for your workspace, so that events carrying the same value resolve to one profile. Phone and email matching are not enabled by default; ask your Binoban team to turn them on if your integration depends on them. See Identity strategy → What's on by default.
Context
context on an Identify call is the same object documented in
Track → Context — environment and identity-adjacent
data about where the call came from (page, device, campaign, and so on).
The one real difference: Identify reads traits from the top-level traits
field, not from context.traits. context.traits is how a Track or
Page call carries traits collected on an earlier Identify call alongside an
event; Identify is the call that sets those traits in the first place, so it
doesn't need the nested form.
See Track for the shared context shape, and
Identity strategy for how Binoban uses
userId, anonymousId, and traits together to resolve events to one
profile.