> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Identifying and changing contexts

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic explains how to use the identify feature in LaunchDarkly SDKs. Identify is available for client-side and server-side SDKs.

## Using identify to change contexts and users

The identify feature's behavior differs between client-side and server-side SDKs.

Client-side SDKs are configured to operate for one end user at a time, identified or anonymous. In these SDKs, the identify feature allows you to change the context, such as when an end user logs in or changes their settings. Identifying contexts and users causes LaunchDarkly to index them.

To associate two contexts with each other, such as your representations of an end user before and after they log in, call identify with a multi-context that contains both contexts. The association between the two contexts that comprise your multi-context doesn't persist between sessions. You must call identify with the multi-context each time.

Here is an example of a multi-context, though each SDK sends context data to LaunchDarkly in a slightly different format:

```json title="Example multi-context" lines wrap theme={null}
{
  "kind": "multi",
  "user": {
    "key": "example-user-key",
    "name": "Sandy",
    "email": "sandy@example.com"
  },
  "device": {
    "key": "example-device-key",
    "type": "iPhone",
    "deviceId": 12345
  }
}
```

Server-side SDKs operate for multiple end users concurrently. Unlike in client-side SDKs, server-side SDKs do not have a notion of "changing the user context" because contexts or users are directly passed to client method invocations for actions such as evaluating flag variations. In server-side SDKs, the only impact of identifying contexts and users is that they are added to the **Contexts** list. However, in most applications this is not needed because they are automatically indexed when used for a flag evaluation. Instead, you should provide the evaluation object in a variation or all flags call to get the expected flag evaluation. To learn more, read [Flag variation evaluation](/docs/sdk/features/evaluating) and [Getting all flags](/docs/sdk/features/all-flags).

To learn more about the differences in how SDKs identify and use users and contexts, read [Choosing an SDK type](/docs/sdk/concepts/client-side-server-side).

> [!NOTE]
>
> **Newer versions of LaunchDarkly SDKs replace users with contexts**
>
> A context is a generalized way of referring to the people, services, machines, or other resources that encounter feature flags in your product. Contexts replace another data object in LaunchDarkly: "users." To learn more, read [Contexts](/docs/home/flags/contexts).
>
> Creating contexts and evaluating flags based on them is supported in the latest major versions of [most of our SDKs](/docs/sdk). For these SDKs, the code samples on this page include the two most recent versions.

Details about each SDK's identify feature are available in the SDK-specific sections below.

