VoidhashDocs
DevelopersHelp centerGuidesAPI reference
Dashboard
Get started
Introduction
Quickstart
How Voidhash works
Glossary
Versions and releases
Concepts
Teams, projects and environments
API keys
Products and perks
Offers
Subscription lifecycle
People and identity
Groups
Events
Features
Paywalls in your app
Feature flags and A/B tests
Paywall components
Push notifications
Ad attribution in your app
Client SDKs
React Native
Swift
Kotlin
Web
Your backend
Node.js
PHP
Go
Rust
Other languages
Payment sources
Forward store notifications
Developer tools
CLI
MCP server
Query analytics with VoidQL
Kotlin SDK
Kotlin quickstart
Display a paywall
Make and restore purchases
Check access
Identify users
Evaluate feature flags
Capture analytics
Groups
Track screens
Development mode
Kotlin SDK reference
Errors
Diagnostic codes
Troubleshooting

Evaluate feature flags

Read feature flags and variants for the current person, with safe defaults.

Feature flags turn features on or off, or pick a variant, for each person without a new build. Voidhash evaluates flags for the current person; you create them and set rollouts in Studio. See Feature flags.

Early access

Feature flags are in early access. Ask us on Discord, or email support@voidhash.com on a paid plan, to turn them on for your team.

A build that uses a test key gets each flag's test configuration, which is the same as production's until you change it in Studio. See Environments.

Evaluate flags

Pass the keys you need, or an empty list to evaluate every flag:

val flags = voidhash.getFeatureFlags(listOf("new_onboarding", "pricing_test"))

val newOnboarding = flags.firstOrNull { it.key == "new_onboarding" }?.enabled == true
val pricingVariant = flags.firstOrNull { it.key == "pricing_test" }?.variantKey

Each FeatureFlag has a key, enabled, the selected variantKey, and the variant's payload. A disabled flag has no variant. Payloads are untyped JSON: a JSONObject, JSONArray, String, Number, Boolean, or null. Validate one before you use it:

import org.json.JSONObject

val copy = flags.firstOrNull { it.key == "onboarding_copy" }?.payload as? JSONObject
val headline = copy?.optString("headline")?.takeIf { it.isNotEmpty() } ?: "Welcome"

Results are cached per person, fresh for 5 minutes and served after that while a refresh runs, so they work offline. getFeatureFlagsState adds isStale and isExpired.

Defaults and updates

With nothing cached, a flag read waits at most 2 seconds, then answers without an evaluation while the request continues. Set a default for each flag that needs a value before then, read flags synchronously with isFeatureEnabled, and collect featureFlags to update your UI when an evaluation arrives:

import com.voidhash.sdk.FeatureFlagOptions
import com.voidhash.sdk.Voidhash
import com.voidhash.sdk.VoidhashOptions

val voidhash = Voidhash.configure(
    context = this,
    publishableKey = "vh_pk_...",
    options = VoidhashOptions(
        featureFlags = FeatureFlagOptions(
            maxWaitMs = 2_000,
            defaults = mapOf("new_onboarding" to false),
        ),
    ),
)

lifecycleScope.launch {
    voidhash.featureFlags.collect {
        showNewOnboarding(voidhash.isFeatureEnabled("new_onboarding"))
    }
}

isFeatureEnabled reads the latest evaluation from memory and never suspends. A flag without an evaluated value reads as its default, or as disabled. getFeatureFlags includes the default of each requested key that has no evaluated value, as a flag without a variant. featureFlags is a StateFlow<List<FeatureFlag>>.

Choose defaults that are safe while flags load or stay unavailable. Don't gate paid access on a flag; use perks.

Identity changes

When an anonymous person signs in, their flags keep answering until the identified person's evaluation arrives, so an offline sign-in doesn't turn features off. Identifying can move a person into a different rollout bucket. Signing out or switching accounts clears the cached flags, so one person never sees another's assignment.

Next steps

  • Feature flags in Studio: rollouts, variants and targeting.
  • A/B tests on paywalls, which need no flag code.
  • Identify users.

Something wrong or missing on this page? Tell us by email or on Discord.

PreviousIdentify usersNextCapture analytics

On this page

Evaluate flagsDefaults and updatesIdentity changesNext steps