
## Setup the SDK
{% steps %}
{% step title="Install the SDK" %}
## Installation

All core logic is written in Rust. Statsig attaches prebuilt binaries as assets with each release, so a Rust environment isn't required. The CMakeLists.txt file handles the build configuration.

If you encounter any installation or build issues, contact us.

```CMake
FetchContent_Declare(
    Statsig
    GIT_REPOSITORY    https://github.com/statsig-io/statsig-cpp-core.git
    GIT_TAG           0.12.2-rc.1 
)
FetchContent_MakeAvailable(Statsig)

target_include_directories(CppApp PRIVATE ${statsig_SOURCE_DIR}/include)
target_include_directories(CppApp PRIVATE ${statsig_SOURCE_DIR}/src)

target_link_libraries(CppApp PRIVATE Statsig)
```
{% /step %}

{% step title="Initialize the SDK" %}
After installation, initialize the SDK using a [Server Secret Key from the Statsig console](https://console.statsig.com/api_keys).

{% callout type="warning" %}
Server Secret Keys should always be kept private. If you expose one, you can disable and recreate it in the Statsig console.
{% /callout %}

An optional `options` parameter accepts a `StatsigOptions` object to customize the SDK.

```cpp
#include <statsig/statsig.h>

statsig_cpp_core::StatsigOptionsBuilder optionsBuilder;
optionsBuilder.environment = "development";
optionsBuilder.specs_url = api_v2 + "/download_config_specs";
optionsBuilder.log_event_url = api + "/log_event";
optionsBuilder.id_lists_url = api + "/get_id_lists";
statsig_cpp_core::StatsigOptions options = optionsBuilder.build();
Statsig statsig("server-secret-key", options);
statsig.initializeBlocking().wait();

```

`initialize` performs a network request. After `initializeBlocking` completes, virtually all SDK operations are synchronous (refer to [Evaluating Feature Gates in the Statsig SDK](https://blog.statsig.com/evaluating-feature-gates-in-the-statsig-sdk-a6f8881a1ad8)). The SDK fetches updates from Statsig in the background, independent of your API calls.
{% /step %}
{% /steps %}

## Tested platforms

{% callout type="note" %}
The upstream Statsig docs source doesn't yet include a `testedPlatforms` snippet for C++ Core. Use the [statsig-cpp-core](https://github.com/statsig-io/statsig-cpp-core) release assets and your target Linux distribution when validating Docker images. Add a tested-platforms table here when the snippet is published upstream.
{% /callout %}

## Working with the SDK

### Checking a Feature Flag/Gate

After the SDK is initialized, you can fetch a [**Feature Gate**](/feature-flags/overview). Feature Gates create logic branches in code that you can roll out to different users from the Statsig Console. Gates are **CLOSED** or **OFF** (equivalent to `return false;`) by default.

All APIs require a user object (refer to [Statsig user](#statsig-user)). To check a gate for a user:

```cpp

if (statsig.checkGate(user, "a_gate")) {
    // Gate is on, enable new feature
} else {
    // Gate is off
}
```

You can also disable exposure logging for this evaluation:

```cpp
FeatureGateEvaluationOptions options;
options.disable_exposure_logging = true;
bool gateValue = statsig.check_gate(user, "a_gate", options);
```

### Reading a Dynamic Config

Feature Gates are useful for simple on/off switches with optional user targeting. To send different values (strings, numbers, etc.) to clients based on user attributes such as country, use [**Dynamic Configs**](/dynamic-config/overview). The API is similar to Feature Gates, but returns a JSON object from which you can retrieve typed parameters. For example:

```cpp
// Get a dynamic config for a specific user
DynamicConfig config = statsig.getDynamicConfig(user, "a_config");

// Access config values (We will provide accessors)
std::string product_name = config.value.get("product_name", "Awesome Product v1");
double price = config.value.get("price", 10.0);


// Access evaluation details such as rule id 
statsig_cpp_core::EvaluationDetails detail = config.details;
std::cout << config.rule_id << std::endl;  // The ID of the rule that served this config
std::cout << config.id_type << std::endl;  // The type of the evaluation (experiment, config, etc)

// Advanced Usage:
// You can disable exposure logging for this specific check
DynamicConfigEvaluationOptions options;
options.disable_exposure_logging = true;
config = statsig.getDynamicConfig(user, "a_config", options);
```

### Getting a Layer/Experiment

**Layers/Experiments** let you run A/B/n experiments. Two APIs are available, but [layers](/experiments/layers-overview) are recommended because layers make parameters reusable and support mutually exclusive experiments.

```cpp
// Get a experiment for a specific user
statsig_cpp_core::Experiment exp = statsig.getExpriment(user, "an_experiment");

// Access config values (We will provide accessors)
auto product_name = exp.value.get("product_name", "Awesome Product v1");
auto price = exp.value.get("price", 10.0);


// Access evaluation details such as rule id 
statsig_cpp_core::EvaluationDetails detail = exp.details;
std::cout << exp.rule_id << std::endl;  // The ID of the rule that served this config
std::cout << exp.id_type << std::endl;  // The type of the evaluation (experiment, config, etc)

// Advanced Usage:
// You can disable exposure logging for this specific check
ExperimentEvaluationOptions options;
options.disable_exposure_logging = true;
config = statsig.getExperiment(user, "an_experiment", options);


```

### Retrieving Feature Gate Metadata

To retrieve more information about a gate evaluation than a boolean value, use the Get Feature Gate API, which returns a `FeatureGate` object:

```cpp
FeatureGate gate = statsig.getFeatureGate(user, "example_gate");
std::cout << gate.rule_id << std::endl;
std::cout << gate.value << std::endl;
```

The `get_feature_gate()` method returns a `FeatureGate` object with:

* `value`: The boolean gate value
* `rule_id`: The ID of the rule that served this gate
* `id_type`: The type of the evaluation
* `evaluation_details`: Additional metadata about the evaluation

### Logging an Event

After setting up a Feature Gate or Experiment, track custom events to measure how features or experiment groups affect user behavior. Call the Log Event API and specify the user and event name. You can also provide a value and metadata:

```cpp
statsig.log_event(
    user,  
    "add_to_cart",
    {
        {"price", "9.99"},
        {"item_name", "diet_coke_48_pack"}
    }  
);
```

The `log_event` method supports multiple overloads:

* `log_event(user, event_name)`
* `log_event(user, event_name, string_value)`
* `log_event(user, event_name, string_value, metadata)`

Statsig is adding support for numerical value and metadata.

## Statsig User

The `StatsigUser` object represents a user in Statsig. You must provide a `userID` or at least one of the `customIDs` to identify the user.

When calling APIs that require a user, pass as much information as possible to enable advanced gate and config conditions (such as country or OS/browser checks) and to measure experiment impact accurately. As explained in [why an ID is always required for server SDKs](/sdks/user#why-is-an-id-always-required-for-server-sdks), at least one identifier (userID or customID) is required to provide a consistent experience for each user.

In addition to `userID`, the top-level fields on `StatsigUser` are: `email`, `ip`, `userAgent`, `country`, `locale`, and `appVersion`. You can also pass key-value pairs in the `custom` field to use for targeting.

### Private attributes

Private attributes are user attributes used for evaluation but not forwarded to any integrations. Use them for PII or sensitive data that you don't want to send to third-party services.
```cpp
  statsig_cpp_core::UserBuilder builder;
  builder.setUserID(j["userID"]);
  builder.setCustomIDs(j["customIDs"]);
  builder.setCountry(j["customIDs"]);
  statsig_cpp_core::User user = builder.build();
  // UserBuilder also supports deserialize from json
```

## Statsig Options

You can pass an optional `options` parameter in addition to `sdkKey` during initialization to customize the Statsig client.

### Available options

```cpp
std::optional<std::string> specs_url;
std::optional<std::string> id_lists_url;
std::optional<std::string> log_event_url;
std::optional<std::string> output_log_level;
std::optional<std::string> environment;
bool enable_id_lists = false;
bool disable_all_logging = false;
bool disable_country_lookup = false;
bool disable_network = false;
```

### Proxy and custom network routing

The C++ Server Core SDK currently documents endpoint overrides rather than a dedicated outbound proxy config. Use `specs_url`, `log_event_url`, and `id_lists_url` to route Statsig network calls through your own endpoints or proxy layer.

### Example usage

```cpp
statsig_cpp_core::StatsigOptionsBuilder optionsBuilder;
optionsBuilder.environment = "development";
optionsBuilder.specs_url = api_v2 + "/download_config_specs";
optionsBuilder.log_event_url = api + "/log_event";
optionsBuilder.id_lists_url = api + "/get_id_lists";
statsig_cpp_core::StatsigOptions options = optionsBuilder.build();
```

## Shutting Statsig Down

Because events are batched and periodically flushed, some events may not have been sent when your app or server shuts down. To ensure all logged events are flushed, call `shutdown()` before your application exits.

```cpp
statsig.shutdownBlocking();
```

The `shutdown()` method:

* Flushes any pending events to Statsig servers
* Cleans up resources
* Waits for all operations to complete

## Reference

### API methods

* `check_gate(user: StatsigUser, gate_name: str, options: Optional[FeatureGateEvaluationOptions] = None) -> bool`
* `get_dynamic_config(user: StatsigUser, config_name: str, options: Optional[DynamicConfigEvaluationOptions] = None) -> DynamicConfig`
* `get_experiment(user: StatsigUser, experiment_name: str, options: Optional[ExperimentEvaluationOptions] = None) -> DynamicConfig`
* `get_layer(user: StatsigUser, layer_name: str, options: Optional[LayerEvaluationOptions] = None) -> Layer`
* `get_feature_gate(user: StatsigUser, gate_name: str, options: Optional[FeatureGateEvaluationOptions] = None) -> FeatureGate`
* `log_event(user: StatsigUser, event_name: str, value: Optional[Union[str, float]] = None, metadata: Optional[Dict[str, str]] = None) -> None`
* `shutdown() -> AsyncResult[None]`

### Fields needed methods

The following methods return information about which user fields are needed for evaluation.

* `get_gate_fields_needed(gate_name: str) -> List[str]`
* `get_dynamic_config_fields_needed(config_name: str) -> List[str]`
* `get_experiment_fields_needed(experiment_name: str) -> List[str]`
* `get_layer_fields_needed(layer_name: str) -> List[str]`

These methods return a list of strings representing the user fields required to evaluate the specified gate, config, experiment, or layer.
