capacitor-levelplay-ads
Unity LevelPlay mediation for Capacitor.
This plugin integrates the Unity LevelPlay mediation SDK (formerly ironSource) into Capacitor.
Banner, interstitial and rewarded ads are supported.
Ads can be served across every mediated demand source from a single, modular API with zero mandatory native configuration.
SDK Versions
| Component | Platform | Version |
|---|---|---|
| LevelPlay Mediation SDK | Android | com.unity3d.ads-mediation:mediation-sdk:9.4.0 |
| IronSource SDK | iOS | IronSourceSDK (CocoaPods) |
Key Features
- Mediation-first: One LevelPlay app key fans out to every network you enable — AdMob, AppLovin, Unity Ads, Vungle, Meta, Mintegral, Pangle.
- IAB TCF v2.3 consent (default): Bundles the Usercentrics CMP
(Google-certified Gold tier partner) for GDPR-compliant consent — collects
a TCF string and writes the standard
IABTCF_*keys every mediation adapter reads. InMobi Choice CMP and a built-in, TCF v2.3-compatible custom modal are also available. - CCPA & COPPA: First-class
setCCPAConsent()andsetChildDirected(). - App Tracking Transparency:
requestTrackingAuthorization()prompts ATT on iOS and is a safe no-op on Android. - Impression-level revenue (ILRD): Subscribe to
onAdRevenuefor per-impression revenue across all networks. - Android 15 edge-to-edge ready: Automated lifecycle workaround so fullscreen ad close buttons are never hidden behind the system bars.
- Anti-spam rate limiting: Built-in per-ad load throttling protects your account from invalid-traffic penalties.
- Opt-in network injection: Mediation adapter pods/gradle deps are injected
at sync time from a single
levelplay.networkskey — no manual XML edits.
Installation
npm install capacitor-levelplay-ads
npx cap sync
Configuration (Mediation Networks)
Mediation network adapters are opt-in. The plugin bundles only the core LevelPlay SDK; each demand source you want is wired in by a Capacitor CLI hook.
- Add a
levelplayblock to your app's rootpackage.json:
{
"name": "your-app-name",
"levelplay": {
"networks": ["admob", "applovin", "unityads"],
"userTrackingDescription": "This identifier is used to deliver personalized ads to you.",
"consentProvider": "usercentrics",
"usercentrics": {
"settingsId": "YOUR_SETTINGS_ID"
}
}
}
Supported network keys: admob, applovin, unityads, vungle, meta,
mintegral, pangle, inmobi, chartboost, fyber, moloco, bigo,
hyprmx, mobilefuse, aps, bidmachine, smaato, verve, ogury,
superawesome, yandex, mytarget, line, pubmatic, tencent, yso, voodoo.
Consent provider
The consentProvider key picks how the plugin collects GDPR consent:
| Value | What it does | When to use |
|---|---|---|
usercentrics (default) |
Bundles the Usercentrics CMP (Google-certified Gold tier partner). IAB TCF v2.3 compliant. Auto-shows the consent banner on first launch and writes the standard IABTCF_* keys to SharedPreferences (Android) / NSUserDefaults (iOS). |
Apps shipped in the EU/EEA. Required for GDPR audit compliance. |
inmobi |
Bundles InMobi Choice CMP. IAB TCF v2.2 compliant. Same TCF key behavior as Usercentrics. | Alternative CMP if you already have an InMobi Choice account. |
custom |
Built-in consent modal you control. Pass a services config to requestConsentInfo() to render the polished two-layer modal (summary + Categories/Services tabs) and write TCF v2.3-compatible IABTCF_* keys + a TC string. Without services, falls back to a basic alert that writes a permissive gdprApplies=0 stub. Self-built, so not an IAB-certified CMP (CMP ID defaults to 0). |
Apps not requiring a certified CMP — e.g. Unity Ads + a few networks — or where you want full control of the consent UI. |
Usercentrics (default)
Set levelplay.usercentrics.settingsId to the Settings ID from your
Usercentrics admin dashboard. Optionally
set levelplay.usercentrics.rulesetId for geolocation-based rulesets.
{
"levelplay": {
"consentProvider": "usercentrics",
"usercentrics": {
"settingsId": "YOUR_SETTINGS_ID"
}
}
}
InMobi Choice
Set levelplay.inmobi.pCode to the pCode from your
InMobi Choice workspace (strip the leading
p-). Optionally set levelplay.inmobi.packageId to override the property
package id; defaults to the app's applicationId/bundle id.
{
"levelplay": {
"consentProvider": "inmobi",
"inmobi": {
"pCode": "YOUR_PCODE_HERE"
}
}
}
Custom modal (TCF v2.3-compatible)
Select it with "consentProvider": "custom", then pass a services config to
requestConsentInfo(). The plugin renders a two-layer modal — a summary screen
(one row per category) and a Manage screen with Categories / Services
tabs — directly in the WebView (identical on iOS and Android), then writes
TCF v2.3-compatible IABTCF_* keys natively and forwards per-network GDPR
consent to LevelPlay.
import services from './services.json'; // your copy of examples/services.example.json
await LevelPlayAds.requestConsentInfo({
services, // universal config: categories + services
appName: 'MyApp',
accentColor: '#143cc4',
logoUrl: 'https://example.com/logo.png',
privacyPolicyUrl: 'https://example.com/privacy',
legalNoticeUrl: 'https://example.com/legal',
});
// Re-open the Manage screen later from a settings button:
await LevelPlayAds.showPrivacyOptions({ services, appName: 'MyApp' });
Data model — two parts:
servicesJSON (universal, language-neutral): categories and services with stable IDs, company names/addresses, policy URLs, ISO country codes, retention IDs, TCF vendor mappings, and an optionalnetworkkey per service that maps the user's toggle to a LevelPlay mediation network (unityads,meta,pangle, …) for per-network consent. A ready-to-copy example built from a real CMP is atexamples/services.example.json— 10 services across Marketing / Functional / Essential.- Translations (language-dependent copy): all labels are resolved by ID from
a locale bundle. English ships built-in. Add languages or override copy via
translations(keyed by locale code); country names resolve automatically via the platform'sIntl.DisplayNames.
await LevelPlayAds.requestConsentInfo({
services,
locale: 'de',
translations: {
de: {
ui: { 'btn.consent': 'Zustimmen', 'btn.manage': 'Optionen verwalten' },
categories: { marketing: { name: 'Marketing', description: '…' } },
purposes: { advertisement: 'Werbung' },
serviceDescriptions: { 'unity-ads': 'Eine umfassende Monetarisierungsplattform.' },
},
},
});
Not an IAB-certified CMP. Output is spec-shaped and adapter-readable, but the plugin isn't registered with IAB Europe (
IABTCF_CmpSdkIDis0) and never fetches the GVL fromconsensu.org. For audited EU/EEA compliance use theusercentricsorinmobiproviders.
The CMP is initialized lazily when your JS code calls
LevelPlayAds.requestConsentInfo(). The call resolves once the user has
interacted with the CMP UI; subsequent calls return the stored decision
without re-showing the dialog.
- Register the hook in the
scriptssection of yourpackage.json:
{
"scripts": {
"capacitor:sync:after": "node node_modules/capacitor-levelplay-ads/scripts/levelplay-manifest.js"
}
}
On every npx cap sync the hook injects, for each selected network:
- Android adapter
implementationlines intoandroid/app/build.gradle - iOS adapter pods into
ios/App/Podfile NSUserTrackingUsageDescription+ per-networkSKAdNetworkIDs intoInfo.plist
Manual alternative
If you'd rather not run the hook, do the equivalent edits yourself:
Android — add the adapters you need to android/app/build.gradle:
dependencies {
implementation 'com.unity3d.ads-mediation:admob-adapter:5.9.0'
implementation 'com.unity3d.ads-mediation:applovin-adapter:5.5.0'
implementation 'com.unity3d.ads-mediation:unityads-adapter:5.8.0'
// …one per network from the supported list above
}
Some networks (Mintegral, Pangle, Chartboost, BidMachine, Smaato, Verve, Ogury,
SuperAwesome, PubMatic, YSO, Voodoo) require extra Maven repositories. The
manifest script injects them automatically; if wiring manually, check the
androidRepos field in scripts/levelplay-manifest.js for the URLs.
iOS — add the matching pods to ios/App/Podfile inside the App target:
pod 'IronSourceAdMobAdapter'
pod 'IronSourceAppLovinAdapter'
pod 'IronSourceUnityAdsAdapter'
iOS — ios/App/App/Info.plist (required for ATT prompt + attribution):
<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>
<key>SKAdNetworkItems</key>
<array>
<dict><key>SKAdNetworkIdentifier</key><string>su67r6k2v3.skadnetwork</string></dict> <!-- IronSource -->
<dict><key>SKAdNetworkIdentifier</key><string>cstr6suwn9.skadnetwork</string></dict> <!-- AdMob -->
<dict><key>SKAdNetworkIdentifier</key><string>ludvb6z3bs.skadnetwork</string></dict> <!-- AppLovin -->
<dict><key>SKAdNetworkIdentifier</key><string>4dzt52r2t5.skadnetwork</string></dict> <!-- UnityAds -->
<!-- Vungle: gta9lk7p23.skadnetwork -->
<!-- Meta: v9wttpbfk9.skadnetwork, n38lu8286q.skadnetwork -->
<!-- Mintegral: kbd757ywx3.skadnetwork -->
<!-- Pangle: 238da6jt44.skadnetwork, 22mmun2rn5.skadnetwork -->
</array>
Without NSUserTrackingUsageDescription Apple will reject the build (the
IronSource SDK calls ATTrackingManager). Without the matching SKAdNetwork
IDs install attribution silently fails and mediation revenue reports go dark.
Adapter versions are pinned in scripts/levelplay-manifest.js — check that
file for the current set if you're maintaining the edits by hand.
Quick Setup
A minimal flow: initialize the SDK, ask for consent, then load and show an interstitial.
import { LevelPlayAds } from 'capacitor-levelplay-ads';
async function bootstrapAds() {
// 1. Initialize the LevelPlay SDK with your app key.
await LevelPlayAds.initialize({
appKey: 'YOUR_LEVELPLAY_APP_KEY',
isTesting: true, // remove or set to false in production
});
// 2. Request a GDPR / consent decision. The plugin shows the Usercentrics
// (or configured CMP) banner on first run and reuses the stored decision.
const consent = await LevelPlayAds.requestConsentInfo({
privacyPolicyUrl: 'https://example.com/privacy',
networks: ['admob', 'meta'], // optional — must match your levelplay.networks
});
if (!consent.canRequestAds) {
console.log('User declined personalised ads.');
}
// 3. (iOS only) Ask for App Tracking Transparency. Resolves with
// "NOT_APPLICABLE" on Android, so the same call works cross-platform.
await LevelPlayAds.requestTrackingAuthorization();
// 4. Pre-load an interstitial. Use AdEvent constants instead of raw
// event-name strings so typos surface at compile time.
LevelPlayAds.addListener(AdEvent.InterstitialLoaded, () => {
console.log('Interstitial ready.');
});
LevelPlayAds.addListener(AdEvent.InterstitialClosed, () => {
console.log('Interstitial closed — next ad is auto-reloading.');
});
// `autoShow: true` chains show() automatically once the ad loads —
// the same promise resolves on display or rejects on display failure.
await LevelPlayAds.loadInterstitial({
adUnitId: 'YOUR_INTERSTITIAL_AD_UNIT',
autoShow: false,
});
}
async function showInterstitial() {
const { isReady } = await LevelPlayAds.isInterstitialReady();
if (isReady) {
await LevelPlayAds.showInterstitial();
}
}
// Optional: a sticky bottom-right banner that flips to bottom-left on rotation.
async function bannerWithRotation() {
await LevelPlayAds.createBanner({
adUnitId: 'YOUR_BANNER_AD_UNIT',
adSize: 'ADAPTIVE',
position: 'BOTTOM_RIGHT',
isOverlap: false, // Android only — pushes the WebView up by banner height
});
LevelPlayAds.addListener(AdEvent.OrientationChanged, ({ orientation }) => {
LevelPlayAds.updateBannerStyle({
position: orientation === 'LANDSCAPE' ? 'BOTTOM_LEFT' : 'BOTTOM_RIGHT',
});
});
}
Import
AdEventalongsideLevelPlayAds:import { LevelPlayAds, AdEvent } from 'capacitor-levelplay-ads';Position and size strings are case- and separator-insensitive at the JS layer —
'top-left','topLeft'and'TOP_LEFT'all canonicalize toTOP_LEFTbefore reaching the native side.
initializeandrequestConsentInfomust complete before anyloadInterstitial/loadRewarded/createBannercall — ad loads are rejected otherwise.
Server-to-Server (S2S) Reward Verification
LevelPlay supports server-to-server callbacks for rewarded ads — your backend
receives an HTTP request from LevelPlay's servers whenever a user earns a reward.
Use setDynamicUserId() to attach a verifiable token so your server can match
the callback to the right user/session.
import { LevelPlayAds, AdEvent } from 'capacitor-levelplay-ads';
// Set a user-specific token before showing the rewarded ad.
// This value is included in the S2S callback as the `dynamicUserId` parameter.
await LevelPlayAds.setDynamicUserId({ userId: 'user_12345' });
// You can encode multiple fields if needed:
const payload = btoa(JSON.stringify({ uid: 'user_12345', txn: 'abc-def' }));
await LevelPlayAds.setDynamicUserId({ userId: payload });
// Load and show the rewarded ad — the active userId at show-time is sent in the callback.
await LevelPlayAds.loadRewarded({ adUnitId: 'YOUR_REWARDED_AD_UNIT' });
const { isReady } = await LevelPlayAds.isRewardedReady();
if (isReady) {
await LevelPlayAds.showRewarded();
}
// Listen for the client-side reward event as a fallback.
LevelPlayAds.addListener(AdEvent.RewardedAdRewarded, (reward) => {
console.log('Reward earned:', reward);
});
S2S callback flow
- User watches a rewarded ad.
- LevelPlay fires an HTTP GET to your configured callback URL with query
parameters including
dynamicUserId. - Your server decodes the token and credits the user.
Configure your S2S callback URL in the LevelPlay dashboard under Ad Units → Rewarded → Server-to-Server Callbacks.
setDynamicUserId()can be called multiple times — the value active whenshowRewarded()executes is the one LevelPlay includes in the callback. Call it before each ad show if the token changes per session or transaction.
iOS integration paths
CocoaPods is the primary, supported iOS integration path — it pulls the
IronSource SDK via the podspec. Swift Package Manager is secondary; see
Package.swift for details. Without the SDK the plugin still builds: all
native SDK code is guarded and degrades to no-ops.
API
initialize(...)launchTestSuite()requestConsentInfo(...)showPrivacyOptions(...)getConsentData()resetConsent()setCCPAConsent(...)setChildDirected(...)requestTrackingAuthorization()getAdvertisingId()setDynamicUserId(...)createBanner(...)showBanner()hideBanner()destroyBanner()updateBannerStyle(...)loadInterstitial(...)isInterstitialReady()showInterstitial()loadRewarded(...)isRewardedReady()showRewarded()addListener(string, ...)- Interfaces
- Type Aliases
Capacitor LevelPlay Ads Plugin
Unity LevelPlay (formerly ironSource) mediation SDK for Capacitor.
CRITICAL: Proper Execution Order
To stay compliant with GDPR / CCPA / COPPA, follow this exact order at app start:
- Request Consent:
await LevelPlayAds.requestConsentInfo(...)Shows the custom consent modal if the user has not decided yet. - Initialize SDK:
await LevelPlayAds.initialize(...)The SDK boots up using the consent decision gathered in step 1. - Load Ads: e.g.
await LevelPlayAds.loadInterstitial(...) - Show Ads: e.g.
await LevelPlayAds.showInterstitial()
Ad loading is gated: initialize() must have run and a consent decision must
exist, otherwise load calls reject.
initialize(...)
initialize(options: InitializeOptions) => Promise<InitializeResult>
Initializes the LevelPlay mediation SDK.
Call after requestConsentInfo().
| Param | Type |
|---|---|
options |
InitializeOptions |
Returns: Promise<InitializeResult>
launchTestSuite()
launchTestSuite() => Promise<void>
Launches the LevelPlay Test Suite for verifying mediation integration. Debug builds only.
requestConsentInfo(...)
requestConsentInfo(options?: ConsentOptions | undefined) => Promise<ConsentData>
Requests the current consent decision. If none exists, shows the custom consent modal. Must be called before loading ads.
| Param | Type |
|---|---|
options |
ConsentOptions |
Returns: Promise<ConsentData>
showPrivacyOptions(...)
showPrivacyOptions(options?: ConsentOptions | undefined) => Promise<ConsentData>
Re-presents the consent modal so the user can change a prior decision. Wire this to a button in your app's settings/privacy screen.
| Param | Type |
|---|---|
options |
ConsentOptions |
Returns: Promise<ConsentData>
getConsentData()
getConsentData() => Promise<ConsentData>
Returns the persisted consent decision without showing any UI.
Returns: Promise<ConsentData>
resetConsent()
resetConsent() => Promise<ConsentData>
Clears the stored consent decision so the next requestConsentInfo()
re-shows the modal. Useful for QA flows and a "reset privacy choice"
button in your settings screen.
Returns: Promise<ConsentData>
setCCPAConsent(...)
setCCPAConsent(options: { doNotSell: boolean; }) => Promise<void>
Sets the CCPA "do not sell my personal information" flag.
| Param | Type |
|---|---|
options |
{ doNotSell: boolean; } |
setChildDirected(...)
setChildDirected(options: { isChildDirected: boolean; }) => Promise<void>
Sets the COPPA child-directed treatment flag.
| Param | Type |
|---|---|
options |
{ isChildDirected: boolean; } |
requestTrackingAuthorization()
requestTrackingAuthorization() => Promise<TrackingAuthorizationResult>
iOS only. Prompts the App Tracking Transparency (ATT) dialog.
No-op on Android (resolves with status NOT_APPLICABLE).
Returns: Promise<TrackingAuthorizationResult>
getAdvertisingId()
getAdvertisingId() => Promise<AdvertisingIdResult>
Returns the platform advertising identifier:
- Android — Google Advertising ID (GAID), via Play Services.
limitedis theLimitAdTrackingflag. - iOS — IDFA, via
ASIdentifierManager. The OS returns an all-zero UUID until the user grants App Tracking Transparency authorization, in which caselimitedis true andidis"00000000-0000-0000-0000-000000000000".
Call requestTrackingAuthorization() first on iOS to get a real value.
Returns: Promise<AdvertisingIdResult>
setDynamicUserId(...)
setDynamicUserId(options: { userId: string; }) => Promise<void>
Sets the dynamic user ID forwarded in server-to-server (S2S) reward
callbacks. Call before showRewarded() to tag each reward with a
verifiable token (e.g. a transaction ID or session nonce).
Can be changed between ad shows — the value active at show time is the one included in the S2S callback.
| Param | Type |
|---|---|
options |
{ userId: string; } |
createBanner(...)
createBanner(options: BannerOptions) => Promise<void>
Creates and loads a banner ad.
| Param | Type |
|---|---|
options |
BannerOptions |
showBanner()
showBanner() => Promise<void>
Shows a previously created (and hidden) banner.
hideBanner()
hideBanner() => Promise<void>
Temporarily hides the banner without destroying it.
destroyBanner()
destroyBanner() => Promise<void>
Destroys the banner and removes it from the view hierarchy.
updateBannerStyle(...)
updateBannerStyle(options: BannerStyleOptions) => Promise<void>
Reposition or restyle the active banner without destroying it.
Only the provided fields change; omitted fields keep their current value.
isOverlap only affects Android — iOS always overlays the WebView.
| Param | Type |
|---|---|
options |
BannerStyleOptions |
loadInterstitial(...)
loadInterstitial(options: AdLoadOptions) => Promise<void>
Loads an interstitial ad.
| Param | Type |
|---|---|
options |
AdLoadOptions |
isInterstitialReady()
isInterstitialReady() => Promise<AdReadyResult>
Synchronously checks whether an interstitial ad is loaded and ready.
Returns: Promise<AdReadyResult>
showInterstitial()
showInterstitial() => Promise<void>
Shows the loaded interstitial ad.
loadRewarded(...)
loadRewarded(options: AdLoadOptions) => Promise<void>
Loads a rewarded ad.
| Param | Type |
|---|---|
options |
AdLoadOptions |
isRewardedReady()
isRewardedReady() => Promise<AdReadyResult>
Synchronously checks whether a rewarded ad is loaded and ready.
Returns: Promise<AdReadyResult>
showRewarded()
showRewarded() => Promise<void>
Shows the loaded rewarded ad.
addListener(string, ...)
addListener(eventName: AdEventName | string, listenerFunc: (info: any) => void) => Promise<PluginListenerHandle>
Listens for native ad events.
Interstitial events
onInterstitialAdLoaded—AdInfoonInterstitialAdLoadFailed—AdErrorInfoonInterstitialAdDisplayed—AdInfoonInterstitialAdDisplayFailed—AdErrorInfoonInterstitialAdClicked—AdInfoonInterstitialAdClosed—AdInfoonInterstitialAdInfoChanged—AdInfo
Rewarded events
onRewardedAdLoaded—AdInfoonRewardedAdLoadFailed—AdErrorInfoonRewardedAdDisplayed—AdInfoonRewardedAdDisplayFailed—AdErrorInfoonRewardedAdClicked—AdInfoonRewardedAdClosed—AdInfoonRewardedAdInfoChanged—AdInfoonRewardedAdRewarded—AdRewardEvent
Banner events
onBannerAdLoaded—AdInfoonBannerAdLoadFailed—AdErrorInfoonBannerAdDisplayed—AdInfoonBannerAdDisplayFailed—AdErrorInfoonBannerAdClicked—AdInfoonBannerAdExpanded—AdInfoonBannerAdCollapsed—AdInfoonBannerAdLeftApplication—AdInfo
Revenue
onAdRevenue—AdRevenueEvent(impression-level ad revenue / ILRD)
Consent
onConsentStatusChanged—ConsentData
Orientation
onOrientationChanged—OrientationChangedEvent
Prefer the typed AdEvent constants (e.g. AdEvent.InterstitialLoaded)
over raw strings for compile-time safety.
| Param | Type |
|---|---|
eventName |
string |
listenerFunc |
(info: any) => void |
Returns: Promise<PluginListenerHandle>
Interfaces
InitializeResult
| Prop | Type | Description |
|---|---|---|
status |
string |
INITIALIZED_SUCCESSFULLY on success. |
InitializeOptions
| Prop | Type | Description |
|---|---|---|
appKey |
string |
LevelPlay app key from the Unity LevelPlay dashboard. Required. |
userId |
string |
Optional publisher-defined user identifier (used for server-to-server rewarded callbacks and reporting). |
isTesting |
boolean |
Enables LevelPlay test/integration mode. Set false before publishing. Default: false |
ConsentData
| Prop | Type | Description |
|---|---|---|
status |
'UNKNOWN' | 'GRANTED' | 'DENIED' |
The recorded consent decision. - UNKNOWN — no decision yet (fresh install). - GRANTED — user granted consent. - DENIED — user denied consent. |
granted |
boolean |
Simplified boolean: true when status === 'GRANTED'. |
canRequestAds |
boolean |
True when ads may be requested (a decision exists, granted or denied). |
provider |
ConsentProvider |
Which provider produced this decision: usercentrics, inmobi, or custom. Useful for deciding whether to trust the tcString field. |
tcString |
string |
IAB TCF consent string. Populated by the usercentrics / inmobi providers, and by the custom provider when the rich modal is used (TCF v2.3-compatible — see {@link ConsentOptions.services}). Undefined for the legacy custom alert, which produces no TCF payload. |
consentedServiceIds |
string[] |
IDs of the services the user left enabled. Populated only by the rich custom modal. |
ConsentOptions
| Prop | Type | Description |
|---|---|---|
privacyPolicyUrl |
string |
URL opened when the user taps the privacy policy link in the modal. Only used by the custom consent provider — ignored under Usercentrics and InMobi (which render their own privacy policy links inside the CMP UI). |
legalNoticeUrl |
string |
URL opened when the user taps the "Legal Notice" link in the custom modal. custom provider only. |
networks |
string[] |
Mediation network keys the consent decision should be applied to. When omitted, consent is applied globally. |
services |
string | ConsentServicesConfig |
Universal, language-neutral definition of the categories and services to display. May be the parsed object or a JSON string. Required to show the rich modal — see {@link ConsentServicesConfig}. |
locale |
string |
BCP-47 / ISO-639-1 language code for the modal copy. Default 'en'. Falls back to English for any missing key. |
translations |
Record<string, ConsentLocaleBundle> |
Extra or overriding translation bundles, keyed by locale code. Merged over the built-in English bundle. Supply this to localize or to override the default copy / per-service descriptions. |
appName |
string |
App name shown in the modal title and copy. Default: 'This app'. |
logoUrl |
string |
URL of the logo shown at the top of the first layer. When omitted, the first letter of appName is shown in an accent-colored circle. |
accentColor |
string |
Accent color (any CSS color) for buttons, switches and active tabs. Default: '#143cc4'. |
cmpId |
number |
IAB CMP ID written into the TC string and IABTCF_CmpSdkID. Default 0 (non-certified). Set your registered ID once you become an IAB-listed CMP. |
cmpVersion |
number |
CMP version written into the TC string and IABTCF_CmpSdkVersion. Default 1. |
gvl |
string | GlobalVendorList |
Optional IAB Global Vendor List, as a parsed object or a URL to fetch. Per IAB policy the GVL must not be fetched from consensu.org on the client; supply your own server-hosted copy here, or omit to use the version the plugin bundles. Only its vendorListVersion affects the encoded TC string today. |
ConsentServicesConfig
Universal, language-neutral consent configuration passed via {@link ConsentOptions.services}. Every human-readable string is a lookup ID resolved through the active {@link ConsentLocaleBundle} — only proper nouns (company names, addresses), URLs and TCF numbers live here.
| Prop | Type | Description |
|---|---|---|
gvlVendorListVersion |
number |
GVL version recorded in the encoded TC string. |
tcfPolicyVersion |
number |
TCF policy version. 5 = TCF v2.3 (the default). |
publisherCC |
string |
Publisher country (ISO-3166-1 alpha-2), e.g. 'PL'. |
categories |
ConsentCategory[] |
Display + toggle metadata for each category. |
services |
ConsentService[] |
The services/vendors shown under the categories. |
ConsentCategory
| Prop | Type | Description |
|---|---|---|
id |
string |
Stable key; also the lookup ID for the localized name/description. |
locked |
boolean |
Locked categories are always on and cannot be toggled (e.g. essential). |
default |
boolean |
Initial toggle state when unlocked. Default false. |
order |
number |
Sort order (ascending). |
icon |
string |
Optional emoji/icon shown on the first-layer summary row. |
ConsentService
| Prop | Type | Description |
|---|---|---|
id |
string |
Stable key; also the lookup ID for an optional localized description. |
categoryId |
string |
Which {@link ConsentCategory.id} this service belongs to. |
network |
string |
LevelPlay mediation network key this service maps to, e.g. 'unityads', 'meta', 'pangle', 'admob'. When set, the user's toggle for this service is forwarded to LevelPlay as a per-network GDPR consent so the mediated SDK receives the right value. Omit for non-mediation services (sign-in, analytics, CMP, etc.). |
default |
boolean |
Initial toggle state. Ignored when the category is locked. Default false. |
company |
{ name: string; address?: string; } |
Processing company — proper nouns, language-neutral. |
description |
string |
Service description shown in the detail card. A localized serviceDescriptions[id] override in a translation bundle takes precedence when present. |
purposeIds |
string[] |
Localized purpose label IDs. |
technologyIds |
string[] |
Localized technology label IDs. |
dataCollectedIds |
string[] |
Localized data-category label IDs. |
legalBasisIds |
string[] |
Localized legal-basis label IDs. |
locationCC |
string[] |
Processing location ISO-3166 country codes. |
transferCC |
string[] |
Third-country transfer ISO-3166 country codes. |
retentionId |
string |
Localized retention-phrasing ID. |
recipients |
string[] |
Data recipient names — proper nouns. |
urls |
{ privacy?: string; cookie?: string; optOut?: string; } |
Policy URLs. |
tcf |
ConsentServiceTcf |
TCF mapping. Omit for vendors not on the IAB Global Vendor List. |
ConsentServiceTcf
| Prop | Type | Description |
|---|---|---|
vendorId |
number |
IAB GVL vendor ID. |
purposeConsents |
number[] |
Purpose IDs (1–24) this vendor seeks consent for. |
purposeLegInt |
number[] |
Purpose IDs (1–24) processed under legitimate interest. |
specialFeatures |
number[] |
Special-feature IDs (1–12), e.g. 1 = precise geolocation. |
googleAtpId |
number |
Google Additional Consent (AC) provider ID, for AdMob/ATP demand. |
ConsentLocaleBundle
Localized copy for the custom modal. Every section is optional and merged over the built-in English bundle; supply only what you want to translate or override. Keys match the IDs used in {@link ConsentServicesConfig}.
| Prop | Type | Description |
|---|---|---|
ui |
Record<string, string> |
UI chrome strings (titles, buttons, section headers). Supports {var}. |
categories |
Record<string, { name: string; description?: string }> |
Per-category name + description, keyed by category ID. |
purposes |
Record<string, string> |
Purpose labels, keyed by purpose ID. |
technologies |
Record<string, string> |
Technology labels, keyed by technology ID. |
dataCategories |
Record<string, string> |
Data-category labels, keyed by data-category ID. |
legalBases |
Record<string, string> |
Legal-basis labels, keyed by legal-basis ID. |
retention |
Record<string, string> |
Retention-phrasing strings, keyed by retention ID. |
countries |
Record<string, string> |
Country names, keyed by ISO-3166 code. |
serviceDescriptions |
Record<string, string> |
Optional localized overrides for per-service descriptions, keyed by service ID. The base text lives in {@link ConsentService.description}; supply this only to translate it. |
GlobalVendorList
Minimal IAB Global Vendor List shape. Only vendorListVersion is read today.
| Prop | Type |
|---|---|
vendorListVersion |
number |
TrackingAuthorizationResult
| Prop | Type | Description |
|---|---|---|
status |
string |
iOS ATT status: AUTHORIZED, DENIED, RESTRICTED, NOT_DETERMINED, or NOT_APPLICABLE (Android). |
AdvertisingIdResult
| Prop | Type | Description |
|---|---|---|
id |
string |
The advertising identifier. Empty string when unavailable; on iOS the all-zeros UUID "00000000-0000-0000-0000-000000000000" when ATT is not authorized. |
limited |
boolean |
True when the user has limited / opted out of ad tracking. Android: LimitAdTracking flag. iOS: true when ATT is not authorized. |
BannerOptions
| Prop | Type | Description |
|---|---|---|
adUnitId |
string |
LevelPlay banner ad unit ID. Required. |
adSize |
'BANNER' | 'LARGE' | 'MEDIUM_RECTANGLE' | 'LEADERBOARD' | 'ADAPTIVE' |
Banner size. Default: ADAPTIVE. |
position |
BannerPosition |
Banner position on screen. Default: BOTTOM. |
isAutoShow |
boolean |
Show the banner automatically once loaded. Default: true. |
isOverlap |
boolean |
If true the banner overlaps the webview; if false it pushes the webview. Android only — iOS always overlays the WebView. Default: true. |
retryInterval |
number |
Minimum delay between consecutive load() calls, in milliseconds. Throttles invalid traffic. Default: 5000 (5 seconds). |
BannerStyleOptions
| Prop | Type | Description |
|---|---|---|
position |
BannerPosition |
New banner position. |
isOverlap |
boolean |
Android-only overlap flag. iOS ignores this. |
AdLoadOptions
| Prop | Type | Description |
|---|---|---|
adUnitId |
string |
LevelPlay ad unit ID. Required. |
autoShow |
boolean |
If true, the ad is shown immediately after a successful load. The returned promise then resolves on display (or rejects with "Auto-show failed: …"). Default: false. |
retryInterval |
number |
Minimum delay between consecutive load() calls, in milliseconds. Throttles invalid traffic. Default: 5000 (5 seconds). |
AdReadyResult
| Prop | Type | Description |
|---|---|---|
isReady |
boolean |
True when the ad is loaded and can be shown. |
PluginListenerHandle
| Prop | Type |
|---|---|
remove |
() => Promise<void> |
Type Aliases
ConsentProvider
Which consent UI the plugin shows. Configured at install time via
levelplay.consentProvider in the host app's package.json — not via JS.
usercentrics(default): IAB TCF v2.3 compliant. Google-certified Gold tier CMP partner. Requireslevelplay.usercentrics.settingsIdfrom https://usercentrics.com/.inmobi: IAB TCF v2.2 compliant. Bundles InMobi Choice CMP. Requireslevelplay.inmobi.pCodefrom https://choice.inmobi.com/.custom: built-in alert dialog. Not TCF compliant; do not ship to EU.
'usercentrics' | 'inmobi' | 'custom'
Record
Construct a type with a set of properties K of type T
{
[P in K]: T;
}
BannerPosition
Banner placement on screen. TOP_LEFT / TOP_RIGHT / BOTTOM_LEFT /
BOTTOM_RIGHT anchor the banner to the corresponding screen corner;
CENTER places it in the middle.
'TOP' | 'BOTTOM' | 'TOP_LEFT' | 'TOP_RIGHT' | 'BOTTOM_LEFT' | 'BOTTOM_RIGHT' | 'CENTER'
AdEventName
(typeof AdEvent)[keyof typeof AdEvent]