Identify
How it works
The Identify method helps you represent a user and their traits — the things you know about them, like their name, email address, and so on. When you use most of our libraries, like our JavaScript client, identifying a profile keeps them in memory, so that future calls reference the identified profile. This saves you the trouble of sending identifying information with every call.
When to send an identify call
While things vary based on the SDK or library you use, you should send an identify call when someone:
- First registers with your service
- Logs into your service or app
- Update their information—like when they change their email address, add a phone number, or set their subscription preferences
In general, you shouldn’t send an identify call on every page load. Beyond the three cases above, additional identify calls are unnecessary and could cause you to hit your plan’s limits.
If you use our JavaScript client, we’ll automatically apply the right identity to calls after you identify a profile. We store identity information in a cookie and local storage; if these values are present, you don’t need to send another identify call unless you want to update the profile’s traits.
If you use our other libraries, you’ll need to add the anonymousId or userId to your calls, but making additional identify calls won’t fetch this information for you.
A typical call
A typical identify call is relatively straightforward. It contains a A key-value pair that you associate with a person or an object—like a person's name, the date they were created in your workspace, or a company's billing date etc. Use attributes to target people and personalize messages.userId and a traits object. The userId is a unique identifier for the profile you’re identifying. The traits
While this is the general shape of your call, our libraries actually capture much more information. See the full payload below. You can send additional objects in your call, overriding the information that our libraries typically capture, but you’ll need to find documentation for your specific library for details.
cioanalytics.identify('97980cfea0067', {
firstName: 'cool',
lastName: 'person',
email: 'cool.person@example.com'
});
The full payload
While your requests are typically short, our libraries capture much more information. This helps us provide context, not only for the profile you identify, but the service you identify them from.
Customer.io and our libraries typically populate integrations and timestamp values as shown in the payload below. If you use our JavaScript or mobile libraries, they’ll also populate context for you. If you use our server-side libraries, you’ll need to populate context yourself.
See common fields for more information about context, integrations, and timestamps in source payloads.
{
"type": "identify",
"traits": {
"name": "Cool Person",
"email": "cool.person@example.com",
"likes_baseball": true,
"games_attended": 5
},
"userId": "97980cfea0067",
"integrations": {
"All": true
},
"messageId": "string",
"receivedAt": "2019-08-24T14:15:22Z",
"sentAt": "2019-08-24T14:15:22Z",
"timestamp": "2019-08-24T14:15:22Z",
"version": 0,
"context": {
"active": true,
"ip": "string",
"locale": "string",
"userAgent": "string",
"channel": "browser",
"campaign": {
"name": "string",
"source": "string",
"medium": "string",
"term": "string",
"content": "string"
},
"page": {
"name": "string",
"path": "string",
"referrer": "string",
"search": "string",
"title": "string",
"url": "string",
"keywords": [
"string"
]
}
}
}
- userIdstringThe unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources _and_ destinations.
- anonymousIdstringA unique substitute for a User ID in cases when you don’t have an absolutely unique identifier. Our libraries generate this value automatically to help you track people before they sign up, log in, provide their email, etc.
- typestringThe event type. This is set automatically by the request method/endpoint.Accepted values:
identify - Additional properties that you know about a person. We've listed some common/reserved traits below, but you can add any traits that you might use in another system.
- emailstringA person's email address. In some cases, you can pass an empty
userIdand we'll use this value to identify a person. - createdAtstring(date-time)We recommend that you pass date-time values as ISO 8601 date-time strings. We convert this value to fit destinations where appropriate.
- Additional Traits *any typeTraits that you want to set on a person. These can take any JSON shape.
- A dictionary of context about a source call/event, like the user’s IP address or locale. Context is automatically collected by our source libraries.
- activebooleanWhether a user is active.
This is usually used when you send an .identify() call to update the traits independently of when you've “last seen” a user.
- ipstringThe user's IP address. This isn't captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
- localestringThe locale string for the current user, e.g.
en-US. - userAgentstringThe user agent of the device making the request
- channelstringThe channel the event originated from.Accepted values:
browser,server,mobile - Contains information about the campaign that resulted in the API call, gathered from, or mapping to, UTM parameters (e.g.
utm_source).- namestringThe campaign name.
- sourcestringThe source of traffic—like the name of your email list, Facebook, Google, etc.
- mediumstringThe type of traffic a person/event originates from, like
email, orreferral. - termstringThe keyword term(s) a user came from.
- contentstring
- Additional UTM Parameters *string
- Contains information about the current page in the browser. This is automatically collected by our JavaScript source.
- namestringThe name of the page. Reserved for future use.
- pathstringThe path portion of the page's URL. Equivalent to the canonical
pathwhich defaults tolocation.pathnamefrom the DOM API. - referrerstringThe previous page's full URL. Equivalent to
document.referrerfrom the DOM API. - searchstringThe query string portion of the page's URL. Equivalent to
location.searchfrom the DOM API. - titlestringThe page's title. Equivalent to
document.titlefrom the DOM API. - urlstringA page's full URL. We first look for the canonical URL. If the canonical URL is not provided, we'll use
location.hreffrom the DOM API. - keywordsarray of [ strings ]A list/array of keywords describing the page's content. The keywords are likely the same as, or similar to, the keywords you would find in an HTML
metatag for SEO purposes. This property is mainly used by content publishers that rely heavily on pageview tracking. This isn't automatically collected.
- Contains a list of booleans indicating the integrations that are enabled (true) or disabled (false). By default, all integrations are enabled (returning an empty object). Set
"All": falseto reverse this behavior.- Enabled/Disabled integrations *boolean
- messageIdstringA unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
- receivedAtstring(date-time)The ISO-8601 timestamp when Data Pipelines receives an event.
- sentAtstring(date-time)The ISO-8601 timestamp when a library sends an event to Data Pipelines.
- timestampstring(date-time)The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill data past events. If you're not backfilling data, you can leave this field empty and we'll use the current time or server time.
- versionnumberThe version of the API that received the event, automatically set by Customer.io.
Identifiers: User ID and Anonymous ID
You identify profiles with a unique value: either a userId or an anonymousId. The userId is typically a UUID/ULID that represents that profile across your backend services, though it can take any form you like as long as it’s unique. An anonymousId is a value you assign to someone you don’t know yet. Every identify call must have a User ID or an Anonymous ID.
User ID
User IDs are a more permanent identifier for a profile, like a database ID that represents a profile across all your backend services. Since these IDs are consistent across a customer’s lifetime, you should use them to identify a profile as soon as you know who they are.
Email as a userId
Customer.io lets you identify profiles by email address. So, as long as email addresses are unique to individual profiles in your use case, you can pass an email address as the A key-value pair that you associate with a person or an object—like a person's name, the date they were created in your workspace, or a company's billing date etc. Use attributes to target people and personalize messages.userId. We’ll parse emails and automatically set them as email attributes
While this works really well for Customer.io, it doesn’t necessarily work for all integrations. Some services don’t support email addresses as userIds, and some require a unique identifier that’s consistent across all your backend services. If you do pass email as a userId, you should check that your integrations support email addresses as userIds.
If you need to send email as an identifier, and some of your integrations don’t support that kind of model, you can filter the places you send your data to An integration that sends data out of Customer.io.integrations object. Or you can modify your integration’s actions to exclude calls that use an email address as a userId.
You can’t use phone as a userId
Unlike email, a phone number can’t serve as a userId in the Pipelines API. Even if your workspace enables phone as an identifier, that only applies to data sent through the Track v2 API. The Pipelines API can’t check your workspace’s identifier settings, so a phone number sent as a userId is stored as a regular id, not a phone identifier.
Send phone numbers as the phone trait and identify people by id or email. Learn more about how to identify people.
Anonymous ID
In many cases, you may not know who a profile is yet — like when someone browses your website before they sign up for an account or log in. But in these cases, you may still want to capture information they voluntarily provide, events they perform, and pages they view. In these cases, you can reference a profile with an Anonymous ID.
The Anonymous ID can be any pseudo-unique identifier. If you use our JavaScript library, we automatically generate anonymous IDs for you. But for our server and other libraries, you might use a session id. If you don’t have any readily available identifier, you can always generate new UUIDs.
Because our JavaScript library automatically generates anonymous IDs, you can send a request without the identifier and our library automatically inserts it. Here’s an example of a JavaScript identify call for an anonymous user:
cioanalytics.identify({
subscriptionStatus: 'inactive'
});
Customer.io doesn’t support anonymous identify calls yet
While many integrations support anonymous identify calls, Customer.io does not support anonymous identify calls yet. Customer.io will ignore anonymous identify calls because anonymous activity in Customer.io is based on events.
This doesn’t mean you shouldn’t send anonymous identify calls, even if you only connect to Customer.io though. For example, if you use our JavaScript client, anonymous identify calls store traits in local storage and attach them to subsequent identify calls. This means that when you formally identify a profile later, you don’t need to capture a bunch of traits at the same time; the JavaScript client library will automatically associate their traits with their userId.
Traits
Traits are things you know about your audience, like their email addresses, names, the plan they’re on, and so on. You’ll include traits in identify calls.
We reserve some traits that have semantic meanings for users because we handle them in special ways. For example, we always expect email to be a string of the user’s email address. We’ll send this on to outbound integrations that require an email address for their tracking.
You should only use reserved traits for their intended meaning.
| Trait | Type | Description |
|---|---|---|
address | Object | Street address of a user optionally containing: city, country, postalCode, state, or street |
age | Number | Age of a user |
avatar | String | URL to an avatar image for the user |
birthday | Date | User’s birthday |
company | Object | Company the user represents, optionally containing: name (String), id (String or Number), industry (String), employee_count (Number) or plan (String) |
createdAt | Date | Date the user’s account was first created. |
description | String | Description of the user |
email | String | Email address of a user |
firstName | String | First name of a user |
gender | String | Gender of a user |
id | String | Unique ID in your database for a user |
lastName | String | Last name of a user |
name | String | Full name of a user. If you only pass a first and last name we automatically fill in the full name for you. |
phone | String | Phone number of a user |
title | String | Title of a user, usually related to their position at a specific company. Example: “VP of Engineering” |
username | String | User’s username. This should be unique to each user, like the usernames of Twitter or GitHub. |
website | String | Website of a user |
Some integrations might represent these traits with slightly different names. For example, Mixpanel recognizes a $created trait when a user is first created, while Intercom recognizes the same trait as created_at. We attempt to handle all the integration-specific conversions for you automatically.
You can pass reserved traits using camelCase or snake_case. For example, in JavaScript you can match the rest of your camel-case code by sending firstName, while in Python you can match your snake-case code by sending first_name. That way the API never seems alien to your code base. However, you should keep in mind that some destinations might not support all reserved traits; if an integration doesn’t support a reserved trait and you send it in camelCase and snake_case from different integrations, you may see both versions of your trait in the service you integrate with.