# Identify

The `identify` call allows you to identify a visiting user and associate their actions to that identity. It also lets you record traits about the user like their name, email address, etc.

{{< info >}}
As a best practice, make sure `identify` is called at the start of every session or page load for logged-in users, if possible. This will ensure all the latest traits are captured.
{{< /info >}}

## When should I call identify?

Ideally, you should make an `identify` call in the following scenarios:

- After a user registers on your website or app.
- After a user logs in to your site or app.
- When a user updates their information, for example, residential address, email ID, etc.
- (Optional) When you load a page accessible by a logged-in user. This is required only when you have a downstream tool with such requirement (for example, Intercom).

## Sample payload

Here is a sample payload for an `identify` event after removing [Common fields]({{< ref "event-spec/standard-events/common-fields.md" >}}):

```json
{
  "type": "identify",
  "context": {
    "traits": {
      "name": "Richard Hendricks",
      "email": "rhedricks@example.com",
      "logins": 2
    }
  },
  "userId": "27340af5c8819"
}
```

The corresponding event that generates the above payload via the [JavaScript SDK]({{< ref "sources/event-streams/sdks/rudderstack-javascript-sdk/_index.md" >}}) is:

```javascript
rudderanalytics.identify("27340af5c8819", {
  name: "Richard Hendricks",
  email: "rhedricks@example.com",
  logins: 2
})
```

## Send a sample `identify` call

Use RudderStack's **Event Playground app** to send sample events to RudderStack and test the data flow without any instrumentation.

Click **Send** to see the API call in the **Network** tab of your browser's developer tools.

{{< script-app-identify >}}

{{< customreadfile "/includes/send-test-events.md" >}}

## Identify fields

The `identify` call has the following fields in addition to the [Common fields]({{< ref "event-spec/standard-events/common-fields.md" >}}):

