Frequency Cap Check
checkFrequencyCap() reports whether the user has already hit their frequency cap for an ad unit — a read-only backend check that records no impression. Use it to detect ahead of time that an ad would not fill, and skip the ad-gated surface entirely, instead of sending the user into a flow that ends in no-fill.
// From a coroutine
val capped = SimulaAds.checkFrequencyCap("SIM-RWD-XXXXXXXX")
if (!capped) {
selectorOpen = true // still eligible — open the selector
}
// Callback overload for Java / non-coroutine code (result delivered on the main thread)
SimulaAds.checkFrequencyCap("SIM-RWD-XXXXXXXX") { capped ->
if (!capped) selectorOpen = true
}Parameters
| Parameter | Type | Description |
|---|---|---|
adUnitId | String | required — the ad unit to check |
primaryUserID | String? | Optional. Falls back to the SDK's current user ID, then to the backend's IP/device/session signals |
Return Value
Returns true when the cap has been reached — the next ad request would not fill, so skip the surface.
Returns false when the user is still eligible, before initialize(), or on any network failure: the check fails open, so a transport hiccup can never hide an ad surface that would otherwise have served.
Eligibility, not a fill guarantee
A pass on the cap check means the user is eligible to be served — it doesn't reserve an ad, and fill is still decided by available demand at request time. In practice, frequency capping is the leading cause of no-fill on Simula, so an uncapped user is a strong predictor of fill.
Example: Gating the CharacterSelector
Rewarded ads are frequency-capped per user. Check the cap before opening the CharacterSelector so a user who can't be served another ad today never sees a dead-end flow:
val scope = rememberCoroutineScope()
Button(onClick = {
scope.launch {
if (!SimulaAds.checkFrequencyCap("SIM-RWD-XXXXXXXX")) selectorOpen = true
}
}) {
Text("Earn free credits")
}Because the check fails open, it can never hide the button from an eligible user.
