> ## 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.

# Private attributes

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic explains how to configure private context and user attributes in LaunchDarkly SDKs. These features are available for client-side, server-side, and AI SDKs.

You can optionally configure your SDK to treat some or all attributes as [private context attributes](/docs/home/flags/private-context-attributes.md). You can use private context attributes for targeting purposes, but the SDK removes them from the context data it sends back to LaunchDarkly.

> [!NOTE]
>
> **The SDK always sends the context key and kind**
>
> The context key is not optional. You cannot set either the context key or the context kind as a private attribute.

If you initially mark an attribute as private, LaunchDarkly will continue to treat the attribute as private in subsequent evaluations as long as the context is in the **Contexts** list, even if you later remove the "private" designation from the attribute. If you no longer want LaunchDarkly to treat the attribute as private, remove the "private" designation within the SDK, delete the context from the **Contexts** list, and re-evaluate the context.

After you configure private attributes within your SDK, the context details page in the LaunchDarkly user interface shows the private attributes under a `_meta` section. The values of these attributes are not displayed:

![The "Attributes" section of the context details page, showing private attributes in a "\_meta" section.](https://mintcdn.com/launchdarkly/nJ-98AdUTCC7b8MD/images/auto/context-details-private-attribute.auto.png?fit=max\&auto=format\&n=nJ-98AdUTCC7b8MD\&q=85\&s=c40e9171bf6ca6e3c0da97ea4df503ca)

The "Attributes" section of the context details page, showing private attributes in a "\_meta" section.

Depending on the type of SDK you use, LaunchDarkly does not receive or store the information in private attributes:

* If you are using a server-side or AI SDK, the SDK will not send the private attribute back to LaunchDarkly.
* If you are using a client-side SDK, the SDK will send the private attribute back to LaunchDarkly for evaluation. However, the SDK won't send the attribute to LaunchDarkly in events data, LaunchDarkly won't store the private attribute, and the private attribute will not appear on the **Contexts** list or on the detail page for the context.

> [!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.md). For these SDKs, the code samples on this page include the two most recent versions.

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

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

## Client-side SDKs

Here are the configuration options for private context and user attributes in 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 Native](#react-native)
* [React Web](#javascript): The React Web SDK relies on the JavaScript SDK for context-related functionality.
* [Roku](#roku)
* [Vue](#javascript): The Vue SDK relies on the JavaScript SDK for context-related functionality.

### .NET (client-side)

> **Expand .NET (client-side) code sample**
>
> In the client-side .NET SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * When creating the LaunchDarkly `Configuration` object, you can call the `AllAttributesPrivate` method, which takes in a boolean parameter. If `true`, all context attributes except the kind and key are removed for all contexts before the SDK sends the context to LaunchDarkly.
> * When creating the LaunchDarkly `Configuration` object, you can call the `PrivateAttributes` method, which takes any number of attribute names or slash-delimited paths to designated JSON properties within an attribute, such as `/address/street`. If any context has a custom or built-in attribute that matches one of these names, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```csharp title=".NET SDK v5.0+ (C#)" lines wrap theme={null}
> // All attributes marked private
> var configAllPrivate = Configuration
>   .Builder("example-mobile-key", ConfigurationBuilder.AutoEnvAttributes.Enabled)
>   .Events(Components.SendEvents().AllAttributesPrivate(true))
>   .Build();
> LdClient client = LdClient.Init(configAllPrivate, context, TimeSpan.FromSeconds(10));
>
> // Two attributes marked private
> var configSomePrivate = Configuration
>   .Builder("example-mobile-key", ConfigurationBuilder.AutoEnvAttributes.Enabled)
>   .Events(Components.SendEvents().PrivateAttributes("email", "address"))
>   .Build();
> client = LdClient.Init(configSomePrivate, context, TimeSpan.FromSeconds(10));
> ```
>
> You can also mark attributes as private when building the context object by calling `Private()` on the context builder.
>
> For example:
>
> ```csharp title=".NET SDK v5.0+ (C#)" lines wrap theme={null}
> var context = Context.Builder("example-context-key")
>     .Set("email", "sandy@example.com")
>     .Private("email")
>     .Build();
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Android

> **Expand Android code sample**
>
> In the Android SDK you can define private attributes for the entire LaunchDarkly client. When creating the `LDConfig` object, call the `privateAttributes` method, which takes in a set of custom or built-in attributes as a parameter. If any context has a custom or built-in attribute named in this set, the SDK removes it before sending the context to LaunchDarkly.
>
> Here's how to configure private attributes:
>
> ```java title="Android SDK v5.x (Java)" expandable lines wrap theme={null}
> // All attributes marked private
> LDConfig ldConfig = new LDConfig.Builder(AutoEnvAttributes.Enabled)
>     .mobileKey("example-mobile-key")
>     .events(
>       Components.sendEvents()
>           .allAttributesPrivate(true)
>     )
>     .build();
>
> // Two attributes marked private
> ldConfig = new LDConfig.Builder(AutoEnvAttributes.Enabled)
>     .mobileKey("example-mobile-key")
>     .events(
>         Components.sendEvents()
>             .privateAttributes("name", "group")
>     )
>     .build();
> ```
>
> ```kotlin title="Android SDK v5.x (Kotlin)" expandable lines wrap theme={null}
> // All attributes marked private
> var ldConfig = LDConfig.Builder(AutoEnvAttributes.Enabled)
>     .mobileKey("example-mobile-key")
>     .events(
>         Components.sendEvents()
>           .allAttributesPrivate(true)
>      )
>      .build()
>
> // Two attributes marked private
> ldConfig = LDConfig.Builder(AutoEnvAttributes.Enabled)
>     .mobileKey("example-mobile-key")
>     .events(
>         Components.sendEvents()
>             .privateAttributes("name", "group")
>     )
>     .build();
> ```
>
> You can also mark attributes as private when building the context object by using the private versions of the builder methods to set the attributes. For example:
>
> ```java title="Android SDK v4.0+ (Java)" lines wrap theme={null}
> LDContext context = LDContext.builder("example-context-key")
>     .set("email", "sandy@example.com")
>     .set("name", "Sandy")
>     .set("group", "Global Health Services")
>     .privateAttributes("name", "group")
>     .build();
> ```
>
> ```kotlin title="Android SDK v4.0+ (Kotlin)" lines wrap theme={null}
> val context: LDContext = LDContext.builder("example-context-key")
>     .set("email", "sandy@example.com")
>     .set("name", "Sandy")
>     .set("group", "Global Health Services")
>     .privateAttributes("name", "group")
>     .build()
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `name` and `group` attributes.

### C++ (client-side)

> **Expand C++ (client-side) code sample**
>
> In the C++ SDK there are two ways to define private attributes for the LaunchDarkly client:
>
> * When using the `ConfigBuilder`, you can call `AllAttributesPrivate()`. When you do this, all context attributes except the kind and key are removed before the SDK sends the context to LaunchDarkly.
> * When using the `ConfigBuilder`, you can configure a set of `PrivateAttributes()`. If any context has an attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> Here's how:
>
> ```cpp title="C++ SDK v3.0 (native)" lines wrap theme={null}
> /* sets all attributes private */
> auto config_builder = client_side::ConfigBuilder("example-mobile-key");
> config_builder.Events().AllAttributesPrivate(true);
> auto config_all_private = config_builder.Build();
>
> /* sets "email" and "address" private */
> config_builder = client_side::ConfigBuilder("example-mobile-key");
> config_builder.Events().PrivateAttributes({"email", "address"});
> auto configSomePrivate = config_builder.Build();
> ```
>
> ```c title="C++ SDK v3.0 (C binding)" lines wrap theme={null}
> /* sets all attributes private */
> LDClientConfigBuilder config_builder = LDClientConfigBuilder_New("example-mobile-key");
> LDClientConfigBuilder_Events_AllAttributesPrivate(config_builder, true);
>
> LDClientConfig config;
> LDStatus config_status = LDClientConfigBuilder_Build(config_builder, &config);
>
> /* sets "email" and "address" private */
> config_builder = LDClientConfigBuilder_New("example-mobile-key");
> LDClientConfigBuilder_Events_PrivateAttribute(config_builder, "email");
> LDClientConfigBuilder_Events_PrivateAttribute(config_builder, "address");
>
> config_status = LDClientConfigBuilder_Build(config_builder, &config);
> ```
>
> You can also define private attributes for a particular context by calling `.SetPrivate()` in the `ContextBuilder`.
>
> Here's how:
>
> ```cpp title="C++ SDK v3.0" lines wrap theme={null}
> auto context = ContextBuilder()
>   .Kind("user", "example-user-key")
>   .Name("Sandy Smith")
>   .SetPrivate("email", "sandy@example.com")
>   .Build();
> ```
>
> To learn more, read [`ContextBuilder`](https://launchdarkly.github.io/cpp-sdks/libs/client-sdk/docs/html/classlaunchdarkly_1_1ContextBuilder.html).

### Electron

> **Expand Electron code sample**
>
> To mark all user attributes except the key as private, use the `allAttributesPrivate` option:
>
> ```js title="JavaScript" lines wrap theme={null}
> const user = {
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com'
> };
>
> const client = LDElectron.initialize('example-client-side-id', user, {
>   allAttributesPrivate: true
> });
> ```
>
> ```ts title="TypeScript" lines wrap theme={null}
> import * as LDElectron from 'launchdarkly-electron-client-sdk';
>
> const user: LDElectron.LDUser = {
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
> };
>
> const client = LDElectron.initializeInMain('example-client-side-id', user, {
>   allAttributesPrivate: true,
> });
> ```
>
> In the above example, the SDK removes the `name` and `email` attributes.
>
> You can also specify an array of which attributes should be private with the `privateAttributeNames` option. You can configure this option in the user object, the configuration object, or both:
>
> ```js title="JavaScript" lines wrap theme={null}
> const user = {
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
>   privateAttributeNames: ['email']
> };
>
> const client = LDElectron.initialize('example-client-side-id', user, {
>   privateAttributeNames: ['email']
> });
> ```
>
> ```ts title="TypeScript" lines wrap theme={null}
> import * as LDElectron from 'launchdarkly-electron-client-sdk';
>
> const user: LDElectron.LDUser = {
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
>   privateAttributeNames: ['email'],
> };
>
> const client = LDElectron.initializeInMain('example-client-side-id', user, {
>   privateAttributeNames: ['email'],
> });
> ```
>
> In the above example, the SDK sends only the `key` and `name` back to LaunchDarkly.

### Flutter

> **Expand Flutter code sample**
>
> In the Flutter SDK, you can define private attributes for the **entire** LaunchDarkly client. When you create the `LDConfig` object, you can set all attributes private for all contexts. You can also provide a list of attributes to the `globalPrivateAttributes` option. If any context has an attribute named in this set, the SDK removes it before sending the context to LaunchDarkly.
>
> ```dart title="Flutter SDK v4" lines wrap theme={null}
> final config = LDConfig(
>   CredentialSource.fromEnvironment(),
>   AutoEnvAttributes.enabled,
>   allAttributesPrivate: true, // all attributes marked private
>   globalPrivateAttributes: ['user/email', 'user/group'], // two attributes marked private for the 'user' context kind
> );
> ```
>
> You can also mark attributes as private when building the context object by using the `private` optional parameter. For example:
>
> ```dart title="Flutter SDK v4" lines wrap theme={null}
> final context = LDContextBuilder()
>   .kind('user', 'example-user-key')
>   .setString('name', 'Sandy')
>   .setString('email', 'sandy@example.com', private: true)
>   .setString('group', 'microsoft', private: true)
>   .build();
> ```
>
> ```dart title="Flutter SDK v2.x+" lines wrap theme={null}
> LDContextBuilder builder = LDContextBuilder();
> builder.kind('user', 'example-user-key')
>     .name('Sandy')
>     .set('email', LDValue.ofString('sandy@example.com'))
>     .set('group', LDValue.ofString('microsoft'))
>     .privateAttributes(['email', 'group']);
> LDContext context = builder.build();
> ```
>
> When the SDK sends this context back to LaunchDarkly, the `email` and `group` attributes are removed.
>
> To learn more about the configuration options for private attributes, read [`allAttributesPrivate`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/LDConfig/allAttributesPrivate.html) and [`globalPrivateAttributes`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/LDConfig/globalPrivateAttributes.html). To learn more about setting private attributes for a specific context, read [`LDContext`](https://pub.dev/documentation/launchdarkly_flutter_client_sdk/latest/launchdarkly_flutter_client_sdk/LDContext-class.html).

### iOS

> **Expand iOS code sample**
>
> In the iOS SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * When creating the `LDConfig` object, you can set the `allContextAttributesPrivate` attribute to `true`.
> * When creating the LDConfig object, you can set the `privateContextAttributes` property to a list of `Reference`s, such as `[Reference("name"), Reference("/address/state")]`. If any context has a custom or built-in attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```swift title="iOS SDK v9.0 (Swift)" lines wrap theme={null}
> // All attributes marked private
> config = LDConfig(mobileKey: "example-mobile-key", autoEnvAttributes: .enabled)
> config.allContextAttributesPrivate = true
>
> // Two attributes marked private
> config = LDConfig(mobileKey: "example-mobile-key", autoEnvAttributes: .enabled)
> config.privateContextAttributes = [Reference("email"), Reference("address")]
> ```
>
> ```objectivec title="iOS SDK v9.0 (Objective-C)" expandable lines wrap theme={null}
> // All attributes marked private
> LDConfig *config = [[LDConfig alloc] initWithMobileKey:@"example-mobile-key" autoEnvAttributes:AutoEnvAttributesEnabled];
> [config setAllContextAttributesPrivate:YES];
> [LDClient startWithConfiguration:config context:context completion:nil];
>
> // Two attributes marked private
> LDConfig *config = [[LDConfig alloc] initWithMobileKey:@"example-mobile-key" autoEnvAttributes:AutoEnvAttributesEnabled];
> [builder nameWithName:@"name"];
> [builder trySetValueWithName:@"email" value:[LDValue ofString:@"example@email.com"]];
> NSDictionary<NSString *, LDValue *> *address = @{
>     @"street": [LDValue ofString:@"Main St"],
>     @"city": [LDValue ofString:@"Springfield"]
> };
> LDContext *context = builder.build.success;
>
> LDConfig *config = [[LDConfig alloc] initWithMobileKey:@"example-mobile-key"];
> [config setPrivateContextAttributes:@[@"email", @"address"]];
> ```
>
> You can also mark attributes as private on a particular `LDContext` instance, for example:
>
> ```swift title="iOS SDK v8.0+ (Swift)" lines wrap theme={null}
> var contextBuilder = LDContextBuilder(key: "example-context-key")
> contextBuilder.trySetValue("name", .string("Sandy"))
> contextBuilder.trySetValue("group", .array([LDValue(stringLiteral: "microsoft")]))
> contextBuilder.addPrivateAttribute(Reference("name"))
> contextBuilder.addPrivateAttribute(Reference("group"))
>
> let context = try contextBuilder.build().get()
> ```
>
> ```objectivec title="iOS SDK v8.0+ (Objective-C)" lines wrap theme={null}
> LDContextBuilder *builder = [[LDContextBuilder alloc] initWithKey:@"example-context-key"];
> [builder trySetValueWithName:@"name" value:[LDValue ofString:@"Sandy"]];
>
> NSArray *groups = [NSArray arrayWithObjects:[LDValue ofString:@"microsoft"], nil];
> [builder trySetValueWithName:@"group" value:[LDValue ofArray:groups]];
>
> [builder addPrivateAttributeWithReference:[[Reference alloc] initWithValue:@"email"]];
> [builder addPrivateAttributeWithReference:[[Reference alloc] initWithValue:@"group"]];
>
> LDContext *context = builder.build.success;
> ```

### JavaScript

> **Expand JavaScript code sample**
>
> You can configure the private attributes option either in the configuration object or in the context object.
>
> In the configuration object, to mark all attributes except the key as private in the JavaScript SDK, use the `allAttributesPrivate` option:
>
> ```js title="JavaScript SDK v3.x+" lines wrap theme={null}
>
> // All attributes marked private
> const client = ld.initialize('example-client-side-id', context, options = {
>   allAttributesPrivate: true
> });
>
> try {
>   await client.waitForInitialization(5);
>   proceedWithSuccessfullyInitializedClient();
> } catch(err) {
>   // Client failed to initialized or timed out
>   // variation() calls return fallback values until initialization completes
> }
>
> ```
>
> ```ts title="JavaScript SDK v3.x+ (TypeScript)" lines wrap theme={null}
> import * as ld from 'launchdarkly-js-client-sdk';
>
> // All attributes marked private
> const options: ld.LDOptions = { allAttributesPrivate: true };
>
> const client = ld.initialize('example-client-side-id', context, options);
>
> try {
>   await client.waitForInitialization(5);
>   proceedWithSuccessfullyInitializedClient();
> } catch(err) {
>   // Client failed to initialized or timed out
>   // variation() calls return fallback values until initialization completes
> }
> ```
>
> To learn more, read [`allAttributesPrivate`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDOptions.html#allAttributesPrivate).
>
> In the configuration object, to mark some attributes as private specify your array of attributes in the `privateAttributes` configuration option:
>
> ```js title="JavaScript SDK v3.x+" lines wrap theme={null}
>
> // Two attributes marked private
> const client = ld.initialize('example-client-side-id', context, options = {
>   privateAttributes: ['email', 'name']
> });
>
> try {
>   await client.waitForInitialization(5);
>   proceedWithSuccessfullyInitializedClient();
> } catch(err) {
>   // Client failed to initialized or timed out
>   // variation() calls return fallback values until initialization completes
> }
>
> ```
>
> ```ts title="JavaScript SDK v3.x+ (TypeScript)" lines wrap theme={null}
> import * as ld from 'launchdarkly-js-client-sdk';
>
> // Two attributes marked private
> const options = { privateAttributes: ['email', 'name'] };
>
> const client = ld.initialize('example-client-side-id', context, options);
>
> try {
>   await client.waitForInitialization(5);
>   proceedWithSuccessfullyInitializedClient();
> } catch(err) {
>   // Client failed to initialized or timed out
>   // variation() calls return fallback values until initialization completes
> }
>
> ```
>
> To learn more, read [`privateAttributes`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDOptions.html#privateAttributes).
>
> In the context object, specify your array of attributes in the `privateAttributes` field of the reserved `_meta` property.
>
> Here's how:
>
> ```js title="JavaScript SDK v3.x+" lines wrap theme={null}
> const context = {
>   kind: 'user',
>   key: 'example-context-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
>   _meta: {
>     privateAttributes: ['email']
>   }
> };
>
> ```
>
> ```ts title="JavaScript SDK v3.x+ (TypeScript)" lines wrap theme={null}
> import * as ld from 'launchdarkly-js-client-sdk';
>
> const context: ld.LDContext = {
>   key: 'example-context-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
>   _meta: {
>     privateAttributes: ['email'],
>   }
> };
>
> ```
>
> To learn more, read [`privateAttributes`](https://launchdarkly.github.io/js-client-sdk/interfaces/LDContextMeta.html#privateAttributes).

### Node.js (client-side)

> **Expand Node.js (client-side) code sample**
>
> To mark all attributes except the key as private in the Node.js SDK, you can use the `allAttributesPrivate` option:
>
> ```js title="Node.js SDK v3.0 (JavaScript)" lines wrap theme={null}
> const context = {
>   kind: 'user',
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com'
> };
> // All attributes marked private
> const client = ld.initialize('example-client-side-id', context, {
>   allAttributesPrivate: true
> });
> // Two attributes marked private
> const clientSomePrivate = ld.initialize('example-client-side-id', context, {
>   privateAttributes: ['email', 'name']
> });
> ```
>
> ```ts title="Node.js SDK v3.0 (TypeScript)" expandable lines wrap theme={null}
> import * as ld from 'launchdarkly-node-client-sdk';
>
> const context: ld.LDContext = {
>   kind: 'user',
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
> };
> // All attributes marked private
> const options: ld.LDOptions = { allAttributesPrivate: true };
>
> const client = ld.initialize('example-client-side-id', context, options);
> // Two attributes marked private
> const optionsSomePrivate = { privateAttributes: ['email', 'name'] };
>
> const clientSomePrivate = ld.initialize('example-client-side-id', context, optionsSomePrivate);
> ```
>
> You can also specify an array of which attributes should be private with the `privateAttributes` option. You can configure this option on a per-context basis by specifying which attributes should be private in your context object.
>
> You can configure this option in both the context object and the configuration object:
>
> ```js title="Node.js SDK v3.0 (JavaScript)" lines wrap theme={null}
> const context = {
>   kind: 'user',
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
>   _meta: {
>     privateAttributes: ['email']
>   }
> };
>
> const client = ld.initialize('example-client-side-id', context, {
>   privateAttributes: ['email']
> });
> ```
>
> ```ts title="Node.js SDK v3.0 (TypeScript)" lines wrap theme={null}
> import * as ld from 'launchdarkly-node-client-sdk';
>
> const context: ld.LDContext = {
>   kind: 'user',
>   key: 'example-user-key',
>   name: 'Sandy Smith',
>   email: 'sandy@example.com',
>   _meta: {
>     privateAttributes: ['email'],
>   }
> };
> const options: ld.LDOptions = { privateAttributes: ['email'] };
>
> const client = ld.initialize('example-client-side-id', context, options);
> ```
>
> In the above example, the SDK sends only the context key and name back to LaunchDarkly.

### React Native

> **Expand React Native code sample**
>
> You can configure this option in the configuration object, to apply to all contexts, either for all attributes or some attributes:
>
> ```js title="React Native SDK v10" lines wrap theme={null}
> // All attributes marked private
> const options = {
>   allAttributesPrivate: true
> }
> const client = new ReactNativeLDClient('example-mobile-key', AutoEnvAttributes.Enabled, options);
>
> // Two attributes marked private
> const optionsSomePrivate = {
>   privateAttributes: ['email', 'address']
> }
> const clientSomePrivate = new ReactNativeLDClient('example-mobile-key', AutoEnvAttributes.Enabled, optionsSomePrivate);
> ```
>
> To learn more, read [`allAttributesPrivate`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/interfaces/LDOptions.html#allAttributesPrivate) and [`privateAttributes`](https://launchdarkly.github.io/js-core/packages/sdk/react-native/docs/interfaces/LDOptions.html#privateAttributes).
>
> You can also mark an attribute as private for a particular context:
>
> ```js title="React Native SDK v7+" lines wrap theme={null}
> const context = {
>   kind: 'user',
>   key: 'example-user-key',
>   firstName: 'Sandy',
>   lastName: 'Smith',
>   email: 'sandy@example.com',
>   address: {
>     street: '123 Main St',
>     city: 'Springfield'
>   },
>   _meta: {
>     privateAttributes: ['email', '/address/street']
>   }
> };
> ```
>
> For attributes that are objects, you can mark specific fields private, using the `/` delimiter followed by the attribute name, then the `/` delimiter followed by the JSON property within the value. In the example, the attribute `"address": { "street": "Main St", "city": "Springfield" }` has only the `/address/street` marked as private.

### React Web

All context-related functionality provided by the [JavaScript SDK](#javascript) is also available in the React Web SDK.

### Roku

> **Expand Roku code sample**
>
> You can configure this option in the configuration object, to apply to all contexts, either for all attributes or some attributes:
>
> ```brightscript title="Brightscript" lines wrap theme={null}
> ' All attributes marked private
> config = LaunchDarklyConfig("example-mobile-key", launchDarklyTaskNode)
> config.setAllAttributesPrivate(true)
>
> LaunchDarklySGInit(config, context)
> client = LaunchDarklySG(launchDarklyTaskNode)
>
> ' Two attributes marked private
> config = LaunchDarklyConfig("example-mobile-key", launchDarklyTaskNode)
> config.addPrivateAttribute("email")
> config.addPrivateAttribute("address")
>
> LaunchDarklySGInit(config, context)
> client = LaunchDarklySG(launchDarklyTaskNode)
> ```
>
> You can also mark an attribute as private for a particular context:
>
> ```brightscript title="BrightScript" lines wrap theme={null}
> ' when creating a context
> context = LaunchDarklyCreateContext({
>     "kind": "user",
>     "key": "context-key-123-abc",
>     "email": "sandy@example.com",
>     "_meta": { privateAttributes: ["email"] }
> })
> ```

### Vue

All context-related functionality provided by the [JavaScript SDK](#javascript) SDK is also available in the Vue SDK.

## Server-side SDKs

Here are the configuration options for private context and user attributes in 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 the server-side .NET SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * When creating the LaunchDarkly `Configuration` object, you can configure [`Events`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/server/api/LaunchDarkly.Sdk.Server.ConfigurationBuilder.html#LaunchDarkly_Sdk_Server_ConfigurationBuilder_Events_) with [`AllAttributesPrivate`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/server/api/LaunchDarkly.Sdk.Server.Integrations.EventProcessorBuilder.html#LaunchDarkly_Sdk_Server_Integrations_EventProcessorBuilder_AllAttributesPrivate_), which takes in a boolean parameter. If `true`, the SDK removes all attributes for all contexts before sending the context to LaunchDarkly, except the key.
> * Or, you can configure `Events` with [`PrivateAttributes`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/server/api/LaunchDarkly.Sdk.Server.Integrations.EventProcessorBuilder.html#LaunchDarkly_Sdk_Server_Integrations_EventProcessorBuilder_PrivateAttributes_), which takes any number of attribute names or slash-delimited paths to designated a JSON property within an attribute, such as `/address/street`. If any context has a custom or built-in attribute that matches one of these names, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```csharp title=".NET SDK v7.0+ (C#)" maxLines=0 expandable lines wrap theme={null}
> // All attributes marked as private
> var config = Configuration.Builder("YOUR_SDK_KEY")
>     .Events(
>         Components.SendEvents()
>            .AllAttributesPrivate(true)  // defaults to false
>     )
>     .Build();
>
> var client = new LdClient(config);
>
> // Two attributes marked as private
> config = Configuration.Builder("YOUR_SDK_KEY")
>     .Events(
>         Components.SendEvents()
>           .PrivateAttributes("email", "address")
>     )
>     .Build();
>
> client = new LdClient(config);
> ```
>
> You can also mark attributes as private when building the context object by calling [`Private()`](https://launchdarkly.github.io/dotnet-core/pkgs/sdk/server/api/LaunchDarkly.Sdk.ContextBuilder.html#LaunchDarkly_Sdk_ContextBuilder_Private_) after setting the attribute on the context builder.
>
> For example:
>
> ```csharp title=".NET SDK v7.0+ (C#)" lines wrap theme={null}
> var context = Context.Builder("example-context-key")
>     .Set("email", "sandy@example.com")
>     .Private("email")
>     .Build();
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Apex

> **Expand Apex code sample**
>
> You can configure the Apex SDK to treat some or all user attributes as private user attributes, either using the `LDConfig` object or on a per-user basis.
>
> When creating the `LDConfig` object, you can use `setAllAttributesPrivate(true)`. When you do this, all user attributes, except the key, are redacted before the SDK sends the user to LaunchDarkly.
>
> Here's how:
>
> ```java title="Java" lines wrap theme={null}
> LDConfig config = new LDConfig.Builder()
>     .setAllAttributesPrivate(true)
>     .build();
> ```
>
> You can also define private attribute names on a per-user basis:
>
> ```java title="Java" lines wrap theme={null}
> Set<String> privateAttributes = new Set<String>();
> privateAttributes.add('firstName');
>
> LDUser user = new LDUser.Builder('example-user-key')
>     .setFirstName('alice')
>     .setPrivateAttributeNames(privateAttributes)
>     .build();
> ```

### C++ (server-side)

> **Expand C++ (server-side) code sample**
>
> In the C++ SDK there are three ways to define private attributes for the LaunchDarkly client:
>
> * When creating the config object, you can use `AllAttributesPrivate`. When you do this, the SDK only sends the context key and kind to LaunchDarkly.
>
>   For example:
>
> ```cpp title="C++ SDK v3.0 (native)" lines wrap theme={null}
> auto config_builder = server_side::ConfigBuilder("YOUR_SDK_KEY");
> config_builder.Events().AllAttributesPrivate(true);
> auto config = config_builder.Build();
> ```
>
> ```c title="C++ SDK v3.0 (C binding)" lines wrap theme={null}
> /* sets all attributes private */
> LDServerConfigBuilder config_builder = LDServerConfigBuilder_New("example-mobile-key");
> LDServerConfigBuilder_Events_AllAttributesPrivate(config_builder, true);
>
> LDServerConfig config;
> LDStatus config_status = LDServerConfigBuilder_Build(config_builder, &config);
>
> /* sets "email" and "address" private */
> config_builder = LDServerConfigBuilder_New("example-mobile-key");
> LDServerConfigBuilder_Events_PrivateAttribute(config_builder, "email");
> LDServerConfigBuilder_Events_PrivateAttribute(config_builder, "address");
>
> config_status = LDServerConfigBuilder_Build(config_builder, &config);
> ```
>
> * When creating the config object, you can list specific private attributes with `PrivateAttributes`. The SDK removes all attributes in this list before sending the context to LaunchDarkly.
>
>   Here's how:
>
> ```cpp title="C++ SDK v3.0 (native)" lines wrap theme={null}
> auto config_builder = server_side::ConfigBuilder("YOUR_SDK_KEY");
> config_builder.Events().PrivateAttributes({"email"});
> auto config = config_builder.Build();
> if (!config) {
>     /* an error occurred, config is not valid */
> }
> ```
>
> * You can also define private attributes on a per-context basis. For example:
>
> ```cpp title="C++ SDK v3.0 (native)" lines wrap theme={null}
> auto context = ContextBuilder()
>   .Kind("user", "example-user-key")
>   .SetPrivate("email", "sandy@example.com")
>   .Build();
> ```
>
> To learn more, read [`ContextBuilder`](https://launchdarkly.github.io/cpp-sdks/libs/server-sdk/docs/html/classlaunchdarkly_1_1ContextBuilder.html).

### Erlang

> **Expand Erlang code sample**
>
> Here's how to set context attributes as private for all or just some contexts:
>
> ```erlang title="Erlang" lines wrap theme={null}
> %% All attributes marked as private
> ldclient:start_instance("YOUR_SDK_KEY", #{private_attributes => all}),
>
> %% Two attributes marked as private
> ldclient:start_instance("YOUR_SDK_KEY", #{private_attributes => [<<"email">>, <<"address">>]})
> ```
>
> Here's how to set context attributes as private for a specific context:
>
> ```erlang title="Erlang" lines wrap theme={null}
>     ContextWithPrivateAttributes = ldclient_context:set_private_attributes([<<"name">>, <<"/address/street">>],
>         ldclient_context:set(<<"name">>, <<"Global Health Services">>,
>         ldclient_context:set(<<"email">>, <<"info@globalhealthexample.com">>,
>         ldclient_context:set(<<"address">>, #{
>             <<"street">> => <<"123 Main Street">>,
>             <<"city">> => <<"Springfield">>
>         },
>     ldclient_context:new(<<"context-key-456def">>, <<"organization">>)))))
> ```
>
> In the example, only the `name` and `/address/street` attributes are private for this context.

### Go

> **Expand Go code sample**
>
> In the Go SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * You can set the configuration option `AllAttributesPrivate` to true. If you enable this, the SDK removes all attributes for all contexts before it sends the context to LaunchDarkly, except the key and kind.
> * You can set the configuration option `PrivateAttributes` to a list of attribute names. If any context has an attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> Here's how to to define private attributes:
>
> ```go title="Go SDK v6+" lines wrap theme={null}
> import (
>     ld "github.com/launchdarkly/go-server-sdk/v6"
>     "github.com/launchdarkly/go-server-sdk/v6/ldcomponents"
> )
>
> var config ld.Config
>
> // Make all attributes private for all contexts
> config.Events = ldcomponents.SendEvents().AllAttributesPrivate(true)
>
> // Or, make just the email and address attributes private for all contexts
> config.Events = ldcomponents.SendEvents().
>     PrivateAttributes("email", "address")
> ```
>
> You can also define a set of private attributes on the context object itself. In the following example, "email" and the "street" field of the "address" attribute are private for this context, in addition to any private attributes that were specified globally:
>
> ```go title="Go SDK v6+" expandable lines wrap theme={null}
> import (
>     "github.com/launchdarkly/go-sdk-common/v3/ldcontext"
>     "github.com/launchdarkly/go-sdk-common/v3/ldvalue"
> )
>
> context := ldcontext.NewBuilder("example-context-key").
>     Kind("organization").
>     Name("Global Health Services").
>     SetString("email", "info@globalhealthexample.com").
>     SetValue("address", ldvalue.ObjectBuild().
>         SetString("street", "123 Main Street").
>         SetString("city", "Springfield").
>         Build()).
>     Private("email").
>     Private("/address/street").
>     Build()
> ```

### Haskell

> **Expand Haskell code sample**
>
> Optionally, you can configure the Haskell SDK to treat some or all context attributes as [private attributes](/docs/home/flags/private-context-attributes.md). You can use private context attributes for targeting purposes, but the SDK removes private context attributes from the data it sends to LaunchDarkly.
>
> There are two ways to define private attributes for the entire LaunchDarkly client:
>
> * When you create the `Config` object, use `configSetAllAttributesPrivate` to set all context attributes as private. When you do this, all context attributes, except the key and kind, are removed before the SDK sends the context to LaunchDarkly.
> * When you create the `Config` object, you can list specific private attributes with `configSetPrivateAttributeNames`. If any context has attributes named in this list, the SDK removes them before sending the context to LaunchDarkly.
>
> Here's how:
>
> ```haskell title="Haskell SDK v4.0" lines wrap theme={null}
> import qualified Data.Set as S
> import qualified LaunchDarkly.Server.Reference as R
>
> -- All attributes marked private
> configAllPrivate = makeConfig "YOUR_SDK_KEY" & configSetAllAttributesPrivate True
>
> -- Two attributes marked private
> configSomePrivate = makeConfig sdkKey
>   & configSetPrivateAttributeNames (S.fromList $ map R.makeLiteral ["name", "email"])
> ```
>
> You can also define private attribute names on a per-context basis.
>
> For example:
>
> ```haskell title="Haskell SDK v4.0" lines wrap theme={null}
> context' = makeContext "key" "user"
>   & withName "Sandy"
>   & withAttribute "email" "sandy@example.com"
>   & withPrivateAttributes (S.fromList $ map R.makeLiteral ["name", "email"])
> ```

### Java

> **Expand Java code sample**
>
> In the Java SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * When creating the `LDConfig` object, you can call the [`allAttributesPrivate`](https://launchdarkly.github.io/java-core/lib/sdk/server/com/launchdarkly/sdk/server/integrations/EventProcessorBuilder.html#allAttributesPrivate-boolean-) method, which takes in a boolean parameter. If `true`, all context attributes except the key for all contexts are removed before the SDK sends the context to LaunchDarkly.
> * When creating the `LDConfig` object, you can call the [`privateAttributes`](https://launchdarkly.github.io/java-core/lib/sdk/server/com/launchdarkly/sdk/server/integrations/EventProcessorBuilder.html#privateAttributes-java.lang.String...-) method, which takes in a set of custom or built-in attributes as a parameter. If any context has a custom or built-in attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> Here's how to define private attributes:
>
> ```java title="Java SDK v6.0+" lines wrap theme={null}
> // All attributes marked private
> LDConfig configWithAllAttributesPrivate = new LDConfig.Builder()
>   .events(
>     Components.sendEvents()
>       .allAttributesPrivate(true)
>   )
>   .build();
>
> // Some attributes marked private
> LDConfig configWithSpecificAttributesPrivate = new LDConfig.Builder()
>   .events(
>     Components.sendEvents()
>       .privateAttributes("name", "email", "someAttribute")
>   )
>   .build();
> ```
>
> You can also mark attributes as private when building the context object by calling the `privateAttributes` builder method. For example:
>
> ```java title="Java SDK v6.0+" lines wrap theme={null}
> LDContext context = LDContext.builder("example-context-key")
>   .set("email", "sandy@example.com")
>   .privateAttributes("email")
>   .build();
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Lua

> **Expand Lua code sample**
>
> In the Lua SDK there are two ways to define private attributes for the LaunchDarkly client:
>
> * Use `allAttributesPrivate` to remove all context attributes except for the kind and key from all contexts before the SDK sends the contexts to LaunchDarkly.
> * Use `privateAttributes` to designate a list of private attributes. If any context has an attribute named in this list, the SDK removes that attribute before sending the context to LaunchDarkly.
>
> Here's how to mark attributes as private:
>
> ```lua title="Lua SDK v2" lines wrap theme={null}
> -- sets all attributes private
> local configAllPrivate = {
>     events = {
>         allAttributesPrivate = true
>     }
> }
>
> -- sets "email" and "address" private
> local configSomePrivate = {
>     events = {
>         privateAttributes = { "email", "address" }
>     }
> }
> ```
>
> You can also define private attributes for a particular context using a list of `privateAttributes`:
>
> ```lua title="Lua SDK v2" lines wrap theme={null}
> local user = ld.makeContext({
>     user = {
>         key  = "example-user-key",
>         attributes = {
>             firstName = "Sandy",
>             lastName  = "Smith",
>             email     = "sandy@example.com",
>             groups    = { "Acme", "Global Health Services" }
>         },
>         privateAttributes = { "email" }
>     }
> })
> ```
>
> To learn more, read [`clientInit`](https://launchdarkly.github.io/lua-server-sdk/modules/launchdarkly-server-sdk.html#clientInit) and [`makeContext`](https://launchdarkly.github.io/lua-server-sdk/modules/launchdarkly-server-sdk.html#makeContext).

### Node.js (server-side)

> **Expand Node.js (server-side) code sample**
>
> In the Node.js SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * In the LaunchDarkly `LDOptions`, you can set `allAttributesPrivate` to `true`. If you enable this, the SDK removes all attributes for all contexts before sending the context to LaunchDarkly, except the kind and key.
> * In the LaunchDarkly `LDOptions` object, you can define a list of `privateAttributes`. If any context has a custom or built-in attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```js title="Node.js SDK v7.0+ (JavaScript)" lines wrap theme={null}
> // All attributes marked private
> const options = {
>   allAttributesPrivate: true
> };
> client = ld.init('YOUR_SDK_KEY', options);
>
> // Two attributes marked private
> const optionsSomePrivate = {
>   privateAttributes: ['email', 'address']
> };
> client = ld.init('YOUR_SDK_KEY', optionsSomePrivate);
> ```
>
> ```ts title="Node.js SDK v7.0+ (TypeScript)" lines wrap theme={null}
> import { LDOptions } from '@launchdarkly/node-server-sdk';
>
> // All attributes marked private
> const options: LDOptions = {
>   allAttributesPrivate: true
> };
>
> const client = ld.init('YOUR_SDK_KEY', options);
>
> // Two attributes marked private
> const optionsSomePrivate: LDOptions = {
>   privateAttributes: ['email', 'address']
> };
>
> const clientSomePrivate = ld.init('YOUR_SDK_KEY', optionsSomePrivate);
> ```
>
> You can also define a set of `privateAttributes` on the context object. For example:
>
> ```ts title="Node.js SDK v8.x+ (TypeScript)" lines wrap theme={null}
> import * as ld from '@launchdarkly/node-server-sdk';
>
> const user: ld.LDContext = {
>   kind: 'user',
>   key: 'example-user-key',
>   email: 'sandy@example.com',
>   _meta: {
>     privateAttributes: ['email'],
>   }
> };
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### PHP

> **Expand PHP code sample**
>
> In the PHP SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * In the LaunchDarkly `config`, you can set `all_attributes_private` to `true`. If you enable this, the SDK removes all attributes except the key and kind from a context before sending the context to LaunchDarkly.
> * In the LaunchDarkly `config` object, you can define a list of `private_attribute_names`. If any context has a custom or built-in attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```php title="PHP SDK v5.0+" lines wrap theme={null}
> // All attributes marked private
> $client = new LaunchDarkly\LDClient($sdkKey, ['all_attributes_private' => true]);
>
> // Two attributes marked private
> $client = new LaunchDarkly\LDClient($sdkKey, ['private_attribute_names' => ['name', 'email']]);
> ```
>
> You can also mark attributes as private when building the context object by calling the equivalent "private" [`LDContextBuilder`](http://launchdarkly.github.io/php-server-sdk/classes/LaunchDarkly-LDContextBuilder.html) method.
>
> For example:
>
> ```php title="PHP SDK v5.0+" lines wrap theme={null}
> $context = LDContext::builder('example-context-key')
>     ->set('email', 'sandy@example.com')
>     ->private('email')
>     ->build();
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Python

> **Expand Python code sample**
>
> In the Python SDK there are two ways to define private attributes for the LaunchDarkly client:
>
> * In the LaunchDarkly `config`, you can set `all_attributes_private` to true. If you enable this, the SDK removes all context attributes for all contexts before sending the context to LaunchDarkly, except the key.
> * In the LaunchDarkly `config` object, you can define a list of attributes in `private_attributes`. If any context has a custom or built-in attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```python title="Python SDK v8.0+" lines wrap theme={null}
> # All attributes marked private
> config = Config(all_attributes_private=True)
>
> # Two attributes marked private
> config = Config(private_attributes=["name", "email"])
> ```
>
> You can also mark attributes as private when building the context object by calling the `private` builder method. For example:
>
> ```python title="Python SDK v8.0+" lines wrap theme={null}
> context = Context.builder("example-context-key") \
>     .set("email", "sandy@example.com") \
>     .private("email") \
>     .build()
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Ruby

> **Expand Ruby code sample**
>
> In the Ruby SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * In the LaunchDarkly `config`, you can set `all_attributes_private` to true. If you enable this, the SDK removes all context attributes for all contexts before sending the context to LaunchDarkly, except the key.
> * In the LaunchDarkly config object, you can define a list of `private_attributes`. If any context has a custom or built-in attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```ruby title="Ruby SDK v7.0+" lines wrap theme={null}
> # All attributes marked private
> config = LaunchDarkly::Config.new({all_attributes_private: true})
>
> # Two attributes marked private
> config = LaunchDarkly::Config.new({private_attributes: ["name", "email"]})
> ```
>
> You can also define a set of `privateAttributes` on the context object. For example:
>
> ```ruby title="Ruby SDK v7.0+" lines wrap theme={null}
> context = LaunchDarkly::LDContext.create({
>   key: "example-user-key",
>   kind: "user",
>   firstName: "Sandy",
>   lastName: "Smith",
>   email: "sandy@example.com",
>   groups: ["Acme", "Global Health Services"],
>   _meta: {
>     privateAttributes: ['email']
>   }
> })
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Rust

> **Expand Rust code sample**
>
> In the Rust SDK there are two ways to define private attributes for the entire LaunchDarkly client:
>
> * In the LaunchDarkly config object, you can set `all_attributes_private` to true. If you enable this, the SDK removes all attributes for all contexts before sending the context to LaunchDarkly, except the key and kind.
> * In the LaunchDarkly config object, you can define a list of `private_attributes`. If any contexts has an attribute named in this list, the SDK removes it before sending the context to LaunchDarkly.
>
> For example:
>
> ```rust title="Rust SDK v1+" lines wrap theme={null}
> // All attributes marked private
> let config_builder = ConfigBuilder::new("YOUR_SDK_KEY");
> let mut processor_builder = EventProcessorBuilder::new();
> processor_builder.all_attributes_private(true);
> config_builder.event_processor(&processor_builder);
>
> // Two attributes marked private
> let config_builder = ConfigBuilder::new("YOUR_SDK_KEY");
> let mut processor_builder = EventProcessorBuilder::new();
> processor_builder.private_attributes(
>     vec![Reference::new("email"), Reference::new("address")]
>         .into_iter()
>         .collect(),
> );
> config_builder.event_processor(&processor_builder);
> ```
>
> You can also define private attributes on the context object. For example:
>
> ```rust title="Rust SDK v1+" lines wrap theme={null}
> let context = ContextBuilder::new("example-context-key")
>     .set_value("email", "youremail@example.com".into())
>     .add_private_attribute(Reference::new("email"))
>     .build()?;
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

## AI SDKs

Here are the configuration options for private context attributes in AI SDKs:

* [.NET AI](#net-ai)
* [Go AI](#go-ai)
* [Node.js (server-side) AI](#node-js-server-side-ai)
* [Python AI](#python-ai)
* [Ruby AI](#ruby-ai)

### .NET AI

> **Expand .NET AI SDK code sample**
>
> In the .NET AI SDK you can mark attributes as private when building the context object by calling `Private()` after setting the attribute on the context builder.
>
> For example:
>
> ```csharp title=".NET AI SDK" lines wrap theme={null}
> var context = Context.Builder("example-context-key")
>     .Set("email", "sandy@example.com")
>     .Private("email")
>     .Build();
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Go AI

> **Expand Go AI SDK code sample**
>
> In the Go AI SDK you can mark attributes as private when building the context object by calling `Private()` after setting the attribute on the context builder.
>
> For example:
>
> ```go title="Go AI SDK" lines wrap theme={null}
> import (
>     "github.com/launchdarkly/go-sdk-common/v3/ldcontext"
> )
>
> context := ldcontext.NewBuilder("example-context-key").
>     Kind("organization").
>     Name("Global Health Services").
>     SetString("email", "info@globalhealthexample.com").
>     Private("email").
>     Build()
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Java AI

> **Expand Java AI SDK code sample**
>
> In the Java AI SDK, you can mark attributes as private when building the context object by calling the `privateAttributes` builder method.
>
> For example:
>
> ```java title="Java AI SDK" lines wrap theme={null}
> LDContext context = LDContext.builder("example-context-key")
>   .set("email", "sandy@example.com")
>   .privateAttributes("email")
>   .build();
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Node.js (server-side) AI

> **Expand Node.js (server-side) AI SDK code sample**
>
> In the Node.js (server-side) AI SDK you can define a set of `privateAttributes` on the context object.
>
> Here's how:
>
> ```ts title="Node.js (server-side) AI SDK (TypeScript)" lines wrap theme={null}
> const context: LDContext = {
>   kind: 'user',
>   key: 'example-user-key',
>   email: 'sandy@example.com',
>   _meta: {
>     privateAttributes: ['email'],
>   }
> };
> ```
>
> ```ts title="Node.js (server-side) AI SDK (JavaScript)" lines wrap theme={null}
> const context = {
>   kind: 'user',
>   key: 'example-user-key',
>   email: 'sandy@example.com',
>   _meta: {
>     privateAttributes: ['email'],
>   }
> };
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Python AI

> **Expand Python AI code sample**
>
> In the Python AI SDK you can mark attributes as private when building the context object by calling the `private` builder method.
>
> Here's how:
>
> ```python title="Python AI SDK" lines wrap theme={null}
> context = Context.builder("example-context-key") \
>     .set("email", "sandy@example.com") \
>     .private("email") \
>     .build()
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.

### Ruby AI

> **Expand Ruby AI code sample**
>
> In the Ruby AI SDK you can mark attributes as private when creating the context.
>
> Here's how:
>
> ```ruby title="Ruby AI SDK" lines wrap theme={null}
> context = LaunchDarkly::LDContext.create({
>     key: "example-user-key",
>     kind: "user",
>     firstName: "Sandy",
>     lastName: "Smith",
>     email: "sandy@example.com",
>     groups: ["Acme", "Global Health Services"],
>     _meta: {
>       privateAttributes: ['email']
>     }
> })
> ```
>
> When the SDK sends this context back to LaunchDarkly, it removes the `email` attribute.
