### Example: Add Client Hooks Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/client.md Shows how to add a custom hook to the client. ```kotlin client.addHooks(listOf(MyCustomHook())) ``` -------------------------------- ### Set Provider and Get Client (Synchronous Wait) Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/getting-started.md Set the `InMemoryProvider` and wait for it to be ready before obtaining a client for flag evaluation. This is useful when immediate evaluation is required after setup. ```kotlin coroutineScope.launch(Dispatchers.Default) { OpenFeatureAPI.setProviderAndWait(InMemoryProvider()) val client = OpenFeatureAPI.getClient() // Ready to evaluate flags } ``` -------------------------------- ### Example: Track Event with Details Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/client.md Shows how to track a checkout event with a value and structured cart details. ```kotlin client.track( "Checkout", TrackingEventDetails( value = 99.99, structure = ImmutableStructure( "cart_size" to Value.Integer(5) ) ) ) ``` -------------------------------- ### Example: Observe Provider Ready Event Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/client.md Demonstrates how to collect provider ready events from the client's observation flow. ```kotlin client.observe().filterIsInstance().collect { println("Provider ready") } ``` -------------------------------- ### Handling ProviderFatalError Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/errors.md Example demonstrating how to detect if the provider is in a fatal state and handle the resulting error. ```kotlin val status = OpenFeatureAPI.getStatus() if (status is OpenFeatureStatus.Fatal) { println("Provider is in fatal state: ${status.error.message}") // All further evaluations will fail with this error } ``` -------------------------------- ### Example: Get Object Flag Value Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/client.md Demonstrates how to retrieve an object flag with a default structure. ```kotlin val config = client.getObjectValue( "user-config", defaultValue = Value.Structure(mapOf("theme" to Value.String("dark"))) ) ``` -------------------------------- ### Creating TrackingEventDetails Instances Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Examples demonstrating how to instantiate TrackingEventDetails with different combinations of values and structures. ```APIDOC ### Creating TrackingEventDetails ```kotlin // Simple: value only val details1 = TrackingEventDetails(value = 49.99) // With structured data val details2 = TrackingEventDetails( value = 99.99, structure = ImmutableStructure( "items" to Value.Integer(3), "tax" to Value.Double(8.50), "shipping" to Value.String("expedited") ) ) // Structure only val details3 = TrackingEventDetails( structure = ImmutableStructure( "eventType" to Value.String("page_view"), "url" to Value.String("/products") ) ) // Empty (default) val details4 = TrackingEventDetails() ``` ``` -------------------------------- ### Example JVM Log Output Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/logging.md An example of the structured log output generated by the LoggingHook for a successful flag evaluation on a JVM environment. ```text 2026-04-15T10:00:00.123Z [DEBUG] FeatureFlags - Flag evaluation starting flag=my-flag type=BOOLEAN defaultValue=false provider=MyProvider 2026-04-15T10:00:00.124Z [DEBUG] FeatureFlags - Flag evaluation completed flag=my-flag value=true variant=on reason=TARGETING_MATCH provider=MyProvider 2026-04-15T10:00:00.124Z [DEBUG] FeatureFlags - Flag evaluation finalized flag=my-flag ``` -------------------------------- ### Track Feature Flag Events with Client Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Examples demonstrating how to track simple events and events with detailed context using the `Client.track` method. ```kotlin val client = OpenFeatureAPI.getClient() // Simple event client.track("UserSignup") // Event with details client.track( "Checkout", TrackingEventDetails( value = 99.99, structure = ImmutableStructure( "cartSize" to Value.Integer(5), "promoCode" to Value.String("SAVE10") ) ) ) ``` -------------------------------- ### Provider Implementation Example Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/types.md An example of implementing a provider's getBooleanEvaluation method. It fetches a flag value from a store and handles potential exceptions by returning an error code. ```kotlin override fun getBooleanEvaluation( key: String, defaultValue: Boolean, context: EvaluationContext? ): ProviderEvaluation { return try { val value = myFlagStore.getFlag(key).toBoolean() ProviderEvaluation(value, variant = if (value) "on" else "off") } catch (e: Exception) { ProviderEvaluation( defaultValue, errorCode = ErrorCode.FLAG_NOT_FOUND, errorMessage = e.message ) } } ``` -------------------------------- ### before Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/hook.md Called before evaluation begins. Used for setup or validation. Throwing an exception here can short-circuit evaluation. ```APIDOC ## before ### Description Called before evaluation begins. Used for setup or validation. Throwing an exception here can short-circuit evaluation. ### Method ```kotlin fun before(ctx: HookContext, hints: Map) = Unit ``` ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Parameters - **ctx** (`HookContext`) - Required - Context with flag key, type, default value, evaluation context, and metadata - **hints** (`Map`) - Required - Hook hints passed by the caller ### Returns `Unit` ### Description Default no-op implementation. Override to run setup or validation before evaluation. Throw an exception to short-circuit evaluation. ### Example ```kotlin override fun before(ctx: HookContext, hints: Map) { println("About to evaluate flag: ${ctx.flagKey}") // validate context, set up state, etc. } ``` ``` -------------------------------- ### Quick Start: Initialize and Use MultiProvider Source: https://github.com/open-feature/kotlin-sdk/blob/main/docs/multiprovider/README.md Demonstrates how to construct multiple providers, wrap them with MultiProvider, set it as the SDK provider, and then use the client for flag evaluation. Ensure providers are ordered correctly for desired fallback behavior. ```kotlin import dev.openfeature.kotlin.sdk.OpenFeatureAPI import dev.openfeature.kotlin.sdk.multiprovider.MultiProvider import dev.openfeature.kotlin.sdk.multiprovider.FirstMatchStrategy // import dev.openfeature.kotlin.sdk.multiprovider.FirstSuccessfulStrategy // 1) Construct your providers (examples) val experiments = MyExperimentProvider() // e.g., local overrides/experiments val remote = MyRemoteProvider() // e.g., network-backed // 2) Wrap them with MultiProvider in the desired order val multi = MultiProvider( providers = listOf(experiments, remote), strategy = FirstMatchStrategy() // default; FirstSuccessfulStrategy() also available ) // 3) Set the SDK provider and wait until ready OpenFeatureAPI.setProviderAndWait(multi) // 4) Use the client as usual val client = OpenFeatureAPI.getClient("my-app") val enabled = client.getBooleanValue("new-ui", defaultValue = false) ``` -------------------------------- ### Implementing Tracking in a Provider Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Example of how to implement the `track` method in a custom provider to send events to an external service. ```APIDOC ### Implementing Tracking in a Provider ```kotlin class ExperimentationProvider : FeatureProvider { override fun track( trackingEventName: String, context: EvaluationContext?, details: TrackingEventDetails? ) { val event = mapOf( "event" to trackingEventName, "user_id" to (context?.getTargetingKey() ?: "unknown"), "value" to details?.value, "attributes" to details?.asObjectMap() ) experimentationService.recordEvent(event) } } ``` ``` -------------------------------- ### ImmutableStructure Examples Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/structure-and-metadata.md Demonstrates creating ImmutableStructure instances. Use the empty constructor for an empty structure, the map constructor for existing maps, or the vararg pairs constructor for convenience. ```kotlin // Empty val empty = ImmutableStructure() // From map val fromMap = ImmutableStructure(mapOf( "region" to Value.String("us-east-1"), "tier" to Value.String("gold") )) // From pairs val fromPairs = ImmutableStructure( "region" to Value.String("us-west-2"), "tier" to Value.String("silver") ) ``` -------------------------------- ### Initialize and Use OpenFeature Client Source: https://github.com/open-feature/kotlin-sdk/blob/main/README.md Configure an OpenFeature provider and obtain a client to evaluate boolean flags. This example demonstrates setting a provider and then retrieving a boolean flag value. Remember to update imports if migrating from versions prior to 0.6.0. ```kotlin coroutineScope.launch(Dispatchers.Default) { // configure a provider, wait for it to complete its initialization tasks OpenFeatureAPI.setProviderAndWait(customProvider) val client = OpenFeatureAPI.getClient() // get a bool flag value client.getBooleanValue("boolFlag", defaultValue = false) } ``` -------------------------------- ### Provider Status Transitions Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/README.md Illustrates the state transitions of the OpenFeature provider status machine, guiding the SDK lifecycle. ```text NotReady ──[setProviderAndWait]──> Ready ──[provider error]──> Error ↓ [provider recovers] ↓ Ready ──[fatal error]──> Fatal ──[provider.stale]──> Stale ``` -------------------------------- ### Track User Actions with OpenFeature Source: https://github.com/open-feature/kotlin-sdk/blob/main/README.md Example of tracking a 'Checkout' event with associated details like total price and items. Note that tracking event names cannot be empty strings. ```kotlin OpenFeatureAPI.getClient().track( "Checkout", TrackingEventDetails( 499.99, ImmutableStructure( "numberOfItems" to Value.Integer(4), "timeInCheckout" to Value.String("PT3M20S") ) ) ) ``` -------------------------------- ### Handling ProviderNotReadyError Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/errors.md Example showing how to check the provider's status and handle a ProviderNotReadyError if evaluations are attempted too early. ```kotlin val status = OpenFeatureAPI.getStatus() if (status != OpenFeatureStatus.Ready) { val details = client.getBooleanDetails("flag", false) // details.errorCode == ErrorCode.PROVIDER_NOT_READY } ``` -------------------------------- ### Initialize FeatureProvider Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/feature-provider.md Called when the provider is registered. Implementations must block until the provider is ready or throw an error. Use this for setup tasks like connecting to a system and loading flags. ```kotlin override suspend fun initialize(initialContext: EvaluationContext?) { // connect to flag management system flagClient.connect() // load initial flag definitions flagClient.fetchFlags() } ``` -------------------------------- ### Example Usage of LoggerFactory Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/logging.md Instantiate a logger with a custom tag and use it to log an informational message with attributes. ```kotlin val logger = LoggerFactory.getLogger("MyApp") logger.info({ "Application started" }, { mapOf("version" to "1.0") }) ``` -------------------------------- ### Run All Tests Source: https://github.com/open-feature/kotlin-sdk/blob/main/CONTRIBUTING.md Executes all tests across all supported platforms. Ensure Google Chrome or Chrome headless is installed as a prerequisite for browser tests. ```bash ./gradlew allTests ``` -------------------------------- ### Set Provider and Wait for Ready - Kotlin Source: https://github.com/open-feature/kotlin-sdk/blob/main/README.md Registers a provider and waits for it to become ready before proceeding. Use when flag evaluations must happen immediately after provider setup. ```kotlin coroutineScope.launch(Dispatchers.Default) { OpenFeatureAPI.setProviderAndWait(MyProvider()) } ``` -------------------------------- ### Implementing Tracking in a Custom Provider Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Example of implementing the `track` method in a custom `FeatureProvider`. This provider records events using an `experimentationService`. ```kotlin class ExperimentationProvider : FeatureProvider { override fun track( trackingEventName: String, context: EvaluationContext?, details: TrackingEventDetails? ) { val event = mapOf( "event" to trackingEventName, "user_id" to (context?.getTargetingKey() ?: "unknown"), "value" to details?.value, "attributes" to details?.asObjectMap() ) experimentationService.recordEvent(event) } } ``` -------------------------------- ### Implement Custom MultiProvider Strategy Source: https://github.com/open-feature/kotlin-sdk/blob/main/docs/multiprovider/README.md Implement the `MultiProvider.Strategy` interface to define custom logic for evaluating flags across multiple providers. This example demonstrates a basic strategy that iterates through providers and selects a result. ```kotlin import dev.openfeature.kotlin.sdk.* import dev.openfeature.kotlin.sdk.multiprovider.MultiProvider class MyStrategy : MultiProvider.Strategy { override fun evaluate( providers: List, key: String, defaultValue: T, evaluationContext: EvaluationContext?, flagEval: FeatureProvider.(String, T, EvaluationContext?) -> ProviderEvaluation ): ProviderEvaluation { // Example: try all, prefer the highest integer value (demo only) var best: ProviderEvaluation? = null for (p in providers) { val e = p.flagEval(key, defaultValue, evaluationContext) // ... decide whether to keep e as best ... best = best ?: e } return best ?: ProviderEvaluation(defaultValue) } } val multi = MultiProvider(listOf(experiments, remote), strategy = MyStrategy()) ``` -------------------------------- ### Custom Feature Provider Implementation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/feature-provider.md Implement the FeatureProvider interface to create a custom provider. This example shows the basic structure including initialization, context setting, shutdown, and a boolean evaluation method. Ensure all required methods are overridden and implement your specific flag evaluation logic within them. ```kotlin class MyProvider(override val metadata: ProviderMetadata) : FeatureProvider { override val hooks: List> = emptyList() override suspend fun initialize(initialContext: EvaluationContext?) { // setup } override suspend fun onContextSet( oldContext: EvaluationContext?, newContext: EvaluationContext ) { // handle context change } override fun shutdown() { // cleanup } override fun getBooleanEvaluation( key: String, defaultValue: Boolean, context: EvaluationContext? ): ProviderEvaluation { return try { val value = flags.getBoolean(key) ProviderEvaluation(value, variant = if (value) "on" else "off") } catch (e: Exception) { ProviderEvaluation( defaultValue, errorCode = ErrorCode.FLAG_NOT_FOUND, errorMessage = "Flag not found: $key" ) } } // Implement other evaluation methods... } ``` -------------------------------- ### A/B Testing with Flag Tracking Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Combine flag evaluation with event tracking to implement A/B testing flows. This example tracks variant assignment and conversion events. ```kotlin class ABTestingFlow { fun processCheckout() { val client = OpenFeatureAPI.getClient("Checkout") // Check which variant the user is in val variant = client.getStringValue("checkout-variant", "control") // Track the variant assignment client.track( "CheckoutVariantAssigned", TrackingEventDetails( structure = ImmutableStructure( "variant" to Value.String(variant) ) ) ) // Execute variant-specific flow when (variant) { "new" -> processNewCheckout() else -> processControlCheckout() } // Track conversion client.track( "CheckoutCompleted", TrackingEventDetails( value = cartTotal, structure = ImmutableStructure( "variant" to Value.String(variant), "itemCount" to Value.Integer(cartItems.size) ) ) ) } } ``` -------------------------------- ### Creating and Extracting Value Types Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/types.md Demonstrates how to instantiate different `Value` subtypes and how to extract their underlying data using the provided accessor methods. This includes examples for primitive types, complex structures, and lists. ```kotlin // Create values val text = Value.String("hello") val flag = Value.Boolean(true) val count = Value.Integer(42) val balance = Value.Double(99.99) // Extract values val str: String? = text.asString() val bool: Boolean? = flag.asBoolean() // Complex types val obj = Value.Structure(mapOf( "name" to Value.String("Alice"), "age" to Value.Integer(30) )) val list = Value.List(listOf( Value.String("a"), Value.String("b") )) ``` -------------------------------- ### Instantiate FlagEvaluationOptions with Hooks and Hints Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/types.md Create an instance of FlagEvaluationOptions to pass custom hooks and hints to a flag evaluation. This example shows how to provide a custom hook and specific hints. ```kotlin val options = FlagEvaluationOptions( hooks = listOf(MyHook()), hookHints = mapOf("custom" to "data") ) val value = client.getBooleanValue("flag", false, options) ``` -------------------------------- ### Implement InMemoryProvider Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/getting-started.md An example implementation of the `FeatureProvider` interface for in-memory flag evaluation. This provider uses a simple map to store flag states. ```kotlin class InMemoryProvider : FeatureProvider { private val flags = mapOf( "new-dashboard" to true, "beta-feature" to false ) override val metadata: ProviderMetadata = object : ProviderMetadata { override val name = "InMemory" } override val hooks: List> = emptyList() override suspend fun initialize(initialContext: EvaluationContext?) { // Initialize any resources } override fun shutdown() { // Cleanup } override suspend fun onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext) { // Handle context changes } override fun getBooleanEvaluation( key: String, defaultValue: Boolean, context: EvaluationContext? ): ProviderEvaluation { val value = flags[key] ?: defaultValue return ProviderEvaluation(value) } // Implement other evaluation methods... } ``` -------------------------------- ### Implement Provider Event Emission Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/events.md Providers can emit events by returning a Flow from their observe() method. This example shows how to emit ProviderReady, ProviderConfigurationChanged, and ProviderError events. ```kotlin class MyProvider : FeatureProvider { private val eventFlow = MutableSharedFlow() override fun observe(): Flow = eventFlow.asSharedFlow() override suspend fun initialize(initialContext: EvaluationContext?) { // ... initialization ... eventFlow.emit(OpenFeatureProviderEvents.ProviderReady( eventDetails = OpenFeatureProviderEvents.EventDetails( message = "Provider initialized successfully" ) )) } fun notifyFlagsChanged(flags: Set) { CoroutineScope(Dispatchers.Default).launch { eventFlow.emit(OpenFeatureProviderEvents.ProviderConfigurationChanged( eventDetails = OpenFeatureProviderEvents.EventDetails( flagsChanged = flags, message = "Flags updated in management system" ) )) } } fun notifyError(code: ErrorCode, message: String) { CoroutineScope(Dispatchers.Default).launch { eventFlow.emit(OpenFeatureProviderEvents.ProviderError( eventDetails = OpenFeatureProviderEvents.EventDetails( errorCode = code, message = message ) )) } } } ``` -------------------------------- ### Track an Event with TrackingEventDetails Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/types.md Track a custom event using the client, providing a name and TrackingEventDetails. This example demonstrates tracking a 'Checkout' event with a value and structured data. ```kotlin client.track( "Checkout", TrackingEventDetails( value = 99.99, structure = ImmutableStructure( "items" to Value.Integer(5), "coupon" to Value.Boolean(true) ) ) ) ``` -------------------------------- ### Get Client Instance - OpenFeatureAPI Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/openfeature-api.md Obtains a `Client` instance for performing flag evaluations. You can optionally provide a name for client identification and logging purposes. ```kotlin val client = OpenFeatureAPI.getClient("MyApp") ``` -------------------------------- ### Implement Custom Strategy for MultiProvider Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Implement the `Strategy` interface to define custom logic for evaluating feature flags across multiple providers. This example shows parallel evaluation and basic error handling. ```kotlin class CustomStrategy : MultiProvider.Strategy { override fun evaluate( providers: List, key: String, defaultValue: T, evaluationContext: EvaluationContext?, flagEval: MultiProvider.FlagEval ): ProviderEvaluation { // Custom logic: evaluate providers in parallel, combine results, etc. val results = providers.map { try { it.flagEval(key, defaultValue, evaluationContext) } catch (e: Exception) { ProviderEvaluation( defaultValue, errorCode = ErrorCode.GENERAL, errorMessage = e.message ) } } // Return majority result, weighted result, etc. return results.first() } } val multiProvider = MultiProvider( providers = listOf(provider1, provider2), strategy = CustomStrategy() ) ``` -------------------------------- ### Provider Error Handling in Kotlin Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/errors.md Shows how a provider should catch exceptions during flag retrieval and return a `ProviderEvaluation` with an appropriate error code instead of throwing. This example handles `FlagNotFoundException` and general exceptions. ```kotlin override fun getBooleanEvaluation( key: String, defaultValue: Boolean, context: EvaluationContext? ): ProviderEvaluation { return try { val value = flagStore.getBoolean(key) ProviderEvaluation(value) } catch (e: FlagNotFoundException) { ProviderEvaluation( defaultValue, errorCode = ErrorCode.FLAG_NOT_FOUND, errorMessage = "Flag '$key' not found: ${e.message}" ) } catch (e: Exception) { ProviderEvaluation( defaultValue, errorCode = ErrorCode.GENERAL, errorMessage = e.message ) } } ``` -------------------------------- ### Implement Custom TimingHook Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/hook.md Example of a custom hook that measures and logs the evaluation duration of a feature flag. It records the start time before evaluation, calculates the duration after, and clears hook data in the finallyAfter stage. ```kotlin class TimingHook : Hook { override fun before(ctx: HookContext, hints: Map) { ctx.hookData["startTime"] = System.nanoTime() } override fun after(ctx: HookContext, details: FlagEvaluationDetails, hints: Map) { val duration = System.nanoTime() - (ctx.hookData["startTime"] as? Long ?: 0L) println("Flag ${ctx.flagKey} evaluated in ${duration}ns to ${details.value}") } override fun error(ctx: HookContext, error: Exception, hints: Map) { println("Error evaluating ${ctx.flagKey}: ${error.message}") } override fun finallyAfter(ctx: HookContext, details: FlagEvaluationDetails, hints: Map) { ctx.hookData.clear() } } ``` -------------------------------- ### Testing with Isolated API Instances Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/isolated-api.md Create isolated OpenFeature API instances for each test to prevent cross-test pollution. This example demonstrates setting up a mock provider and evaluating a flag within a test. ```kotlin @OptIn(ExperimentalIsolatedApi::class) class FeatureFlagsTest { private lateinit var api: OpenFeatureAPIInstance @Before fun setUp() { api = createOpenFeatureAPIInstance() } @Test fun testFlagEvaluation() = runBlocking { // Each test gets its own instance val mockProvider = MockProvider(mapOf("my-flag" to true)) api.setProviderAndWait(mockProvider) val client = api.getClient() val value = client.getBooleanValue("my-flag", false) assertEquals(true, value) } @After fun tearDown() = runBlocking { api.shutdown() } } ``` -------------------------------- ### Get Double Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/feature-provider.md Evaluates a floating-point flag. Returns a ProviderEvaluation. ```kotlin fun getDoubleEvaluation( key: String, defaultValue: Double, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### initialize Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Initializes all underlying providers concurrently. Throws an exception if any provider fails to initialize. ```APIDOC ## initialize ### Description Initializes all underlying providers concurrently. Throws if any provider fails initialization. ### Method `suspend fun initialize(initialContext: EvaluationContext?) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```kotlin // Example usage: // multiProvider.initialize(EvaluationContext.Builder()...build()) ``` ### Response #### Success Response None (initialization is a side effect) #### Response Example None ``` -------------------------------- ### Initialize and Use OpenFeature Kotlin SDK Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/getting-started.md This snippet shows how to initialize the OpenFeature SDK with a custom provider, add a logging hook, set the initial evaluation context, and evaluate feature flags. It also demonstrates tracking events and observing provider configuration changes. ```kotlin class MyApplication { suspend fun initialize() { // Set up provider OpenFeatureAPI.setProviderAndWait(MyFlagProvider()) // Add logging hook val logger = LoggerFactory.getLogger("FeatureFlags") OpenFeatureAPI.addHooks(listOf( LoggingHook(logger, logEvaluationContext = false) )) // Set initial context val context = ImmutableContext( targetingKey = "user-123", attributes = mapOf("region" to Value.String("us-east-1")) ) OpenFeatureAPI.setEvaluationContextAndWait(context) } fun evaluateFeatures() { val client = OpenFeatureAPI.getClient("MyApp") // Check features if (client.getBooleanValue("new-ui", false)) { showNewUI() } // Track events client.track("UserLoggedIn") // Listen for changes viewModelScope.launch { OpenFeatureAPI.observe() .collect { println("Flags updated: ${it.eventDetails?.flagsChanged}") refreshUI() } } } suspend fun shutdown() { OpenFeatureAPI.shutdown() } } ``` -------------------------------- ### Get String Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/feature-provider.md Evaluates a string flag. Returns a ProviderEvaluation. ```kotlin fun getStringEvaluation( key: String, defaultValue: String, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### Sharing State Between Hooks Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/hook.md Demonstrates using the `hookData` map within `HookContext` to share mutable state, such as a start time, between the `before` and `finallyAfter` hook methods for performance measurement. ```kotlin override fun before(ctx: HookContext, hints: Map) { ctx.hookData["startTime"] = System.currentTimeMillis() } override fun finallyAfter(ctx: HookContext, details: FlagEvaluationDetails, hints: Map) { val duration = System.currentTimeMillis() - (ctx.hookData["startTime"] as? Long ?: 0) logger.debug("Evaluation took ${duration}ms") } ``` -------------------------------- ### asMap Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/evaluation-context.md Gets all attributes as a map of Values. This method is inherited from the Structure interface. ```APIDOC ## asMap ### Description Gets all attributes as a map of Values. This method is inherited from the Structure interface. ### Method GET ### Endpoint N/A (SDK method) ### Returns `Map` ### Example ```kotlin val attributes = context.asMap() attributes.forEach { (key, value) -> println("$key: $value") } ``` ``` -------------------------------- ### keySet Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/evaluation-context.md Gets all attribute keys in the context. This method is inherited from the Structure interface. ```APIDOC ## keySet ### Description Gets all attribute keys in the context. This method is inherited from the Structure interface. ### Method GET ### Endpoint N/A (SDK method) ### Returns `Set` - all attribute names ``` -------------------------------- ### Observe Provider Ready Event Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/README.md Demonstrates how to observe provider state changes, specifically the ProviderReady event, using Kotlin coroutines. This allows reacting to provider initialization. ```kotlin OpenFeatureAPI.observe().collect { ... } ``` -------------------------------- ### Get Long Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/feature-provider.md Evaluates a 64-bit integer flag. Returns a ProviderEvaluation. ```kotlin fun getLongEvaluation( key: String, defaultValue: Long, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### Provider Implementation with Metadata Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/structure-and-metadata.md Shows how to implement the FeatureProvider interface and provide custom ProviderMetadata, including the provider's name. ```kotlin // In a provider implementation class MyProvider : FeatureProvider { override val metadata: ProviderMetadata = object : ProviderMetadata { override val name = "MyProvider" } } // Accessing metadata val name = OpenFeatureAPI.getProviderMetadata()?.name ``` -------------------------------- ### Get Integer Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/feature-provider.md Evaluates a 32-bit integer flag. Returns a ProviderEvaluation. ```kotlin fun getIntegerEvaluation( key: String, defaultValue: Int, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### getValue Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/evaluation-context.md Gets a single attribute value by key. This method is inherited from the Structure interface. ```APIDOC ## getValue ### Description Gets a single attribute value by key. This method is inherited from the Structure interface. ### Method GET ### Endpoint N/A (SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **key** (`String`) - Required - Attribute name ### Returns `Value?` - the attribute value, or `null` if not present ### Example ```kotlin val region = context.getValue("region")?.asString() ``` ``` -------------------------------- ### Track Basic Events Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Demonstrates how to track simple events using the OpenFeature client. This is useful for logging general occurrences. ```kotlin val client = OpenFeatureAPI.getClient() // Track a simple event client.track("FeatureEnabled") client.track("UserSignup") client.track("PurchaseCompleted") ``` -------------------------------- ### Set Evaluation Context Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/evaluation-context.md Example of creating an ImmutableContext with attributes and setting it as the global evaluation context. ```kotlin val context = ImmutableContext( targetingKey = "user-123", attributes = mapOf( "region" to Value.String("us-east-1"), "plan" to Value.String("enterprise"), "login_count" to Value.Integer(42) ) ) OpenFeatureAPI.setEvaluationContext(context) ``` -------------------------------- ### Create and Use an Isolated OpenFeature API Instance Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/isolated-api.md Demonstrates how to create an isolated OpenFeature API instance and manage its provider, context, client, hooks, and status. Use this when you need independent OpenFeature configurations. ```kotlin @OptIn(ExperimentalIsolatedApi::class) val instance = createOpenFeatureAPIInstance() // Provider management instance.setProvider(myProvider) instance.setProviderAndWait(myProvider) instance.getProvider() instance.clearProvider() // Context management instance.setEvaluationContext(context) instance.setEvaluationContextAndWait(context) instance.getEvaluationContext() // Client creation val client = instance.getClient("MyClient") // Hook management instance.addHooks(listOf(myHook)) instance.clearHooks() // Status and events instance.getStatus() instance.statusFlow instance.observe() // Lifecycle instance.shutdown() ``` -------------------------------- ### Get Evaluation Context Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/openfeature-api.md Retrieves the current evaluation context. Returns null if no context is set. ```kotlin fun getEvaluationContext(): EvaluationContext? ``` ```kotlin val context = OpenFeatureAPI.getEvaluationContext() ``` -------------------------------- ### Register LoggingHook with Default Settings Source: https://github.com/open-feature/kotlin-sdk/blob/main/README.md Demonstrates how to instantiate and register the LoggingHook globally. Configure log levels for different evaluation stages and control context logging. ```kotlin val logger = LoggerFactory.getLogger("FeatureFlags") val hook = LoggingHook( logger = logger, logEvaluationContext = false, // set true to include context attributes in logs beforeLogLevel = LogLevel.DEBUG, afterLogLevel = LogLevel.DEBUG, errorLogLevel = LogLevel.ERROR, finallyLogLevel = LogLevel.DEBUG, ) // register globally OpenFeatureAPI.addHooks(listOf(hook)) ``` -------------------------------- ### Handling InvalidContextError Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/errors.md Example demonstrating how to trigger and handle an InvalidContextError due to missing required context attributes. ```kotlin val context = ImmutableContext( targetingKey = "user-1" // missing required "region" attribute ) OpenFeatureAPI.setEvaluationContext(context) val details = client.getBooleanDetails("regional-flag", false) if (details.errorCode == ErrorCode.INVALID_CONTEXT) { println("Context missing required attributes: ${details.errorMessage}") } ``` -------------------------------- ### MultiProvider Constructor Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Instantiate a MultiProvider with a list of FeatureProviders and an optional evaluation strategy. Use this to set up multiple providers for flag evaluation. ```kotlin class MultiProvider( providers: List, private val strategy: Strategy = FirstMatchStrategy() ) : FeatureProvider ``` ```kotlin val multiProvider = MultiProvider( providers = listOf(provider1, provider2), strategy = FirstMatchStrategy() ) OpenFeatureAPI.setProvider(multiProvider) ``` -------------------------------- ### Conditional Tracking Usage Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Shows an example of conditionally tracking an event based on a feature flag evaluation. ```APIDOC ### Conditional Tracking ```kotlin val client = OpenFeatureAPI.getClient() if (client.getBooleanValue("enable-checkout-v2", false)) { client.track( "CheckoutV2Used", TrackingEventDetails( structure = ImmutableStructure( "variant" to Value.String("new_flow") ) ) ) } ``` ``` -------------------------------- ### LoggingHook Configuration and Usage Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/logging.md Demonstrates how to configure and register the LoggingHook globally, on a client, or for a specific evaluation. It also shows how to override logging behavior using hook hints. ```APIDOC ## LoggingHook A built-in hook that logs structured information at each stage of the flag evaluation lifecycle. ### Class Signature ```kotlin class LoggingHook( private val logger: Logger = NoOpLogger(), private val logEvaluationContext: Boolean = false, private val beforeLogLevel: LogLevel = LogLevel.DEBUG, private val afterLogLevel: LogLevel = LogLevel.DEBUG, private val errorLogLevel: LogLevel = LogLevel.ERROR, private val finallyLogLevel: LogLevel = LogLevel.DEBUG, private val logTargetingKey: Boolean = true, private val includeAttributes: Set? = null, private val excludeAttributes: Set = DEFAULT_SENSITIVE_KEYS ) ``` ### Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `logger` | `Logger` | `NoOpLogger()` | Logger to emit records to | | `logEvaluationContext` | `Boolean` | `false` | Include evaluation context in logs | | `beforeLogLevel` | `LogLevel` | `DEBUG` | Log level for before stage | | `afterLogLevel` | `LogLevel` | `DEBUG` | Log level for after stage | | `errorLogLevel` | `LogLevel` | `ERROR` | Log level for error stage | | `finallyLogLevel` | `LogLevel` | `DEBUG` | Log level for finally stage | | `logTargetingKey` | `Boolean` | `true` | Include targeting key in context logs | | `includeAttributes` | `Set?` | `null` | Allowlist of attributes to log (takes precedence over exclude) | | `excludeAttributes` | `Set` | `DEFAULT_SENSITIVE_KEYS` | Denylist of attributes to omit | ### Register LoggingHook ```kotlin // Globally val logger = LoggerFactory.getLogger("FeatureFlags") val hook = LoggingHook( logger = logger, logEvaluationContext = false, beforeLogLevel = LogLevel.DEBUG ) OpenFeatureAPI.addHooks(listOf(hook)) // On a client val client = OpenFeatureAPI.getClient() client.addHooks(listOf(hook)) // On a specific evaluation val details = client.getBooleanDetails( "flag", false, FlagEvaluationOptions( hooks = listOf(hook), hookHints = mapOf(LoggingHook.HINT_LOG_EVALUATION_CONTEXT to true) ) ) ``` ### PII Filtering When `logEvaluationContext = true`, context attributes are logged. By default, attributes matching common PII field names are excluded. **Default Sensitive Keys:** `email`, `phone`, `phoneNumber`, `ssn`, `socialSecurityNumber`, `creditCard`, `creditCardNumber`, `password`, `address`, `streetAddress`, `zipCode`, `postalCode`, `ipAddress`, `firstName`, `lastName`, `fullName`, `dateOfBirth` #### Examples **Allow only specific safe attributes:** ```kotlin val hook = LoggingHook( logger = logger, logEvaluationContext = true, logTargetingKey = false, // Don't log the targeting key includeAttributes = setOf("region", "plan", "tier") // Allowlist (takes precedence) ) ``` **Extend the default denylist:** ```kotlin val hook = LoggingHook( logger = logger, logEvaluationContext = true, excludeAttributes = LoggingHook.DEFAULT_SENSITIVE_KEYS + setOf("internalId", "accountNumber") ) ``` ### Lifecycle Logging `LoggingHook` logs at four stages: | Stage | Log Level (default) | Attributes | |-------|---------------------|------------| | `before` | DEBUG | `flag`, `type`, `defaultValue`, `provider`, `client` (if set), `context.*` (if enabled) | | `after` | DEBUG | `flag`, `value`, `variant` (if set), `reason` (if set), `provider`, `context.*` (if enabled) | | `error` | ERROR | `flag`, `type`, `defaultValue`, `provider`, `error` (if set), `context.*` (if enabled) | | `finallyAfter` | DEBUG | `flag`, `errorCode` (if set), `errorMessage` (if set) | ### Per-Evaluation Override Enable context logging for a specific evaluation via hook hints: ```kotlin client.getBooleanValue( "my-flag", false, FlagEvaluationOptions( hooks = listOf(loggingHook), hookHints = mapOf(LoggingHook.HINT_LOG_EVALUATION_CONTEXT to true) ) ) ``` ``` -------------------------------- ### Get Client Metadata Name Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/client.md Retrieve the name of the client from its metadata. This is useful for identification in logs and events. ```kotlin val client = OpenFeatureAPI.getClient("MyApp") println(client.metadata.name) // prints "MyApp" ``` -------------------------------- ### Get Provider Metadata Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/openfeature-api.md Retrieves metadata for the currently registered provider. Returns null if no provider is set. ```kotlin fun getProviderMetadata(): ProviderMetadata? ``` ```kotlin val metadata = OpenFeatureAPI.getProviderMetadata() println(metadata?.name) ``` -------------------------------- ### Demonstrate Isolated Instance State Management Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/isolated-api.md Illustrates how each isolated OpenFeature API instance maintains its own provider, distinct from the global instance and other isolated instances. This is useful for managing separate configurations in complex applications. ```kotlin @OptIn(ExperimentalIsolatedApi::class) fun main() { // Global singleton val globalAPI = OpenFeatureAPI globalAPI.setProvider(MyProvider("Global")) // Isolated instance 1 val instance1 = createOpenFeatureAPIInstance() instance1.setProvider(MyProvider("Instance1")) // Isolated instance 2 val instance2 = createOpenFeatureAPIInstance() instance2.setProvider(MyProvider("Instance2")) // Each has its own provider globalAPI.getProvider().metadata.name // "Global" instance1.getProvider().metadata.name // "Instance1" instance2.getProvider().metadata.name // "Instance2" } ``` -------------------------------- ### Get All Attribute Keys from EvaluationContext Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/evaluation-context.md Retrieves a set of all attribute keys present in the context. This is part of the Structure interface. ```kotlin fun keySet(): Set ``` -------------------------------- ### Using the Logger Interface Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/logging.md Demonstrates how to obtain a logger instance and log messages with associated attributes and potential exceptions. Messages and attributes are lazily evaluated. ```kotlin val logger = LoggerFactory.getLogger("FeatureFlags") logger.debug( { "Evaluating flag: myFlag" }, { mapOf("userId" to "user-123", "region" to "us-east-1") } ) logger.error( { "Flag evaluation failed" }, { mapOf("flag" to "my-flag", "error" to "Type mismatch") }, throwable = exception ) ``` -------------------------------- ### Multi-Provider Usage with FirstMatchStrategy Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Demonstrates how to create and configure a Multi-Provider with the FirstMatchStrategy. This strategy evaluates providers in the order they are listed, using the first one that returns a value. ```kotlin // Create multiple providers val provider1 = MyProvider("Primary") val provider2 = MyProvider("Fallback") // Create multi-provider with FirstMatchStrategy val multiProvider = MultiProvider( providers = listOf(provider1, provider2), strategy = FirstMatchStrategy() ) // Set the multi-provider coroutineScope.launch(Dispatchers.Default) { OpenFeatureAPI.setProviderAndWait(multiProvider) val client = OpenFeatureAPI.getClient() // Evaluations are delegated to the strategy // Strategy evaluates provider1, then provider2 if needed val value = client.getBooleanValue("my-flag", false) } ``` -------------------------------- ### Get Double Flag Value Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/client.md Evaluates a double-precision floating-point flag. Use the overload with options for custom evaluation context. ```kotlin fun getDoubleValue(key: String, defaultValue: Double): Double ``` ```kotlin fun getDoubleValue( key: String, defaultValue: Double, options: FlagEvaluationOptions ): Double ``` -------------------------------- ### Initialize Multi-Provider Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Initializes all underlying providers concurrently. Throws an error if any provider fails initialization. ```kotlin override suspend fun initialize(initialContext: EvaluationContext?) ``` -------------------------------- ### Get Long Flag Value Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/client.md Evaluates a 64-bit integer flag. Use the overload with options for custom evaluation context. ```kotlin fun getLongValue(key: String, defaultValue: Long): Long ``` ```kotlin fun getLongValue( key: String, defaultValue: Long, options: FlagEvaluationOptions ): Long ``` -------------------------------- ### Get Targeting Key from EvaluationContext Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/evaluation-context.md Retrieves the primary identifier used for flag evaluation. Returns an empty string if not set. ```kotlin fun getTargetingKey(): String ``` ```kotlin val context = ImmutableContext(targetingKey = "user-123") println(context.getTargetingKey()) // prints "user-123" ``` -------------------------------- ### Get Object Flag Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Retrieves an object flag evaluation. Passes the flag key, default value, and context to the strategy. ```kotlin override fun getObjectEvaluation( key: String, defaultValue: Value, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### Configure and Add LoggingHook Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/hook.md Demonstrates how to instantiate and configure the built-in LoggingHook with custom logger and log levels. The hook is then added to the OpenFeature API. ```kotlin val hook = LoggingHook( logger = LoggerFactory.getLogger("FeatureFlags"), logEvaluationContext = true, beforeLogLevel = LogLevel.DEBUG, afterLogLevel = LogLevel.DEBUG, errorLogLevel = LogLevel.ERROR, finallyLogLevel = LogLevel.DEBUG ) OpenFeatureAPI.addHooks(listOf(hook)) ``` -------------------------------- ### Get Double Flag Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Retrieves a double flag evaluation. Passes the flag key, default value, and context to the strategy. ```kotlin override fun getDoubleEvaluation( key: String, defaultValue: Double, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### Get Long Flag Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Retrieves a long flag evaluation. Passes the flag key, default value, and context to the strategy. ```kotlin override fun getLongEvaluation( key: String, defaultValue: Long, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### Run All Verifications Source: https://github.com/open-feature/kotlin-sdk/blob/main/CONTRIBUTING.md Performs all project verifications, including tests and linting. This command provides a comprehensive check of the project's health. ```bash ./gradlew check ``` -------------------------------- ### Get Integer Flag Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Retrieves an integer flag evaluation. Passes the flag key, default value, and context to the strategy. ```kotlin override fun getIntegerEvaluation( key: String, defaultValue: Int, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### ImmutableContext Constructors Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/evaluation-context.md Demonstrates the different ways to construct an ImmutableContext, including empty, with a targeting key, and with both a targeting key and attributes. ```kotlin ImmutableContext() ImmutableContext(targetingKey = "user-123") ImmutableContext( targetingKey = "user-123", attributes = mapOf( "region" to Value.String("us-east-1"), "tier" to Value.String("premium") ) ) ``` -------------------------------- ### Get String Flag Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Retrieves a string flag evaluation. Passes the flag key, default value, and context to the strategy. ```kotlin override fun getStringEvaluation( key: String, defaultValue: String, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### Get Boolean Flag Evaluation Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Retrieves a boolean flag evaluation. Passes the flag key, default value, and context to the strategy. ```kotlin override fun getBooleanEvaluation( key: String, defaultValue: Boolean, context: EvaluationContext? ): ProviderEvaluation ``` -------------------------------- ### Create TrackingEventDetails Instances Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/tracking.md Demonstrates various ways to create TrackingEventDetails objects, including with only a value, with structured data, with only structure, and with default values. ```kotlin // Simple: value only val details1 = TrackingEventDetails(value = 49.99) // With structured data val details2 = TrackingEventDetails( value = 99.99, structure = ImmutableStructure( "items" to Value.Integer(3), "tax" to Value.Double(8.50), "shipping" to Value.String("expedited") ) ) // Structure only val details3 = TrackingEventDetails( structure = ImmutableStructure( "eventType" to Value.String("page_view"), "url" to Value.String("/products") ) ) // Empty (default) val details4 = TrackingEventDetails() ``` -------------------------------- ### Get Provider Status Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/openfeature-api.md Retrieves the current status of the provider. The status indicates whether the provider is ready, encountering errors, or reconciling. ```kotlin fun getStatus(): OpenFeatureStatus ``` ```kotlin val status = OpenFeatureAPI.getStatus() if (status == OpenFeatureStatus.Ready) { val client = OpenFeatureAPI.getClient() } ``` -------------------------------- ### Get Current Feature Provider - OpenFeatureAPI Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/openfeature-api.md Retrieves the currently active feature provider. If no provider has been explicitly set, it returns a `NoOpProvider`. ```kotlin val provider = OpenFeatureAPI.getProvider() ``` -------------------------------- ### MultiProvider Constructor Source: https://github.com/open-feature/kotlin-sdk/blob/main/_autodocs/api-reference/multi-provider.md Initializes a new instance of the MultiProvider class. This provider delegates flag evaluations to multiple underlying providers using a specified strategy. ```APIDOC ## MultiProvider Constructor ### Description Initializes a new instance of the MultiProvider class. This provider delegates flag evaluations to multiple underlying providers using a specified strategy. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **providers** (`List`) - Required - The list of underlying feature providers to manage. * **strategy** (`Strategy`) - Optional - The strategy used for combining results from the underlying providers. Defaults to `FirstMatchStrategy()`. ```