Kotlin SDK reference
Client options, methods, caching and shutdown of the Voidhash Android SDK.
Everything VoidhashOptions accepts and the client exposes. To install the SDK and create the
client, see Kotlin SDK.
Client options
| Option | Default | Description |
|---|---|---|
baseUrl | https://api.voidhash.com | API origin, for self-hosting. |
ingestUrl | baseUrl | Analytics origin. |
debug | false | Logs SDK warnings to logcat under the tag Voidhash and marks requests as debug traffic. |
distinctId | Generated | Starts with this user ID and links the device's anonymous ID to it. Usually call identify instead. |
enabled | true | false makes the client inert. See Disabled clients. |
readOnly | false | Observer mode: records purchases, never acknowledges or consumes them, and refuses purchase. |
dev | false | Buys from a simulated store in debug builds. See Development mode. |
paywallRenderer | null | Draws flows; pass VoidhashUiPaywallRenderer(). See Paywalls. |
flowCapabilities | setOf(FlowCapability.LINKS) | What flows may do. See Grant capabilities. |
preloadPlacements | emptyList() | Locations whose flows are cached on first launch. Needs a renderer. |
featureFlags | FeatureFlagOptions() | maxWaitMs (2,000 ms) and defaults for flag reads. See Defaults and updates. |
analyticsConsent | AnalyticsConsent.GRANTED | Consent until your app calls setAnalyticsConsent. See Analytics consent. |
automaticLifecycleEvents | true | Records $app_* and $sign_out events. See Automatic events. |
screenTracking | ScreenTrackingOptions() | Automatic $screen events. See Track screens. |
installAttribution | true | Credits installs to ad campaigns. See Credit installs. |
metaAppId | null | Also asks Meta's apps about the install. See Meta app-install ads. |
onDiagnostic | null | Receives problems the SDK handled itself. See Diagnostics. |
runInSecondaryProcess | false | Runs the SDK outside the main process. |
Disabled clients
With enabled = false, the client makes no requests, opens no billing connection, runs no timers,
and leaves its stored data untouched. Methods return empty values: getProducts() and
getFeatureFlags() an empty list, getCurrentPerson() and resolvePaywall() null, and flush()
and shutdown() nothing sent. purchase throws CONFIGURATION_MISSING, and presentFlow returns
FLOW_DISABLED.
Methods
Methods that can wait are suspending functions. They never read storage or post work on the calling thread.
| Method | Returns | Guide |
|---|---|---|
initialize() | — | Create the client |
getProducts() | List<VoidhashProduct> | Load products |
purchase(activity, product, offerId) | VoidhashTransaction | Start a purchase |
restorePurchases() | — | Restore purchases |
reportTransaction(purchase, isRestore) | — | Observer mode |
syncPurchases() | — | Recover with a scan |
setReadOnly(readOnly), isReadOnly | — | Observer mode |
getCurrentPerson(forceFetch), getCurrentPersonState() | VoidhashPerson? | Check access |
identify(externalUserId, email, name), identifyWithStatus(...) | VoidhashPerson?, PersonWriteResult | Identify users |
setPersonAttributes(map), setPersonAttributesWithStatus(map) | —, PersonWriteResult | Set person attributes |
signOut(), reset() | — | Sign out |
getDistinctId() | String | Read the distinct ID |
presentFlow(activity, placement), dismissFlow() | FlowResult | Paywalls |
resolvePaywall(location), resolvePaywallState(location) | ResolvedPaywall? | Caching and offline |
getFeatureFlags(keys), getFeatureFlagsState(keys) | List<FeatureFlag> | Feature flags |
isFeatureEnabled(key), featureFlags | Boolean, StateFlow | Defaults and updates |
capture(name, properties), screen(name, properties) | — | Capture analytics |
trackPushOpened(extras) | — | Report opened notifications |
setAnalyticsConsent(consent), analyticsConsent | — | Analytics consent |
setAdDataSharing(granted) | PersonWriteResult | Share purchases with ad platforms |
sessionId | String | Sessions and delivery |
flush() | FlushStatus | Sessions and delivery |
shutdown() | FlushStatus | Shutdown |
fetchSchema, fetchPerson, identifyPerson, setPersonTraits, evaluateFeatureFlags,
syncStoreTransaction, syncStoreTransactionWithStatus, injectInternalSchema and
recordDevelopmentPurchase exist for hosts that embed the client as their transport. They take
the distinct ID on every call and skip the cache and identity the app-facing methods manage. Don't
call them from an app; use identify, setPersonAttributes, getFeatureFlags and
reportTransaction instead.
Caching
Reads answer from the device cache and refresh in the background. A stale read waits at most
500 ms for a refresh. Cached values are never discarded for age; the …State() variants return
them with isStale and isExpired.
| Data | Fresh for | Kept for | Wait with nothing cached |
|---|---|---|---|
| Person | 5 minutes | 2 days | 10 seconds |
| Feature flags | 5 minutes | Until replaced | maxWaitMs, 2 seconds |
| Paywall per location | 1 hour | 7 days | 10 seconds |
Events, purchases and attribute writes are stored on disk and retried until delivered. After 5 failures in a row the SDK pauses requests and serves the cache until a retry succeeds.
Shutdown
Call shutdown() only when the process is going away for good, not when the app goes to the
background:
voidhash.shutdown()It flushes analytics for at most 2 seconds, ends the Google Play connection and stops the SDK's
timers. Unsent events stay on the device for the next client. Afterwards Voidhash.shared is
null, and the identity, attribute and store methods throw CLIENT_SHUT_DOWN.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.