Documentation Index
Fetch the complete documentation index at: https://growthbook-preview.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
OpenFeature is a CNCF-incubating open standard for feature flagging. GrowthBook provides OpenFeature provider SDKs for Python, Go, .NET, and Java — listed in the OpenFeature ecosystem.
Prerequisites
The API host:
| Environment | API Host |
|---|
| Cloud | https://cdn.growthbook.io |
| Self-hosted | Your own GrowthBook URL (e.g. https://growthbook.example.com) |
Why Use OpenFeature with GrowthBook?
OpenFeature defines a vendor-neutral interface for evaluating feature flags. Using a GrowthBook OpenFeature provider means:
- Vendor portability — Your flag evaluation code is identical regardless of which provider is active. Switching from or to GrowthBook only requires changing the provider bootstrap, not a single flag call.
- Standardized API — Teams use the same OpenFeature interface they already know across all services.
- Ecosystem compatibility — OpenFeature-aware tooling — including OpenTelemetry hooks and other instrumentation — works automatically with GrowthBook.
- Polyglot consistency — The same conceptual API spans Python, Go, .NET, Java (and more), giving teams a single mental model.
When to use the native GrowthBook SDK insteadThe native GrowthBook SDKs expose features that go beyond the OpenFeature interface: Sticky Bucketing, Visual Editor experiments, inline experiment definitions, and real-time SSE streaming. If you need those capabilities, use the native SDK for your language instead.
Installation & Setup
GitHub: growthbook-openfeature-provider-python | PyPI: growthbook-openfeature-providerRequirements: Python 3.9+pip install growthbook-openfeature-provider
Async setup (recommended for async frameworks like FastAPI, aiohttp):import asyncio
from openfeature.api import OpenFeatureAPI
from openfeature.evaluation_context import EvaluationContext
from growthbook_openfeature_provider import GrowthBookProvider, GrowthBookProviderOptions
async def main():
provider = GrowthBookProvider(GrowthBookProviderOptions(
api_host="https://cdn.growthbook.io",
client_key="sdk-abc123"
))
await provider.initialize()
OpenFeatureAPI.set_provider(provider)
client = OpenFeatureAPI.get_client("my-app")
# ... evaluate flags ...
await provider.close()
asyncio.run(main())
Synchronous setup:from openfeature.api import OpenFeatureAPI
from growthbook_openfeature_provider import GrowthBookProvider, GrowthBookProviderOptions
provider = GrowthBookProvider(GrowthBookProviderOptions(
api_host="https://cdn.growthbook.io",
client_key="sdk-abc123"
))
provider.initialize_sync()
OpenFeatureAPI.set_provider(provider)
client = OpenFeatureAPI.get_client("my-app")
GitHub: growthbook-openfeature-provider-gogo get github.com/growthbook/growthbook-openfeature-provider-go
package main
import (
"context"
growthbook "github.com/growthbook/growthbook-openfeature-provider-go"
"github.com/open-feature/go-sdk/openfeature"
)
func main() {
provider := growthbook.NewProvider(
growthbook.WithAPIHost("https://cdn.growthbook.io"),
growthbook.WithClientKey("sdk-abc123"),
)
openfeature.SetProvider(provider)
client := openfeature.NewClient("my-app")
// ... evaluate flags ...
}
GitHub: growthbook-openfeature-provider-dotnetdotnet add package GrowthBook.OpenFeature
using OpenFeature;
using GrowthBook.OpenFeature;
var provider = new GrowthBookProvider(new GrowthBookProviderOptions
{
ApiHost = "https://cdn.growthbook.io",
ClientKey = "sdk-abc123"
});
await Api.Instance.SetProviderAsync(provider);
var client = Api.Instance.GetClient("my-app");
// ... evaluate flags ...
GitHub: growthbook-openfeature-provider-java<dependency>
<groupId>io.growthbook</groupId>
<artifactId>growthbook-openfeature-provider</artifactId>
<version>1.0.0</version>
</dependency>
import dev.openfeature.sdk.OpenFeatureAPI;
import io.growthbook.openfeature.GrowthBookProvider;
GrowthBookProvider provider = GrowthBookProvider.builder()
.apiHost("https://cdn.growthbook.io")
.clientKey("sdk-abc123")
.build();
OpenFeatureAPI.getInstance().setProvider(provider);
Client client = OpenFeatureAPI.getInstance().getClient("my-app");
// ... evaluate flags ...
Evaluation Context (Targeting Attributes)
Pass user attributes to the OpenFeature client via an EvaluationContext. These become GrowthBook targeting attributes used for percentage rollouts, feature targeting rules, and experiment bucketing.
The targetingKey maps to the user ID in GrowthBook. Additional attributes (e.g. country, plan, email) are matched against your feature flag targeting conditions.
from openfeature.evaluation_context import EvaluationContext
context = EvaluationContext(
targeting_key="user-123",
attributes={
"country": "US",
"plan": "premium",
"email": "user@example.com",
}
)
context := openfeature.NewEvaluationContext(
"user-123",
map[string]interface{}{
"country": "US",
"plan": "premium",
"email": "user@example.com",
},
)
var context = EvaluationContext.Builder()
.SetTargetingKey("user-123")
.Set("country", "US")
.Set("plan", "premium")
.Set("email", "user@example.com")
.Build();
EvaluationContext context = new ImmutableContext("user-123", Map.of(
"country", new Value("US"),
"plan", new Value("premium"),
"email", new Value("user@example.com")
));
Evaluating Feature Flags
OpenFeature defines five value types. GrowthBook’s feature flags map to all of them.
Boolean
The most common type — use for on/off feature gates.
# Synchronous
enabled = client.get_boolean_value("dark-mode", False, context)
# Async (returns FlagEvaluationDetails with value, reason, variant, etc.)
details = await provider.resolve_boolean_details_async("dark-mode", False, context)
enabled = details.value
enabled, _ := client.BooleanValue(context, "dark-mode", false, openfeature.EvaluationContext{})
var enabled = await client.GetBooleanValueAsync("dark-mode", false, context);
Boolean enabled = client.getBooleanValue("dark-mode", false, context);
String
Use for multi-variant flags where the value is a string (e.g. button color, layout variant).
variant = client.get_string_value("button-color", "blue", context)
variant, _ := client.StringValue(context, "button-color", "blue", openfeature.EvaluationContext{})
var variant = await client.GetStringValueAsync("button-color", "blue", context);
String variant = client.getStringValue("button-color", "blue", context);
Integer & Float/Double
Use for numeric feature values such as rate limits, timeouts, or pricing.
request_limit = client.get_integer_value("api-request-limit", 100, context)
price = client.get_float_value("subscription-price", 9.99, context)
requestLimit, _ := client.IntValue(context, "api-request-limit", 100, openfeature.EvaluationContext{})
price, _ := client.FloatValue(context, "subscription-price", 9.99, openfeature.EvaluationContext{})
var requestLimit = await client.GetIntegerValueAsync("api-request-limit", 100, context);
var price = await client.GetDoubleValueAsync("subscription-price", 9.99, context);
Integer requestLimit = client.getIntegerValue("api-request-limit", 100, context);
Double price = client.getDoubleValue("subscription-price", 9.99, context);
Object
Use for structured feature values (e.g. configuration payloads, theme objects).
config = client.get_object_value("theme-config", {"color": "blue"}, context)
config, _ := client.ObjectValue(context, "theme-config", map[string]interface{}{"color": "blue"}, openfeature.EvaluationContext{})
var config = await client.GetObjectValueAsync("theme-config", new Value(new Structure(new Dictionary<string, Value> { { "color", new Value("blue") } })), context);
Value config = client.getObjectValue("theme-config", new Value(Map.of("color", new Value("blue"))), context);
Configuration Options
| Option | Python | Go | .NET | Java | Description |
|---|
api_host/apiHost | ✓ | ✓ | ✓ | ✓ | GrowthBook CDN or self-hosted URL |
client_key/clientKey | ✓ | ✓ | ✓ | ✓ | SDK Connection key from GrowthBook |
decryption_key | ✓ | — | — | — | Key for encrypted SDK endpoint payloads |
cache_ttl | ✓ | ✓ | — | — | Seconds before re-fetching features (default: 60) |
enabled | ✓ | — | ✓ | — | Enable/disable the provider entirely |
qa_mode | ✓ | — | — | — | Forces all experiments into the control variation |
Shutdown & Cleanup
Always shut down the provider when your application exits to close background connections.
await provider.close() # async
# or
provider.close_sync() # sync
await Api.Instance.ShutdownAsync();
OpenFeatureAPI.getInstance().shutdown();
Further Reading