Request Volume
System Health
Loading health…
Launch a CPI campaign in minutes. Upload a banner creative, set a daily budget, and AiMatrix auto-delivers installs across the network — with pacing, frequency caps, and per-install bid scoring tuned for games.
Drop the Cocos2d-x SDK into your game, register your app, and start earning from house ads across the AiMatrix network. Real-time eCPM, transparent revenue share, no minimum fill — built for Android, Cocos2d-x C++ first.
AiMatrix runs both sides of the house: Ads for advertisers buying installs and Revenue for publishers monetizing their games. Pick your side below.
Launch CPI campaigns. Manual bid, Target CPI, Target ROAS, or Max installs — you pick the strategy.
Drop in the Cocos2d-x SDK (or use the native Android / Java integration), register your app, start earning per install delivered. AdMob-style floor eCPM + optimize-for controls.
No account managers, no minimum commitment. From signup to first install, under 15 minutes.
Upload a banner creative, pick a bidding strategy (Manual CPI, Target CPI, Target ROAS, or Max Installs), set a daily budget. Targeting: country, device, OS version, game genre.
The network auto-bids on every eligible impression. Pacing, frequency caps, and install-prediction scoring run in the background — you watch the dashboard.
Billed on confirmed install events only. Real-time spend tracker, transparent eCPM and CVR per campaign. Pause, resume, or reallocate budget live.
Drop the SDK, register an app, get paid per install delivered. No minimum traffic, no approval queue.
Cocos2d-x 3.17.2 / 4.0, Android Java, Kotlin, or Jetpack Compose — one-line init, per-format APIs for banner, interstitial, rewarded, native, and icon ads.
Per-app floor eCPM and optimize-for preset (Revenue / Fill / Balanced) — AdMob-style knobs. Paid Event Listener streams per-impression revenue to your server.
70% revenue share by default, tunable per-publisher by admins. Real-time Earnings dashboard, per-app daily breakdown, precision-tagged revenue attribution.
Advertiser side looks like Google Ads. Publisher side looks like AdMob. Campaigns from one serve on the other's inventory — that's the network.
App developers drop the SDK into their game (5 platforms supported), register their app, and get an App ID in < 5 minutes. Earnings start the moment the first ad serves.
Game marketers create a CPI campaign with a creative + budget. Four bidding strategies cover manual bids all the way to fully-automated Max Installs.
Every impression on a publisher app runs through install-prediction scoring; the matching campaign serves and both sides get paid. No mediation, no waterfall.
Every feature below ships live today — no coming-soons, no beta flags.
Paste any Google Play Store URL — every ad demo below updates to show exactly what your campaign would look like on-device.
Native ads blend into your game's UI — card or list-item style — so they feel like part of the experience while still showing the required AD label for Google Play.
Rendered by the SDK using fields you provide: icon, headline, body and CTA.
Full-screen ads shown at natural breaks — between levels, after a game-over, or on app resume. High-impact placement with one-tap install and a visible close button.
Full device viewport, portrait or landscape. The AD label and × button are enforced by the SDK.
Opt-in full-screen ads that reward the player with in-game currency, extra lives, or hints. Highest eCPM in the network because players choose to watch them.
You define the reward (e.g. 50 gems) and the SDK fires a callback to your game once the ad completes.
Small square tiles rendered inside your game's "More games" screen or launcher. Low-intrusion, high-retention — a single tap takes the player to the Play Store.
Just the app icon. The SDK adds the AD chip so you stay compliant.
Sub-100ms ad decisions on every impression. Auctions run per impression, not per batch — so every slot is priced fairly.
Impressions, clicks, installs and revenue update the moment events hit the tracker. No overnight batches.
Revenue share is set per publisher and visible in your dashboard at all times. No hidden deductions.
Target by country, device, Android version, game genre, and session behaviour — all configurable per campaign.
Drop-in banner SDK for Cocos2d-x C++ on Android. A few lines of code — or a single Gradle dep plus a Java call — and your game is live on the network.
Every advertiser is reviewed. Click-fraud detection runs on every request so your inventory stays clean.
Launch user-acquisition campaigns with transparent CPI pricing, freq caps, pacing, and real-time spend reporting. No account managers, no minimums — just a dashboard and a daily budget.
Already publishing apps? Visit revenue.aimatrixnetwork.com to monetize — advertiser and publisher accounts are separate.
Drop the Cocos2d-x C++ SDK (or native Android Java integration), register your app, get an App ID. House ads from the AiMatrix advertiser pool start serving immediately, with per-install revenue share paid on delivery — no minimum traffic, no approval queue.
Buying installs instead? Visit ads.aimatrixnetwork.com — advertiser accounts live on a separate portal.
Launch user-acquisition campaigns with granular bidding and creative A/B testing.
Open Ads portal →Integrate the SDK, approve campaigns, and watch revenue build up in real time.
Open Revenue portal →One email, one side — advertiser or publisher. Pick during signup and we'll route you to the right portal.
Pick the side that matches how you'll use AiMatrix. You can't be on both — one account, one portal.
Create a banner campaign. Creatives can be uploaded after the campaign is saved.
Paste your app's Play Store URL or package name — we'll fetch the title, icon, and description automatically.
Tune how this app earns.
Loading health…
| Campaign | Status | Payout / install | Daily Budget | Spent |
|---|---|---|---|---|
Loading campaigns… | ||||
| App | Package | Category | Status | App ID | Settings | |
|---|---|---|---|---|---|---|
Loading apps… | ||||||
| Date | App | Impressions | Clicks | eCPM | Revenue |
|---|---|---|---|---|---|
Loading earnings… | |||||
No publisher admin list endpoint yet
Publishers register via POST /api/auth/v1/auth/register with role=publisher.
No advertiser admin list endpoint yet
Advertisers register via POST /api/auth/v1/auth/register with role=advertiser.
aimatrix/ into your game root, then add add_subdirectory(aimatrix) and target_link_libraries(${APP_NAME} aimatrix) to your CMakeLists.txt.
Cocos2d-x 3.17.2 uses ndk-build. Place aimatrix.a + headers under cocos2d/external/aimatrix/, then add LOCAL_WHOLE_STATIC_LIBRARIES += aimatrix_static to proj.android/app/jni/Android.mk.
Add the Maven dep: implementation 'com.aimatrixnetwork:sdk:1.0.0' in your app/build.gradle. Minimum SDK 21.
Same Maven dep as Java: implementation 'com.aimatrixnetwork:sdk:1.0.0'. Kotlin extensions are bundled — no extra artifact needed.
Same Maven dep plus the Compose artifact: implementation 'com.aimatrixnetwork:sdk-compose:1.0.0' exposes AiMatrixBanner, AiMatrixNativeAd, etc. as Composables.
#include "aimatrix/AiMatrix.h" // Once on app boot, e.g. in AppDelegate::applicationDidFinishLaunching. aimatrix::AiMatrix::init("YOUR_APP_ID"); // Size: BannerSize::BANNER_320_50 | MEDIUM_RECTANGLE | LEADERBOARD | SMART auto banner = aimatrix::AiMatrix::showBanner({ .size = aimatrix::BannerSize::SMART, .placement = "MainMenu_Bottom", .anchor = aimatrix::Anchor::Bottom, }); banner->onClick([]{ CCLOG("banner clicked"); });
#include "aimatrix/AiMatrix.h" // 3.17.2 calls look identical to 4.0 — the SDK API is the same. // Only the build glue differs: add to proj.android/app/jni/Android.mk: // LOCAL_WHOLE_STATIC_LIBRARIES += aimatrix_static // Once on app boot, e.g. in AppDelegate::applicationDidFinishLaunching. aimatrix::AiMatrix::init("YOUR_APP_ID"); aimatrix::Banner* banner = aimatrix::AiMatrix::showBanner({ aimatrix::BannerSize::SMART, "MainMenu_Bottom", aimatrix::Anchor::Bottom, }); banner->onClick([]{ CCLOG("banner clicked"); });
import com.aimatrixnetwork.sdk.AiMatrix; import com.aimatrixnetwork.sdk.Banner; import com.aimatrixnetwork.sdk.BannerSize; // In your Application.onCreate(): AiMatrix.init(this, "YOUR_APP_ID"); // Anywhere after: attach the banner to your Activity's root view. Banner banner = AiMatrix.showBanner(this, new Banner.Request() .size(BannerSize.SMART) .placement("MainMenu_Bottom") .anchor(Banner.Anchor.BOTTOM)); banner.setOnClickListener(() -> Log.d("AiMatrix", "banner clicked"));
import com.aimatrixnetwork.sdk.AiMatrix import com.aimatrixnetwork.sdk.BannerSize // In your Application.onCreate(): AiMatrix.init(this, "YOUR_APP_ID") // Anywhere after: attach the banner to your Activity's root view. val banner = AiMatrix.showBanner(this) { size = BannerSize.SMART placement = "MainMenu_Bottom" anchor = Banner.Anchor.BOTTOM } banner.onClick { Log.d("AiMatrix", "banner clicked") }
import com.aimatrixnetwork.sdk.compose.AiMatrixBanner import com.aimatrixnetwork.sdk.BannerSize // Drop the composable anywhere in your UI tree. The SDK handles // lifecycle + refresh internally; `AiMatrix.init()` should still // be called once in your Application.onCreate(). @Composable fun MainMenuScreen() { Column(Modifier.fillMaxSize()) { // ... your menu content ... Spacer(Modifier.weight(1f)) AiMatrixBanner( placement = "MainMenu_Bottom", size = BannerSize.SMART, onClick = { Log.d("AiMatrix", "banner clicked") }, ) } }
#include "aimatrix/AiMatrix.h" aimatrix::AiMatrix::loadNative({ .placement = "Feed_Card" }, [this](const aimatrix::NativeAd& ad) { // Render the ad inside your own Cocos2d-x UI nodes. auto sprite = Sprite::create(ad.iconPath); myCard.icon->setSpriteFrame(sprite->getSpriteFrame()); myCard.title->setString(ad.headline); myCard.body->setString(ad.description); myCard.cta->setString("Install"); ad.bindClick(myCard.node); });
#include "aimatrix/AiMatrix.h" // Same API as 4.0 — the SDK targets the older std::function+lambda // syntax too, so your 3.17.2 compiler (clang / gcc-4.9+) is fine. aimatrix::AiMatrix::loadNative( aimatrix::NativeRequest("Feed_Card"), [this](const aimatrix::NativeAd& ad) { auto sprite = Sprite::create(ad.iconPath); myCard.icon->setSpriteFrame(sprite->getSpriteFrame()); myCard.title->setString(ad.headline); myCard.body->setString(ad.description); myCard.cta->setString("Install"); ad.bindClick(myCard.node); });
import com.aimatrixnetwork.sdk.AiMatrix; import com.aimatrixnetwork.sdk.NativeAd; AiMatrix.loadNative(this, "Feed_Card", new NativeAd.Listener() { @Override public void onAdLoaded(NativeAd ad) { // Render inside your own view. The SDK returns assets only — // you're in full control of the layout + click surface. Glide.with(iconView).load(ad.getIconUrl()).into(iconView); titleView.setText(ad.getHeadline()); bodyView.setText(ad.getDescription()); ctaView.setText("Install"); rootView.setOnClickListener(v -> ad.onClick()); } @Override public void onAdFailed(String error) { Log.w("AiMatrix", error); } });
import com.aimatrixnetwork.sdk.AiMatrix import com.aimatrixnetwork.sdk.NativeAd AiMatrix.loadNative(this, "Feed_Card") { result -> result.onSuccess { ad: NativeAd -> Glide.with(iconView).load(ad.iconUrl).into(iconView) titleView.text = ad.headline bodyView.text = ad.description ctaView.text = "Install" rootView.setOnClickListener { ad.onClick() } }.onFailure { Log.w("AiMatrix", it.message.orEmpty()) } }
import com.aimatrixnetwork.sdk.compose.AiMatrixNativeAd // The Composable handles loading + rendering. Supply the layout // through the `content` lambda — the SDK exposes the loaded ad as // a receiver so you reference fields directly. @Composable fun FeedCard() { AiMatrixNativeAd(placement = "Feed_Card") { ad -> Row(Modifier.clickable { ad.onClick() }.padding(12.dp)) { AsyncImage(model = ad.iconUrl, contentDescription = null, modifier = Modifier.size(48.dp).clip(RoundedCornerShape(10.dp))) Column(Modifier.padding(start = 12.dp)) { Text(ad.headline, fontWeight = FontWeight.Bold) Text(ad.description, style = MaterialTheme.typography.bodySmall) } } } }
#include "aimatrix/AiMatrix.h" // Preload at level-start so there is zero delay when shown. aimatrix::AiMatrix::preloadInterstitial({ .placement = "LevelComplete" }); // Show when the level ends. if (aimatrix::AiMatrix::isInterstitialReady("LevelComplete")) { aimatrix::AiMatrix::showInterstitial("LevelComplete", [](aimatrix::AdResult r){ CCLOG("interstitial closed: %d", (int)r); }); }
#include "aimatrix/AiMatrix.h" // API identical to 4.0 — preload early, show when ready. aimatrix::AiMatrix::preloadInterstitial( aimatrix::InterstitialRequest("LevelComplete")); if (aimatrix::AiMatrix::isInterstitialReady("LevelComplete")) { aimatrix::AiMatrix::showInterstitial("LevelComplete", [](aimatrix::AdResult r) { CCLOG("interstitial closed: %d", (int)r); }); }
import com.aimatrixnetwork.sdk.AiMatrix; import com.aimatrixnetwork.sdk.Interstitial; // Preload at level-start so there is zero delay when shown. AiMatrix.preloadInterstitial(this, "LevelComplete"); // Show when the level ends. if (AiMatrix.isInterstitialReady("LevelComplete")) { AiMatrix.showInterstitial(this, "LevelComplete", new Interstitial.Listener() { @Override public void onClosed(Interstitial.Result r) { Log.d("AiMatrix", "interstitial closed: " + r); } }); }
import com.aimatrixnetwork.sdk.AiMatrix import com.aimatrixnetwork.sdk.Interstitial // Preload at level-start so there is zero delay when shown. AiMatrix.preloadInterstitial(this, "LevelComplete") // Show when the level ends. if (AiMatrix.isInterstitialReady("LevelComplete")) { AiMatrix.showInterstitial(this, "LevelComplete") { r: Interstitial.Result -> Log.d("AiMatrix", "interstitial closed: $r") } }
import com.aimatrixnetwork.sdk.compose.rememberAiMatrixInterstitial // rememberAiMatrixInterstitial preloads when the Composable enters // composition + disposes cleanly when it leaves. Call .show() when // you want to display (e.g. after a level-complete state flip). @Composable fun LevelScreen(state: LevelState) { val inter = rememberAiMatrixInterstitial(placement = "LevelComplete") LaunchedEffect(state.completed) { if (state.completed && inter.isReady) { inter.show() } } // ... your level UI ... }
#include "aimatrix/AiMatrix.h" aimatrix::AiMatrix::preloadRewarded({ .placement = "ExtraLife", .reward = { "gems", 50 }, }); // Show when the player taps "Watch ad for reward". aimatrix::AiMatrix::showRewarded("ExtraLife", [this](const aimatrix::RewardResult& r) { if (r.completed) { player->addGems(r.reward.amount); } });
#include "aimatrix/AiMatrix.h" aimatrix::RewardedRequest req("ExtraLife"); req.reward = aimatrix::Reward("gems", 50); aimatrix::AiMatrix::preloadRewarded(req); // Show when the player taps "Watch ad for reward". aimatrix::AiMatrix::showRewarded("ExtraLife", [this](const aimatrix::RewardResult& r) { if (r.completed) { player->addGems(r.reward.amount); } });
import com.aimatrixnetwork.sdk.AiMatrix; import com.aimatrixnetwork.sdk.Rewarded; import com.aimatrixnetwork.sdk.Reward; AiMatrix.preloadRewarded(this, new Rewarded.Request() .placement("ExtraLife") .reward(new Reward("gems", 50))); // Show when the player taps "Watch ad for reward". AiMatrix.showRewarded(this, "ExtraLife", new Rewarded.Listener() { @Override public void onRewarded(Reward r) { player.addGems(r.getAmount()); } @Override public void onClosed(boolean earned) { /* track */ } });
import com.aimatrixnetwork.sdk.AiMatrix import com.aimatrixnetwork.sdk.Reward AiMatrix.preloadRewarded(this) { placement = "ExtraLife" reward = Reward("gems", 50) } // Show when the player taps "Watch ad for reward". AiMatrix.showRewarded(this, "ExtraLife") { result -> if (result.completed) { player.addGems(result.reward.amount) } }
import com.aimatrixnetwork.sdk.compose.rememberAiMatrixRewarded import com.aimatrixnetwork.sdk.Reward @Composable fun ExtraLifeButton(onRewarded: (Reward) -> Unit) { val rewarded = rememberAiMatrixRewarded( placement = "ExtraLife", reward = Reward("gems", 50), ) Button( enabled = rewarded.isReady, onClick = { rewarded.show { r -> if (r.completed) onRewarded(r.reward) } }, ) { Text("Watch ad · earn 50 gems") } }
#include "aimatrix/AiMatrix.h" // Returns up to N icon ads for a "More games" grid. aimatrix::AiMatrix::loadIconAds({ .placement = "MoreGames", .count = 3, }, [this](const std::vector<aimatrix::IconAd>& ads) { for (size_t i = 0; i < ads.size(); ++i) { // Icon-only — no text, just the tile sprite. auto sprite = Sprite::create(ads[i].iconPath); grid.tiles[i].icon->setSpriteFrame(sprite->getSpriteFrame()); ads[i].bindClick(grid.tiles[i].node); } });
#include "aimatrix/AiMatrix.h" aimatrix::IconRequest req("MoreGames", 3); aimatrix::AiMatrix::loadIconAds(req, [this](const std::vector<aimatrix::IconAd>& ads) { for (size_t i = 0; i < ads.size(); ++i) { auto sprite = Sprite::create(ads[i].iconPath); grid.tiles[i].icon->setSpriteFrame(sprite->getSpriteFrame()); ads[i].bindClick(grid.tiles[i].node); } });
import com.aimatrixnetwork.sdk.AiMatrix; import com.aimatrixnetwork.sdk.IconAd; import java.util.List; AiMatrix.loadIconAds(this, "MoreGames", 3, new IconAd.Listener() { @Override public void onAdsLoaded(List<IconAd> ads) { for (int i = 0; i < ads.size(); i++) { IconAd ad = ads.get(i); Glide.with(tileIcons[i]).load(ad.getIconUrl()).into(tileIcons[i]); tileIcons[i].setOnClickListener(v -> ad.onClick()); } } });
import com.aimatrixnetwork.sdk.AiMatrix import com.aimatrixnetwork.sdk.IconAd AiMatrix.loadIconAds(this, placement = "MoreGames", count = 3) { ads: List<IconAd> -> ads.forEachIndexed { i, ad -> Glide.with(tileIcons[i]).load(ad.iconUrl).into(tileIcons[i]) tileIcons[i].setOnClickListener { ad.onClick() } } }
import com.aimatrixnetwork.sdk.compose.AiMatrixIconGrid @Composable fun MoreGamesGrid() { AiMatrixIconGrid(placement = "MoreGames", count = 3) { ads -> LazyRow(horizontalArrangement = Arrangement.spacedBy(10.dp)) { items(ads) { ad -> AsyncImage( model = ad.iconUrl, contentDescription = null, modifier = Modifier.size(72.dp) .clip(RoundedCornerShape(16.dp)) .clickable { ad.onClick() }, ) } } } }
#include "aimatrix/AiMatrix.h" // Fires once per revenue-earning impression. Mirrors AdMob's // OnPaidEventListener: currency, value, precision, ad source + // format. SDK auto-POSTs to /track/paid-event; this callback // lets you mirror the event locally (MMP, analytics, ...). aimatrix::AiMatrix::setPaidEventListener( [](const aimatrix::PaidEvent& evt) { CCLOG("paid: impression=%s value=%.4f %s precision=%d fmt=%s", evt.impressionId.c_str(), evt.value, evt.currency.c_str(), evt.precision, evt.adFormat.c_str()); // Optional: forward to AppsFlyer / Adjust via their JNI bridges. aimatrix::AiMatrix::forwardToMMP("appsflyer", evt); });
#include "aimatrix/AiMatrix.h" // Same API as 4.0 — std::function callback. aimatrix::AiMatrix::setPaidEventListener( [](const aimatrix::PaidEvent& evt) { CCLOG("paid: %s %.4f %s", evt.impressionId.c_str(), evt.value, evt.currency.c_str()); aimatrix::AiMatrix::forwardToMMP("appsflyer", evt); });
import com.aimatrixnetwork.sdk.AiMatrix; import com.aimatrixnetwork.sdk.PaidEvent; // Register once, typically in Application.onCreate() after init(). // SDK auto-POSTs the event server-side; this callback mirrors it // locally so you can forward to AppsFlyer / Adjust / Branch. AiMatrix.setPaidEventListener(new PaidEvent.Listener() { @Override public void onPaidEvent(PaidEvent evt) { Log.d("AiMatrix", String.format( "paid: impression=%s value=%.4f %s precision=%d fmt=%s", evt.getImpressionId(), evt.getValue(), evt.getCurrency(), evt.getPrecision(), evt.getAdFormat())); AiMatrix.forwardToMMP("appsflyer", evt); } });
import com.aimatrixnetwork.sdk.AiMatrix import com.aimatrixnetwork.sdk.PaidEvent // Called once per revenue-earning impression. SDK auto-POSTs // the event to /track/paid-event; this listener mirrors it // locally so you can forward to AppsFlyer / Adjust / Branch. AiMatrix.setPaidEventListener { evt: PaidEvent -> Log.d("AiMatrix", "paid: impression=${evt.impressionId} " + "value=${evt.value} ${evt.currency} " + "precision=${evt.precision} fmt=${evt.adFormat}") AiMatrix.forwardToMMP("appsflyer", evt) }
import com.aimatrixnetwork.sdk.compose.rememberAiMatrixPaidEvents import androidx.compose.runtime.collectAsState // rememberAiMatrixPaidEvents exposes the paid-event stream as a // Compose State<PaidEvent?>. Useful for showing a "you earned // ₹X" toast, a running revenue counter, or whatever your UI needs. // The server-side POST still happens automatically inside the SDK. @Composable fun RevenueBadge() { val last by rememberAiMatrixPaidEvents() last?.let { evt -> Text( text = "+${evt.currency} %.4f".format(evt.value), style = MaterialTheme.typography.labelSmall, ) } }