| **Field** | **Type** | **Presence** | **Description** |
| :-------- | :------- | :------------------- | :-------------- |
| `userId`  | String   | Optional, **if** `anonymousId` is set | Your user's unique identifier. Every `identify` call requires a `userId` or an `anonymousId`. |
| `traits`  | Object   | Optional | Includes the traits of the user such as their `name`, `email`, etc. For more more information, check the [Traits](#identify-traits) section below. |

{{< warning >}}
The field names can change slightly depending on the SDK. However, the functionality remains the same.

See the [SDK-specific documentation]({{< ref "sources/event-streams/sdks/_index.md" >}}) for the implementation specifics and details on the above fields.
{{< /warning >}}

## User ID vs Anonymous ID

RudderStack requires every `identify` call to have either a `userId` or an `anonymousId`. This section highlights the differences between the two.

### User ID

A user ID \(`userId`\) uniquely identifies your user in your database. It is a permanent identifier of your customer which never changes - like a database ID.

{{< info >}}
For `identify` calls, include a `userId` as often as possible to identify the most up to date traits of the customer.
{{< /info >}}

{{< success >}}
It is recommended to use a database ID as the `userId` instead of usernames or email addresses. This is because users may update their username or email address at any point in the future. Instead, pass these attributes as **traits**.
{{< /success >}}

### Anonymous ID

There are instances where you may get a visitor on your website/app who may or may not be your customer. Nonetheless, you still want to track their actions and tie them to various events, page views, and traits. In such cases, you should use an Anonymous ID \(`anonymousId`\) to identify this user.

{{< info >}}
An anonymousId can be any identifier. For instance, a session ID corresponding to the visitor's session. If you don't have a readily available identifier, we recommend generating a **UUID**.
{{< /info >}}

{{< success >}}
RudderStack's web and mobile [SDKs]({{< ref "sources/event-streams/sdks/_index.md" >}}) automatically use anonymous IDs to track unknown users on your website or mobile apps, so you don't have to worry about including an `anonymousId` explicitly.
{{< /success >}}

### Set a custom user ID (`externalId`)

You can pass a custom ID (`externalId`) along with the standard `userId` in your `identify` call. RudderStack adds this value under `context.externalId`.

The following code snippet shows how to add an `externalId` to your `identify` event using the [JavaScript SDK]({{< ref "sources/event-streams/sdks/rudderstack-javascript-sdk/" >}}), before sending it to the [Braze]({{< ref "destinations/streaming-destinations/braze/_index.md" >}}) destination:

```javascript
rudderanalytics.identify(
  "1hKOmRA4GRlm", {
    firstName: "Alex",
    city: "New Orleans",
    country: "Louisiana",
    phone: "+1-202-555-0146",
    email: "alex@example.com",
    custom_flavor: "chocolate",
  } {
    externalId: [{
      id: "<external_id>",
      type: "brazeExternalId",
    }, ],
  }
);
```

## Identify traits

Traits are additional user information included in an `identify` call. Some examples of traits include age, gender, or some specific details - for example, a user's product plan (basic, premium, and so on).

{{< info >}}
There are some differences in the way RudderStack captures and sends the user traits across different SDKs. While RudderStack ideally sends the user traits in the [`context.traits`]({{< ref "event-spec/standard-events/common-fields.md#contextual-fields" >}}) object (as in case of [JavaScript SDK]({{< ref "sources/event-streams/sdks/rudderstack-javascript-sdk/_index.md" >}})), for some SDKs it also sends the user traits in the root-level `traits` object (for backward compatibility).

Refer to the [SDK-specific documentation]({{< ref "sources/event-streams/sdks/" >}}) for more details on sending user traits.
{{< /info >}}

After making an `identify` call, user traits are not required in subsequent calls. You only need to include changed/updated traits since the last `identify` call.

RudderStack has some reserved traits that it handles in special ways. These are listed in the table below:

<table>
  <thead>
    <tr>
      <th style="text-align:left">
        <b>Trait</b>
      </th>
      <th style="text-align:left">
        <b>Type</b>
      </th>
      <th style="text-align:left">
        <b>Description</b>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">id</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">Fallback parameter used only for mapping data <b>if</b> <code class="inline-code">userId</code> is not available in the event payload. </td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">firstName</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">User's first name</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">lastName</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">User's last name</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">name</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">
        <p>Full name of the user. If you already passed the <code class="inline-code">firstName</code> and <code class="inline-code">lastName</code>, RudderStack will automatically fill this field.</p>
      </td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">age</code>
      </td>
      <td style="text-align:left">Number</td>
      <td style="text-align:left">User's age</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">email</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">User's email address</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">phone</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">User's phone number</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">address</code>
      </td>
      <td style="text-align:left">Object</td>
      <td style="text-align:left">
        <p>User's street address. This can optionally contain either/all of the following fields:</p>
        <ul>
          <li>
            <code class="inline-code">city</code>
          </li>
          <li>
            <code class="inline-code">country</code>
          </li>
          <li>
            <code class="inline-code">postalCode</code>
          </li>
          <li>
            <code class="inline-code">state</code>
          </li>
          <li>
            <code class="inline-code">street</code>
          </li>
        </ul>
      </td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">birthday</code>
      </td>
      <td style="text-align:left">Date</td>
      <td style="text-align:left">User's date of birth</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">company</code>
      </td>
      <td style="text-align:left">Object</td>
      <td style="text-align:left">
        <p>User's company. This can optionally contain either/all of the following fields:</p>
        <ul>
          <li>
            <code class="inline-code">name</code> (String)
          </li>
          <li>
            <code class="inline-code">id</code> (String / Number)
          </li>
          <li>
            <code class="inline-code">industry</code> (String)
          </li>
          <li>
            <code class="inline-code">employee_count</code> (Number)
          </li>
          <li>
            <code class="inline-code">plan</code> (String)
          </li>
        </ul>
      </td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">createdAt</code>
      </td>
      <td style="text-align:left">Date</td>
      <td style="text-align:left">
        <p>Date of user's account creation. We recommend using the <b>ISO-8601</b> date string format.</p>
      </td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">description</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">User's description</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">gender</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">User's gender</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">title</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">
        <p>User's title related to their position in their company</p>
      </td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">username</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">
        <p>User's username. This should be unique for every user.</p>
      </td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">website</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">User's website</td>
    </tr>
    <tr>
      <td style="text-align:left">
        <code class="inline-code">avatar</code>
      </td>
      <td style="text-align:left">String</td>
      <td style="text-align:left">URL of the user's avatar image</td>
    </tr>
  </tbody>
</table>

{{< success >}}
Different destinations recognize some of the above traits differently. For example, Mixpanel recognizes `createdAt` as `$created`, while Intercom recognizes it as `created_at`.

With RudderStack, you don't have to worry about these inconsistencies, it handles these destination-specific conversions automatically.
{{< /success >}}

## Pass traits to an identify call

When you pass traits to an `identify` call, they will be stored in a cookie on the user's browser or mobile device and will be passed automatically to all subsequent calls.

Below is an example of how to pass traits to an `identify` call from our [JavaScript SDK]({{< ref "sources/event-streams/sdks/rudderstack-javascript-sdk/_index.md" >}}). For more examples, check our other [SDKs]({{< ref "sources/event-streams/sdks/_index.md" >}}).

```javascript
rudderanalytics.identify("1hKOmRA4GRlm", {
  name: "Alex Keener",
  gender: "male",
})
```

In the above example, `{name: "Richard Hendricks", gender: "male"}` are stored in a cookie and passed along with all subsequent calls.

## FAQ

##### How can I achieve consistent identity tracking for users across different top-level domains? 

You can leverage the JavaScript SDK's [Query string API]({{< ref "sources/event-streams/sdks/rudderstack-javascript-sdk/supported-api.md#query-string-api" >}}) to pass the user ID (`userId` or `anonymousId`) from one domain to the other so that the user journeys can be stitched together.

<br />
