C++ Server SDK
Statsig's Next-gen Cpp Server SDK built in our [Server Core](/server-core) framework
Setup the SDK
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.
CMakeFetchContent_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)Initialize the SDK
After installation, initialize the SDK using a Server Secret Key from the Statsig console.Server Secret Keys should always be kept private. If you expose one, you can disable and recreate it in the Statsig console.
An optional
optionsparameter accepts aStatsigOptionsobject 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();initializeperforms a network request. AfterinitializeBlockingcompletes, virtually all SDK operations are synchronous (refer to Evaluating Feature Gates in the Statsig SDK). The SDK fetches updates from Statsig in the background, independent of your API calls.
Tested platforms
testedPlatforms snippet for C++ Core. Use the 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.Working with the SDK
Checking a Feature Flag/Gate
After the SDK is initialized, you can fetch a Feature Gate. 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 toreturn false;) by default.All APIs require a user object (refer to Statsig user). To check a gate for a user:
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:
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. The API is similar to Feature Gates, but returns a JSON object from which you can retrieve typed parameters. For example:// 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 are recommended because layers make parameters reusable and support mutually exclusive experiments.// 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:
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 valuerule_id: The ID of the rule that served this gateid_type: The type of the evaluationevaluation_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:
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.
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.
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
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
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.
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) -> boolget_dynamic_config(user: StatsigUser, config_name: str, options: Optional[DynamicConfigEvaluationOptions] = None) -> DynamicConfigget_experiment(user: StatsigUser, experiment_name: str, options: Optional[ExperimentEvaluationOptions] = None) -> DynamicConfigget_layer(user: StatsigUser, layer_name: str, options: Optional[LayerEvaluationOptions] = None) -> Layerget_feature_gate(user: StatsigUser, gate_name: str, options: Optional[FeatureGateEvaluationOptions] = None) -> FeatureGatelog_event(user: StatsigUser, event_name: str, value: Optional[Union[str, float]] = None, metadata: Optional[Dict[str, str]] = None) -> Noneshutdown() -> 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.
Was this helpful?