* [Client-side SDKs](#client-side-sdks)
* [Server-side SDKs](#server-side-sdks)

## When to call identify

The timing of your identify calls determines which flag values your application receives, and how much network traffic the SDK generates. This section describes the recommended patterns for calling identify in client-side SDKs, followed by guidance for [server-side SDKs](#call-identify-sparingly-in-server-side-sdks).

### Initialize with the context you know

If you know the context when your application starts, such as when an end user is already logged in, initialize the SDK with that context. You do not need to call identify afterward.

If you do not know the context when your application starts, initialize the SDK with an anonymous context. Then call identify when the context becomes available. Always give each anonymous context a unique key, or let the SDK generate one for you. If all of your anonymous contexts share the same key, then percentage rollouts, Experimentation, and individual targeting do not work as expected. To learn more, read [Anonymous contexts](/docs/home/flags/anonymous-contexts).

The React Native SDK version 10 is an exception to this rule. You do not provide a context when you initialize this SDK. Instead, you must call identify before you can evaluate flags for a context. To learn more, read [React Native](#react-native).

### Call identify when the context changes

Call identify when the context changes, such as when:

* An end user logs in or logs out.
* Your application learns more about the end user, such as their organization.
* The value of an attribute that you use in targeting changes.

In some situations, the new context can be an updated version of the existing context. For example, on the sign-in page of a single-page app, you could represent the same person as a multi-context that combines their pre-login anonymous context and a post-login context with the "user" kind. After the person logs in, call identify to serve them the correct flag values for their account.

In other situations, the new context can be a multi-context based on multiple identifiers. For example, you might initialize the client with a context of the "device" kind as soon as an end user opens your app. After the end user logs in, you then have their user and organization information. Call identify with a multi-context that contains the "device," "user," and "organization" contexts for the end user.

Never call identify when the context has not changed, such as on every page view or every time a mobile app returns to the foreground. Each identify call fetches flag values from LaunchDarkly and sends an event to LaunchDarkly.

### Use one client instance

Create one SDK client instance for each LaunchDarkly environment that your application uses, and reuse that instance. To change the context, call identify on the existing client. Do not close the client and initialize a new one, because a new client must connect to LaunchDarkly and retrieve flag values again before it is ready. To learn more, read [Correctly implementing the singleton pattern](/docs/home/account/calculating-billing#correctly-implementing-the-singleton-pattern).

### Wait for identify to complete

After you call identify to change contexts, the SDK loads flag values for the new context. Until that load completes, it is possible that flag evaluations return values that LaunchDarkly served for the previous context. The exact behavior differs between SDKs. Some SDKs keep the previous context's flag values in memory, or read them from local storage, until the new values arrive.

If your application must not use the previous context's flag values, wait for the identify call to complete before you evaluate flags. This is especially important for flags that control access to a feature or that are part of an experiment. Depending on the SDK, you can await the result, pass a completion callback, or wait on a `Future`.

If your application waits for identify before it displays content, set a timeout to prevent a slow network connection from blocking your application. After the timeout expires, the identify call keeps running, and the SDK updates the flag values when it completes. Plan what your application does until then, such as displaying content based on the flag values the SDK already has. Some SDKs recommend a timeout of less than 15 seconds, and log a message if you set a longer one.

### Avoid overlapping identify calls

If you call identify again before an earlier identify call completes, some SDKs discard the intermediate calls and identify only the most recent context. A discarded call reports a "shed" or "superseded" result instead of a "completed" result. Other SDKs queue identify calls and complete them in order.

If your code depends on each identify call completing, wait for each call to complete before you start the next one. To learn how your SDK handles overlapping calls, read the SDK-specific sections below.

### Call identify sparingly in server-side SDKs

In server-side SDKs, pass the context to each flag evaluation call. Do not call identify for each request. Flag evaluations already add contexts to the **Contexts** list. Calling identify for each request only sends additional events to LaunchDarkly. Call identify only when you want to add contexts to the **Contexts** list before you evaluate flags for them.

Initialize only one SDK client instance when your application starts, and reuse it for the lifetime of the process.

## Client-side SDKs

This feature is available in the following client-side SDKs:

* [.NET (client-side)](#net-client-side)
* [Android](#android)
* [C++ (client-side)](#c++-client-side)
* [Electron](#electron)
* [Flutter](#flutter)
* [iOS](#ios)
* [JavaScript](#javascript)
* [Node.js (client-side)](#node-js-client-side)
* [React](#react)
* [React Native](#react-native)
* [Roku](#roku)
* [Vue](#vue)

In client-side SDKs, the identify feature changes the current context and loads the flag values for the new context.

### .NET (client-side)

> **Expand .NET (client-side) code sample**
>
> The identify method tells the client to change the current context and obtain the feature flag values for the new context. In the .NET SDK, you can use either the `Identify` or `IdentifyAsync` method to switch contexts.
>
> To wait until the flag values for the new context have been loaded before proceeding, call the synchronous method `Identify` with a timeout, or call the asynchronous method `IdentifyAsync` and await the result.
>
> Here's how:
>
> ```csharp title=".NET SDK v5.0+ (C#)" lines wrap theme={null}
> var updatedContext = Context.Builder("example-context-key")
>     .Set("email", "sandy@example.com")
>     .Build();
>
> // Synchronous method
> client.Identify(updatedContext, TimeSpan.FromSeconds(5));
>
> // Asynchronous method
> await client.IdentifyAsync(updatedContext);
> ```
>
> To learn more, read [`Identify`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/client/api/LaunchDarkly.Sdk.Client.LdClient.html#LaunchDarkly_Sdk_Client_LdClient_Identify_) and [`IdentifyAsync`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/client/api/LaunchDarkly.Sdk.Client.LdClient.html#LaunchDarkly_Sdk_Client_LdClient_IdentifyAsync_).

### Android

> **Expand Android code sample**
>
> The `identify()` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> Here's how:
>
> ```java title="Android SDK v4.0+ (Java)" lines wrap theme={null}
> LDContext updatedContext = LDContext.builderFromContext(context)
>     .set("email", "sandy@example.com")
>     .build();
>
> client.identify(updatedContext);
> ```
>
> ```kotlin title="Android SDK v4.0+ (Kotlin)" lines wrap theme={null}
> val updatedContext: LDContext = LDContext.builderFromContext(context)
>     .set("email", "sandy@example.com")
>     .build()
>
> client.identify(updatedContext)
> ```
>
> The `identify()` call loads any saved flag values for the new user context and immediately triggers an update of the latest flags from LaunchDarkly.
>
> `identify()` returns a [Future](https://developer.android.com/reference/java/util/concurrent/Future) to indicate completion. If you want to be sure subsequent code is using the latest values from the server, you can wait for the Future using `get`. To avoid blocking indefinitely, call `get` with a timeout, such as `get(5, TimeUnit.SECONDS)`.
>
> To learn more, read [`identify`](https://launchdarkly.github.io/android-client-sdk/com/launchdarkly/sdk/android/LDClient.html#identify\(com.launchdarkly.sdk.LDContext\)).

### C++ (client-side)

> **Expand C++ (client-side) code sample**
>
> The identify method tells the client to change the current context and obtain the feature flag values for the new context.
>
> Here's how to update your initial context when you have additional information:
>
> ```cpp title="C++ SDK v3 (native)" lines wrap theme={null}
> /* before end user logs in */
> auto context = ContextBuilder()
>   .Kind("device", "example-device-key")
>   .Build();
>
> /* after end user logs in */
> auto updated_context = ContextBuilder(context)
>   .Kind("user", "example-user-key")
>   .Name("Sandy")
>   .Kind("organization", "example-organization-key")
>   .Name("Global Health Services")
>   .Build();
> ```
>
> After you update the context, you must call identify with the updated context in order to evaluate flags based on the updated information.
>
> Here's how to use the identify method to switch contexts:
>
> ```cpp title="C++ SDK v3.0 (native)" lines wrap theme={null}
> client.IdentifyAsync(updated_context);
> ```
>
> ```c title="C++ SDK v3.0 (C binding)" lines wrap theme={null}
> LDClientSDK_Identify(client, updated_context, LD_NONBLOCKING, NULL);
> ```
>
> You can also examine the result to determine if the identification succeeded. Here's how:
>
> ```cpp title="C++ SDK v3.0 (native)" lines wrap theme={null}
> auto identify_result = client.IdentifyAsync(updated_context);
> auto status = identify_result.wait_for(maxwait);
>
> if (status == std::future_status::ready) {
>   /* The client's attempt to identify succeeded or failed in the specified amount of time. */
>   if (identify_result.get()) {
>     /* Identification succeeded */
>   } else {
>     /* Identification failed */
>   }
> } else {
>   /* The specified timeout was reached, but the client is still identifying. */
> }
> ```
>
> ```c title="C++ SDK v3.0 (C binding)" lines wrap theme={null}
> bool identified_successfully;
> if (LDClientSDK_Identify(client, updated_context, maxwait, &identified_successfully)) {
>   /* The client's attempt to identify succeeded or failed in the specified amount of time. */
>   if (identified_successfully) {
>     /* Identification succeeded. */
>   } else {
>     /* Identification failed. */
>   }
> } else {
>    /* The specified timeout was reached, but the client is still identifying. */
> }
> ```
>
> The `IdentifyAsync` call loads any saved flag values for the new context and immediately triggers an update of the latest flags from LaunchDarkly. To learn more, read [`IdentifyAsync`](https://launchdarkly.github.io/cpp-sdks/libs/client-sdk/docs/html/classlaunchdarkly_1_1client__side_1_1Client.html#a62fc1fe135495b72fa37ecedf5a2c7e2).

### Electron

> **Expand Electron code sample**
>
> The `identify()` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> Here's how:
>
> ```js title="JavaScript" lines wrap theme={null}
> const newUser = { key: 'example-user-key', name: 'Sandy' };
>
> client.identify(newUser, null, (err, newFlags) => {
>   console.log('value of flag for this user is: ' + newFlags['example-flag-key']);
>   console.log('this should be the same: ' + client.variation('example-flag-key'));
> });
>
> // or:
> client.identify(newUser).then((newFlags) => {
>   // as above
> });
> ```
>
> ```ts title="TypeScript" lines wrap theme={null}
> import * as LDElectron from 'launchdarkly-electron-client-sdk';
>
> const newUser: LDElectron.LDUser = {
>   key: 'someone-else', name: 'John',
> };
>
> client.identify(newUser, null, (err, newFlags) => {
>   console.log('value of flag for this user is: ' + newFlags['example-flag-key']);
>   console.log('this should be the same: ' + client.variation('example-flag-key'));
> });
>
> // or:
> client.identify(newUser).then((newFlags) => {
>   // as above
> });
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/electron-client-sdk/interfaces/_launchdarkly_electron_client_sdk_.ldelectronmainclient.html#identify).

### Flutter

> **Expand Flutter code sample**
>
> The `identify` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> Here's how:
>
> ```dart title="Flutter SDK v4, single context" lines wrap theme={null}
> final updatedContext = LDContextBuilder()
>   .kind('user', 'example-user-key')
>   .setString('email', 'sandy@example.com')
>   .build();
>
> await client.identify(updatedContext);
> ```
>
> ```dart title="Flutter SDK v4, multi-context" lines wrap theme={null}
> final updatedMultiContext = LDContextBuilder()
>   .kind('user', 'example-user-key')
>   .kind('device', 'example-device-key')
>   .build();
>
> await client.identify(updatedMultiContext);
> ```
>
> `identify` returns an `IdentifyResult`. If you call `identify` while an earlier call is in progress, the SDK holds the new call until the earlier one completes. If you call `identify` again before the held call starts, the new call replaces it. A replaced call returns `IdentifySuperseded`.
>
> To learn more, read [`identify`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/LDClient/identify.html).

### iOS

> **Expand iOS code sample**
>
> The `identify()` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> If the client app does not identify an `LDContext`, `LDClient` creates an anonymous default context, which can affect which feature flags LaunchDarkly delivers to the `LDClient`. Client apps should follow the [Apple Privacy Policy](https://apple.com/legal/privacy) when collecting end user information.
>
> Here's how:
>
> ```swift title="iOS SDK v9.4+ (Swift)" lines wrap theme={null}
> let newContext = try LDContextBuilder(key: "example-context-key").build().get()
>
> LDClient.get()!.identify(context: newContext, timeout: 5) { result in
>     switch result {
>     case .complete:
>         // Flags have been retrieved for the new context
>         break
>     case .timeout:
>         // The identify request is still in progress
>         break
>     case .shed:
>         // A later identify call replaced this one
>         break
>     case .error:
>         // The identify request failed
>         break
>     }
> }
> ```
>
> ```objectivec title="iOS SDK v8.0+ (Objective-C)" lines wrap theme={null}
> LDContextBuilder *builder = [[LDContextBuilder alloc] initWithKey:@"example-context-key"];
> ContextBuilderResult *result = builder.build;
>
> if (result.success) {
>     LDContext *newContext = result.success;
>
>     [[LDClient get] identifyWithContext:newContext];
>
>     // You can also call identify with a completion
>     [[LDClient get] identifyWithContext:newContext completion:^() {
>         // Flags have been retrieved for the new context
>     }];
> }
> ```
>
> In version 9.4 and later, the `identify(context:completion:)` and `identify(context:timeout:completion:)` methods pass an `IdentifyResult` to the completion. The result is `.complete`, `.error`, `.shed`, or `.timeout`. The Swift example uses `identify(context:timeout:completion:)` to make sure the completion runs within five seconds. The identify request continues after the timeout expires.
>
> The SDK processes one identify request at a time. If you call `identify(context:completion:)` while a request is in flight, the SDK holds the new request. If you call it again before the held request starts, the new request replaces the held one, and the held request reports `.shed`. The Objective-C `identifyWithContext:completion:` method, and the deprecated Swift version of `identify(context:completion:)` whose completion takes no arguments, do not shed requests.
>
> To learn more, read [`identify`](https://launchdarkly.github.io/ios-client-sdk/Classes/ObjcLDClient.html#/c:@M@LaunchDarkly@objc\(cs\)LDClient\(im\)identifyWithContext:).

### JavaScript

> **Expand JavaScript code sample**
>
> The `identify()` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> In version 3 of the JavaScript SDK, if you provide a callback function, it is called with a map of flag keys and values after the flag values for the new context are available. After that point, `variation()` uses the new values. You can also use a Promise for the same purpose. When you use a Promise, it is important that you handle the rejection case. Otherwise, it will become an unhandled Promise rejection, which is a serious error on some platforms.
>
> It is possible that the `identify()` call will fail. If you are using a callback, the callback will receive an error value, and calls to [evaluate a flag](/docs/sdk/features/evaluating) will still return flag values for the previous context.
>
> Here's how to identify a new context:
>
> ```js title="JavaScript SDK v3+, single context" lines wrap theme={null}
> client.identify(newContext, hash, function() {
>   console.log("New context's flags available");
> });
> ```
>
> ```js title="JavaScript SDK v3+, multi-context" expandable lines wrap theme={null}
> const newMultiContext = {
>   kind: 'multi',
>   user: {
>     key: 'example-user-key',
>     name: 'Anna',
>     role: 'doctor'
>   },
>   device: {
>     key: 'example-device-key',
>     platform: 'Android'
>   }
> }
>
> client.identify(newMultiContext, hash, function() {
>   console.log("New context's flags available");
> });
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDClient.html#identify).
>
> In version 4 of the JavaScript SDK, `identify()` returns a promise that resolves to a result object, and the promise is never rejected. The result's `status` is `completed`, `error`, `timeout`, or `shed`. You can pass identify options as the second argument, including `hash` for secure mode and `timeout`, in seconds, which defaults to five seconds.
>
> By default, identify calls are sheddable in version 4. If you call `identify()` again before an earlier call completes, the SDK discards the intermediate calls and identifies only the most recent context. A discarded call resolves with a `status` of `shed`. To queue identify calls and complete them in order instead, set the `sheddable` option to `false`.
>
> Here's how to identify a new context in version 4:
>
> ```js title="JavaScript SDK v4" lines wrap theme={null}
> const result = await client.identify(newContext, { timeout: 5 });
>
> if (result.status === 'completed') {
>   console.log("New context's flags available");
> } else if (result.status === 'shed') {
>   // A later identify call replaced this one
> } else {
>   console.error(`identify did not complete: ${result.status}`);
> }
> ```
>
> To learn more, read [`LDIdentifyOptions`](https://launchdarkly.github.io/js-core/packages/sdk/browser/docs/interfaces/LDIdentifyOptions.html).
>
> If you are using the [LaunchDarkly observability SDKs](/docs/sdk/observability), calling `identify()` also automatically indexes your sessions. You can then [search for sessions](/docs/home/observability/session-replay) based on context attributes.
>
> If your contexts are extraordinarily large, you may need to configure the JavaScript SDK to send the evaluation context as a request body. To learn more, read [Using REPORT in the JavaScript SDK](/docs/guides/account/user-data#use-report-in-the-javascript-sdk).
>
> > [!WARNING]
> >
> > **You must use a hash parameter while in secure mode**
> >
> > The hash parameter is the hash for the new context, assuming that the context's key has changed. The hash parameter is only required in secure mode. If secure mode is not enabled, pass in `null` for the hash.

### Node.js (client-side)

> **Expand Node.js (client-side) code sample**
>
> The `identify()` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> Here's how:
>
> ```js title="Node.js SDK v3.0, single context" lines wrap theme={null}
> client.identify(newContext, null, () => {
>   console.log("New context's flags available");
> });
>
> // or, with a Promise:
> client.identify(newContext).then(() => {
>   console.log("New context's flags available");
> });
> ```
>
> ```js title="Node.js SDK v3.0, multi-context" maxLines=0 expandable lines wrap theme={null}
> const newMultiContext = {
>   kind: 'multi',
>   user: {
>     key: 'aa0ceb',
>     name: 'Anna',
>     role: 'doctor'
>   },
>   device: {
>     key: 'example-device-key',
>     platform: 'Android'
>   }
> }
>
> client.identify(newMultiContext, null, () => {
>   console.log("New context's flags available");
> });
>
> // or, with a Promise:
> client.identify(newMultiContext).then(() => {
>   console.log("New context's flags available");
> });
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/node-client-sdk/interfaces/LDClient.html#identify).
>
> In version 4 of the Node.js (client-side) SDK, `identify()` returns a promise that resolves to a result object, and the promise is never rejected. The result's `status` is `completed`, `error`, `timeout`, or `shed`. You can pass identify options as the second argument, including `hash` for secure mode and `timeout`, in seconds, which defaults to five seconds.
>
> By default, identify calls are sheddable in version 4. If you call `identify()` again before an earlier call completes, the SDK discards the intermediate calls and identifies only the most recent context. A discarded call resolves with a `status` of `shed`. To queue identify calls and complete them in order instead, set the `sheddable` option to `false`.
>
> Here's how to identify a new context in version 4:
>
> ```js title="Node.js SDK v4" lines wrap theme={null}
> const result = await client.identify(newContext, { timeout: 5 });
>
> if (result.status === 'completed') {
>   console.log("New context's flags available");
> } else if (result.status === 'shed') {
>   // A later identify call replaced this one
> } else {
>   console.error(`identify did not complete: ${result.status}`);
> }
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/js-core/packages/sdk/node-client/docs/interfaces/LDClient.html#identify).

### React

> **Expand React code sample**
>
> The `identify()` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> Here's how:
>
> ```js title="JavaScript" lines wrap theme={null}
> import { useLDClient } from 'launchdarkly-react-client-sdk';
>
> let ldClient = useLDClient();
>
> ldClient.identify(newContext, null, () => {
>   console.log("New context's flags available");
> });
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDClient.html#identify).
>
> In version 4 of the React Web SDK, `identify()` returns a promise that resolves to a result object, and the promise is never rejected. The result's `status` is `completed`, `error`, `timeout`, or `shed`. By default, identify calls are sheddable. If you call `identify()` again before an earlier call completes, the SDK discards the intermediate calls and identifies only the most recent context. To queue identify calls and complete them in order instead, set the `sheddable` identify option to `false`. To learn more, read [Identify the context](/docs/sdk/client-side/react/react-web#identify-the-context).

### React Native

> **Expand React Native code sample**
>
> The `identify` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> > [!NOTE]
> >
> > **Version 10 requires an identify call**
> >
> > In the React Native SDK version 10, you do not provide a context when you initialize the `ReactNativeLDClient`. You must call `identify` before you can evaluate a feature flag for a specific context. End users will receive fallback values until you specify a context by calling `identify`.
>
> If multiple customers use your app on a single device, you may choose to change contexts and have separate flag settings for each one. The SDK stores contexts on a single device using [react-native-async-storage](https://github.com/react-native-async-storage/async-storage), and supports switching between different contexts. You can use the `identify` method to switch contexts. `identify` loads any saved flag values for the new context and immediately triggers an update of the latest flags from LaunchDarkly.
>
> Here's how:
>
> ```ts title="React Native SDK v10" lines wrap theme={null}
> import { useLDClient } from '@launchdarkly/react-native-client-sdk';
>
> const client = useLDClient();
> const context: LDContext = {'key': 'example-user-key', 'kind': 'user'};
>     client
>       .identify(context)
>       .catch((e: any) => console.error(`error identifying ${context.key}: ${e}`));
>
> ```
>
> By default, the SDK queues identify calls and completes them in order. To discard intermediate calls instead, set the `sheddable` identify option to `true`. The `timeout` identify option defaults to five seconds. If the timeout expires, the promise that `identify` returns is rejected, but the SDK continues to identify the context.
>
> To learn more, read [`identify`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/classes/LDClientImpl.html#identify).

### Roku

> **Expand Roku code sample**
>
> The `identify()` method tells the client to change the current context and obtain the feature flag values for the new context.
>
> To do this:
>
> ```brightscript title="Roku SDK v2.0 (BrightScript)" expandable lines wrap theme={null}
> ' before the end user logs in
> device = {
>   "kind": "device",
>   "key": "example-device-key",
>   "type": "tablet"
> }
> context = LaunchDarklyCreateContext(device)
>
> ' after the end user logs in
> multi = {
>   "kind": "multi",
>   "device": device,
>   "user": {"key": "example-user-key", "name": "Sandy"},
>   "organization": {"key": "example-organization-key", "name": "Acme, Inc."}
> }
>
> launchDarkly.identify(multi)
>
> ```

### Vue

> **Expand Vue code sample**
>
> To change the context, retrieve the client with `useLDClient()` and call the `identify()` method. The variation composables re-evaluate after `identify()` completes. Your components update without additional work.
>
> `identify()` returns a promise that resolves to a result object, and the promise is never rejected. The result's `status` is `completed`, `error`, `timeout`, or `shed`. By default, identify calls are sheddable. If you call `identify()` again before an earlier call completes, the SDK discards the intermediate calls and identifies only the most recent context. To queue identify calls and complete them in order instead, set the `sheddable` identify option to `false`.
>
> To react to context changes elsewhere in your application, call `onContextChange()` on the client. It returns a function that unsubscribes the callback.
>
> Here's how to identify a new context:
>
> ```html title="Vue SDK v3.0, single context" lines wrap theme={null}
> <script setup>
> import { useLDClient } from '@launchdarkly/vue-client-sdk'
>
> const ldClient = useLDClient()
>
> async function signIn(userKey) {
>   await ldClient.identify({ kind: 'user', key: userKey })
>   // The variation composables re-evaluate automatically.
> }
> </script>
> ```
>
> ```html title="Vue SDK v3.0, multi-context" lines wrap theme={null}
> <script setup>
> import { useLDClient } from '@launchdarkly/vue-client-sdk'
>
> const ldClient = useLDClient()
>
> async function signIn() {
>   await ldClient.identify({
>     kind: 'multi',
>     user: {
>       key: 'example-user-key',
>       name: 'Anna',
>       role: 'doctor'
>     },
>     device: {
>       key: 'example-device-key',
>       platform: 'Android'
>     }
>   })
>   // The variation composables re-evaluate automatically.
> }
> </script>
> ```
>
> To run your own logic when the context changes, subscribe with `onContextChange()`:
>
> ```html title="Vue SDK v3.0" lines wrap theme={null}
> <script setup>
> import { onScopeDispose } from 'vue'
> import { useLDClient } from '@launchdarkly/vue-client-sdk'
>
> const ldClient = useLDClient()
>
> // onContextChange returns a function that unsubscribes the callback.
> const unsubscribe = ldClient.onContextChange((context) => {
>   console.log('context changed:', context)
> })
>
> onScopeDispose(unsubscribe)
> </script>
> ```

## Server-side SDKs

This feature is available in the following server-side SDKs:

* [.NET (server-side)](#net-server-side)
* [Apex](#apex)
* [C++ (server side)](#c++-server-side)
* [Erlang](#erlang)
* [Go](#go)
* [Haskell](#haskell)
* [Java](#java)
* [Lua](#lua)
* [Node.js (server side)](#node-js-server-side)
* [PHP](#php)
* [Python](#python)
* [Ruby](#ruby)
* [Rust](#rust)

### .NET (server-side)

> **Expand .NET (server-side) code sample**
>
> In server-side SDKs, `Identify` creates or updates contexts on LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `Identify`. The `Variation` methods automatically create contexts on the **Contexts** list for you, using the context you pass to each `Variation` method. `Identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `Identify`:
>
> ```csharp title=".NET SDK v7.0+ (C#)" lines wrap theme={null}
> client.Identify(context);
> ```
>
> To learn more, read [`Identify`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/server/api/LaunchDarkly.Sdk.Server.LdClient.html#LaunchDarkly_Sdk_Server_LdClient_Identify_).

### Apex

> **Expand Apex code sample**
>
> In server-side SDKs, `identify` creates or updates users in LaunchDarkly, which makes them available for targeting and autocomplete on the **Users** list.
>
> To use `identify`:
>
> ```java title="Apex" lines wrap theme={null}
> client.identify(user);
> ```
>
> To learn more, read [Other methods](https://github.com/launchdarkly/apex-server-sdk/blob/main/doc.md#other-methods-1).

### C++ (server-side)

> **Expand C++ (server-side) code sample**
>
> In server-side SDKs, `Identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `Identify`. The `variation` call automatically creates contexts on the **Contexts** list for you, using the evaluation context you pass to each `variation` method. `Identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `Identify`:
>
> ```cpp title="C++ SDK v3.0 (native)" lines wrap theme={null}
> client.Identify(context);
> ```
>
> ```c title="C++ SDK v3.0 (C binding)" lines wrap theme={null}
> LDServerSDK_Identify(client, context);
> ```
>
> To learn more, read `Identify()` in [`Client`](https://launchdarkly.github.io/cpp-sdks/libs/server-sdk/docs/html/classlaunchdarkly_1_1server__side_1_1Client.html).

### Erlang

> **Expand Erlang code sample**
>
> In server-side SDKs, `identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` methods automatically create contexts on the **Contexts** list for you, using the context you pass to each `variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```erlang title="Erlang SDK v2.0+" lines wrap theme={null}
> ldclient:identify(#{key => <<"example-context-key">>})
> ```
>
> To learn more, read [`identify`](https://hexdocs.pm/launchdarkly_server_sdk/ldclient.html#identify-1).

### Go

> **Expand Go code sample**
>
> In server-side SDKs, `Identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `Identify`. The `Variation` method automatically creates contexts on the **Contexts** list for you, using the context you pass to each `Variation` method. `Identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `Identify`:
>
> ```go title="Go SDK v7.13.4+, using LDScopedClient" lines wrap theme={null}
> // There is not an Identify method in the LDScopedClient,
> // so you need to access the method from the LDClient.
> // Then, pass in the scoped client's current context.
> // LDScopedClient is in beta and may change without notice.
> scopedClient.Client().Identify(scopedClient.CurrentContext())
> ```
>
> ```go title="Go SDK v6+, using LDClient" lines wrap theme={null}
> client.Identify(context)
> ```
>
> To learn more, read [`Identify`](https://pkg.go.dev/gopkg.in/launchdarkly/go-server-sdk.v5#LDClient.Identify).

### Haskell

> **Expand Haskell code sample**
>
> In server-side SDKs, `identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` methods automatically create contexts on the **Contexts** list for you, using the context you pass to each `variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```haskell title="Haskell SDK v4.0" lines wrap theme={null}
> identify client context
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/haskell-server-sdk/LaunchDarkly-Server-Client.html#v:identify).

### Java

> **Expand Java code sample**
>
> In server-side SDKs, `identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` methods automatically create contexts on the **Contexts** list for you, using the context you pass to each `variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```java title="Java SDK v6.0+" lines wrap theme={null}
> client.identify(context);
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/java-core/lib/sdk/server/com/launchdarkly/sdk/server/LDClient.html#identify-com.launchdarkly.sdk.LDContext-).

### Lua

> **Expand Lua code sample**
>
> In server-side SDKs, `identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` methods automatically create contexts on the **Contexts** list for you, using the context you pass to each `variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```lua title="Lua SDK v2" lines wrap theme={null}
> client:identify(context)
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/lua-server-sdk/modules/launchdarkly-server-sdk.html#identify).

### Node.js (server-side)

> **Expand Node.js (server-side) code sample**
>
> In server-side SDKs, `identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` call automatically creates users on the **Contexts** list for you, using the context you pass to each `variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```js title="Node.js SDK v7.x and later" lines wrap theme={null}
> client.identify(context);
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/js-core/packages/sdk/server-node/docs/interfaces/LDClient.html#identify).

### PHP

> **Expand PHP code sample**
>
> In server-side SDKs, `identify` creates or updates users in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` call automatically creates contexts on the **Contexts** list for you, using the context you pass to each `variation` call. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```php title="PHP SDK v5.0+" lines wrap theme={null}
> $client->identify($context);
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/php-server-sdk/classes/LaunchDarkly-LDClient.html#method_identify).

### Python

> **Expand Python code sample**
>
> In server-side SDKs, `identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` method automatically creates contexts on the **Contexts** list for you, using the context you pass to each `variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```python title="Python SDK v8.0+" lines wrap theme={null}
> ldclient.get().identify(context)
> ```
>
> To learn more, read [`identify`](https://launchdarkly-python-sdk.readthedocs.io/en/latest/api-main.html#ldclient.client.LDClient.identify).

### Ruby

> **Expand Ruby code sample**
>
> In server-side SDKs, `identify` creates or updates contexts in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` call automatically creates contexts on the **Contexts** list for you, using the context you pass to each `variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```ruby title="Ruby SDK v7.0+" lines wrap theme={null}
> client.identify(context)
> ```
>
> To learn more, read [`identify`](https://launchdarkly.github.io/ruby-server-sdk/LaunchDarkly/LDClient.html#identify-instance_method).

### Rust

> **Expand Rust code sample**
>
> In server-side SDKs, `identify` creates or updates users in LaunchDarkly, which makes them available for targeting and autocomplete on the **Contexts** list.
>
> In most cases, you do not need to call `identify`. The `variation` methods automatically create users or contexts on the **Contexts** list for you, using the context you pass to each `Variation` method. `identify` is useful if you want to pre-populate your **Contexts** list before you launch any features.
>
> To use `identify`:
>
> ```rust title="Rust SDK v1+" lines wrap theme={null}
> client.identify(context);
> ```
>
> To learn more, read [`identify`](https://docs.rs/launchdarkly-server-sdk/latest/launchdarkly_server_sdk/struct.Client.html#method.identify).
