# Identify

 See our API documentation for code samples

This page can help you better understand when and how to use this API method. But, if you already know how it works and are ready to get started, you can go straight to our [API documentation](/integrations/api/cdp) and start writing code.

## How it works[](#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 person keeps them in memory, so that future calls reference the identified person. This saves you the trouble of sending identifying information with every call.

 See our API documentation for code samples

This page can help you better understand when and how to use this API method. But, if you already know how it works and are ready to get started, you can go straight to our [API documentation](/integrations/api/cdp) and start writing code.

## When to send an identify 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](/accounts-and-workspaces/how-we-bill).

If you use our [JavaScript client](/integrations/data-in/connections/javascript/js-source-identities), we’ll automatically apply the right identity to calls after you identify a person. 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 person’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-call)

A typical identify call is relatively straightforward. It contains a `userId` and a `traits` object. The `userId` is a unique identifier for the person you’re identifying. The [traitsA 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.](/journeys/attributes/) object contains information about the person, like their name, email address, and so on.

While this is the general shape of your call, our libraries actually capture much more information. See the [full payload below](#complete-payload). 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.

```javascript
cioanalytics.identify('97980cfea0067', {
  firstName: 'cool',
  lastName: 'person',
  email: 'cool.person@example.com'
});
```

## The full payload[](#complete-payload)

While your requests are typically short, our libraries capture much more information. This helps us provide context, not only for the person 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](/integrations/data-in/source-spec/common-fields) for more information about context, integrations, and timestamps in source payloads.

```json
{
  "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"
      ]
    }
  }
}
```

*   integrations object
    
    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": false` to reverse this behavior.
    
    *   *Enabled/Disabled integrations\** boolean
        
*   messageId string
    
    A unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
    
*   receivedAt string  (date-time)
    
    The ISO-8601 timestamp when Data Pipelines receives an event.
    
*   sentAt string  (date-time)
    
    The ISO-8601 timestamp when a library sends an event to Data Pipelines.
    
*   timestamp string  (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.
    
*   traits object
    
    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.
    
    *   createdAt string  (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.
        
    *   email string
        
        A person’s email address. In some cases, you can pass an empty `userId` and we’ll use this value to identify a person.
        
    *   *Additional Traits\** any type
        
        Traits that you want to set on a person. These can take any JSON shape.
        
*   type string
    
    The event type. This is set automatically by the request method/endpoint.
    
    Accepted values:`identify`
    
*   version number
    
    The version of the API that received the event, automatically set by Customer.io.
    

## Identifiers: User ID and Anonymous ID[](#identifiers-user-id-and-anonymous-id)

You identify people with a unique value: either a `userId` or an `anonymousId`. The `userId` is typically a UUID/ULID that represents that person 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](#user-id) or an [Anonymous ID](#anonymous-id)**.

### User ID[](#user-id)

User IDs are a more permanent identifier for a person, like a database ID that represents a person across all your backend services. Since these IDs are consistent across a customer’s lifetime, you should use them to `identify` a person as soon as you know who they are.

### Email as a `userId`[](#email-as-a-userid)

Customer.io lets you identify people by email address. So, as long as email addresses are unique to individual people in your use case, you can pass an email address as the `userId`. We’ll parse emails and automatically set them as `email` [attributesA 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.](/journeys/attributes/) for you. This provides a handy way to identify people as leads when they’ve just provided their email address and then pass a database identifier for them when they become a customer, user, etc.

While this works really well for Customer.io, it doesn’t necessarily work for all integrations. Some services don’t support email addresses as `userId`s, 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 `userId`s.

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 toAn integration that sends data *out* of Customer.io. using [the `integrations` object](/integrations/data-in/source-spec/common-fields/#the-integrations-object). Or you can modify your [integration’s actions](/integrations/data-out/actions/) to exclude calls that use an email address as a `userId`.

### Anonymous ID[](#anonymous-id)

In many cases, you may not know who a person 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 person 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](http://en.wikipedia.org/wiki/Universally_unique_identifier).

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:

```js
cioanalytics.identify({
  subscriptionStatus: 'inactive'
});
```

### Customer.io Journeys doesn’t support anonymous identify calls yet[](#customerio-journeys-doesnt-support-anonymous-identify-calls-yet)

While many integrations support anonymous `identify` calls, Customer.io does not support anonymous `identify` calls yet. Journeys will ignore anonymous `identify` calls because anonymous activity in Journeys is based on events.

**This doesn’t mean you shouldn’t send anonymous `identify` calls**, even if you only connect to Journeys though. For example, if you use our [JavaScript client](/integrations/data-in/connections/javascript/), anonymous `identify` calls store traits in local storage and attach them to subsequent `identify` calls. This means that when you formally identify a person 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)

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.