Keewano Unity SDK
Loading...
Searching...
No Matches
Ad Revenue

Overview

Ad revenue tracking allows you to monitor monetization from advertisements shown in your game. The Keewano SDK provides dedicated methods to track both the revenue generated from ads and the virtual items granted as rewards (e.g., from rewarded video ads).

Note
Best Practice: Use Ad Network Callbacks
Always call these ad tracking methods from the revenue callbacks provided by your ad serving SDK (IronSource, Google AdMob, Unity Ads, etc.). These callbacks contain accurate revenue data from the ad network. Never estimate or hardcode revenue values.

Ad Revenue vs IAP

It's important to understand the distinction between different types of monetization in your game:

  • Ad Revenue: Revenue from displaying ads (tracked with ReportAdRevenue)
  • Ad Item Grants: Virtual items granted as rewards for watching ads (tracked with ReportAdItemsGranted)
  • In-App Purchases (IAP): Real money purchases (see In-App Purchases)

For example:

  • Player watches a rewarded video ad that generates $0.05 revenue → Ad Revenue
  • Player receives 100 Coins as reward for watching the ad → Ad Item Grant
  • Player buys "500 Crystals Pack" for $4.99 → IAP (see In-App Purchases)

The Two Ad Revenue Methods

The Keewano SDK provides two separate methods for tracking ad revenue:

1. ReportAdRevenue - Track the Ad Revenue

Use KeewanoSDK.ReportAdRevenue() to log the revenue generated from displaying an advertisement.

// After ad impression completes and revenue callback is received
KeewanoSDK.ReportAdRevenue(placementId, revenueInUsdCents);
Definition KeewanoSDK.cs:18
static void ReportAdRevenue(string placement, uint revenueUsdCents)
Reports an ad revenue event.
Definition KeewanoSDK.cs:348

Parameters:

  • placement - The ad placement identifier describing the game context where the ad was shown
  • revenueUsdCents - The revenue in US cents (e.g., $0.05 = 5)

When to call:

  • ONLY after receiving the revenue callback from your ad serving SDK (IronSource, AdMob, Unity Ads, etc.)
  • NEVER estimate or hardcode revenue values

2. ReportAdItemsGranted - Track Rewarded Ad Items

Use KeewanoSDK.ReportAdItemsGranted() to log the virtual items or currencies granted to the player for watching an advertisement (typically rewarded video ads).

// After player watches rewarded ad and receives items
Keewano.Item[] rewardItems = { new Keewano.Item("Coins", 100) };
KeewanoSDK.ReportAdItemsGranted(placementId, rewardItems);
static void ReportAdItemsGranted(string placement, Item[] items)
Reports items granted from watching an advertisement.
Definition KeewanoSDK.cs:364
Definition KBatch.cs:6
Represents a game item with a unique identifier and a quantity.
Definition KeewanoItems.cs:11

Parameters:

  • placement - The same ad placement identifier used in ReportAdRevenue
  • items - Array of items granted (can also use ReadOnlySpan<Item> for zero-copy performance)

When to call:

  • ONLY after items are successfully granted to the player's account
  • For rewarded ads where the player receives in-game items/currency

Placement Naming Best Practices

Use Game-Specific Context, Not Ad Types

Placement names should describe where in your game and why the ad was shown, not just the ad format type.

Use descriptive game-context names:

// Describes WHERE and WHY the ad was shown
KeewanoSDK.ReportAdRevenue("OutOfEnergyPrompt_WatchForRefill", 15);
KeewanoSDK.ReportAdRevenue("LevelFailed_WatchFor5Moves", 12);
KeewanoSDK.ReportAdRevenue("MainMenu_DailyBonusOffer", 10);
KeewanoSDK.ReportAdRevenue("LevelComplete_NextLevelTransition", 8);

Avoid generic ad-type names:

KeewanoSDK.ReportAdRevenue("rewarded_video", 15); // ❌ Too generic
KeewanoSDK.ReportAdRevenue("interstitial", 8); // ❌ No context
KeewanoSDK.ReportAdRevenue("banner", 3); // ❌ Unclear purpose

Placement Naming Examples

Game Context Bad Name Good Name
Out of energy popup offering ad to refill "rewarded_video" "OutOfEnergyPrompt_WatchForRefill"
Level failed, offering 5 more moves "rewarded" "LevelFailed_WatchFor5Moves"
Level failed, offering continue from checkpoint "video_ad" "LevelFailed_ContinueFromCheckpoint"
Ad shown between levels "interstitial" "LevelComplete_Transition"
Daily bonus popup offering double rewards "rewarded_video_2" "DailyBonus_DoubleReward"
Shop popup offering free coins "ad_1" "Shop_WatchForFreeCoins"
Main menu banner "banner" "MainMenu_TopBanner"
Pause menu offering revive "pause_ad" "PauseMenu_ReviveOffer"

Keep Placement Names Static

Important: Don't include dynamic values like level numbers, player IDs, or timestamps in placement names.

Don't do this:

// BAD: Including level number in placement name
KeewanoSDK.ReportAdRevenue($"Level_{levelNumber}_Failed_Watch5Moves", revenue);
KeewanoSDK.ReportAdRevenue($"LevelComplete_{levelNumber}_Transition", revenue);

Do this instead:

// GOOD: Static placement name with context from custom events
KeewanoSDK.ReportLevelStart(5); // Custom event - establishes level context
// ... gameplay ...
// Player runs out of moves, watches ad for 5 more moves
KeewanoSDK.ReportAdRevenue("LevelFailed_Watch5Moves", revenue); // Static name
Keewano.Item[] moves = { new Keewano.Item("Moves", 5) };
KeewanoSDK.ReportAdItemsGranted("LevelFailed_Watch5Moves", moves); // Grant the moves
// ... player continues with extra moves ...
KeewanoSDK.ReportLevelEnd(5); // Custom event - marks level completion

Why? The Keewano SDK maintains an ordered event stream for each player. When you report ReportLevelStart(5), the AI Agents know the player is in level 5. Any events that follow (including ad views) are automatically associated with level 5 until you report ReportLevelEnd(5). There's no need to repeat the level number in every event.

This "context-first" approach means:

  • Report game state changes with custom events (level start/end, entering shop, etc.)
  • Use static placement names that describe the UI location and purpose
  • Let the Keewano AI automatically correlate ad views with the surrounding game context
See also
Custom Events for information on defining custom events like ReportLevelStart, ReportLevelEnd, etc.

Why Context Matters

Using game-specific placement names allows the Keewano AI Agents to:

  • Understand which ad placements perform best in specific game contexts
  • Identify which player actions lead to ad views
  • Analyze the relationship between ad placements and player progression
  • Correlate ad viewing behavior with churn, retention, and monetization

For example, seeing that "LevelFailed_Watch5Moves" has high engagement but "LevelComplete_Transition" has low engagement tells you meaningful information about your game design and player motivation.

Why Are These Two Methods Separated?

These methods are separated because not all ads grant items:

Common Cases

  1. Interstitial Ads Between Levels: Generate revenue but don't grant items - only call ReportAdRevenue
  2. Rewarded Video Ads: Generate revenue AND grant items - call both methods
  3. Banner Ads: Generate revenue but don't grant items - only call ReportAdRevenue
  4. Asynchronous Rewards: Ad completes → revenue tracked → items granted later by server

Common Scenarios

Scenario 1: Interstitial Ad Between Levels (No Reward)

Very common in casual games - ads shown during level transitions that generate revenue but don't reward the player.

void OnLevelComplete(int levelNumber)
{
// Player completed level, show interstitial ad before next level
ShowInterstitialAd();
}
// Ad network callback
void OnInterstitialAdShown(uint revenueCents)
{
// Only report revenue - player gets nothing for watching
KeewanoSDK.ReportAdRevenue("LevelComplete_Transition", revenueCents);
// NO ReportAdItemsGranted call - this ad doesn't reward anything
}

Scenario 2: Out of Energy - Watch to Refill

Player runs out of energy, popup offers to watch ad to refill.

void OnOutOfEnergy()
{
// Show popup: "Out of energy! Watch ad to refill?"
ShowRewardedAdOffer();
}
// Ad network callback
void OnOutOfEnergyAdCompleted(uint revenueCents)
{
const string placement = "OutOfEnergyPrompt_WatchForRefill";
// 1. Report the ad revenue
KeewanoSDK.ReportAdRevenue(placement, revenueCents);
// 2. Grant energy to the player
Keewano.Item[] rewardItems = { new Keewano.Item("Energy", 5) };
KeewanoSDK.ReportAdItemsGranted(placement, rewardItems);
}

Scenario 3: Level Failed - Watch for Extra Moves

Common in Match-3 games - player fails level, offered extra moves to continue.

void OnLevelFailed(int levelNumber)
{
// Show popup: "Level failed! Watch ad for 5 more moves?"
ShowRewardedAdOffer();
}
// Ad network callback
void OnLevelFailedAdCompleted(uint revenueCents)
{
const string placement = "LevelFailed_WatchFor5Moves";
// 1. Report revenue
KeewanoSDK.ReportAdRevenue(placement, revenueCents);
// 2. Grant 5 moves and let player continue
Keewano.Item[] moves = { new Keewano.Item("Moves", 5) };
KeewanoSDK.ReportAdItemsGranted(placement, moves);
}

Scenario 4: Daily Bonus - Watch to Double Reward

Player opens daily bonus, can watch ad to double the reward.

void OnDailyBonusPopup()
{
// Show popup: "Daily bonus: 50 coins. Watch ad to double it!"
ShowRewardedAdOffer();
}
// Ad network callback
void OnDailyBonusAdCompleted(uint revenueCents)
{
const string placement = "DailyBonus_DoubleReward";
// Report revenue
KeewanoSDK.ReportAdRevenue(placement, revenueCents);
// Grant doubled reward
Keewano.Item[] doubledReward = { new Keewano.Item("Coins", 100) }; // 50 * 2
KeewanoSDK.ReportAdItemsGranted(placement, doubledReward);
}

Scenario 5: Main Menu Banner (No Reward)

Banner ad shown in main menu that generates revenue but doesn't grant anything.

void OnMainMenuShown()
{
ShowBannerAd();
}
// Ad network callback
void OnBannerAdImpression(uint revenueCents)
{
// Only report revenue - banners don't grant items
KeewanoSDK.ReportAdRevenue("MainMenu_TopBanner", revenueCents);
// NO ReportAdItemsGranted call
}

Scenario 6: Shop - Watch for Free Coins

Player in shop, can watch ad to get free coins.

void OnShopOpened()
{
// Show "Watch ad for free coins" button
}
void OnWatchForCoinsButtonClicked()
{
ShowRewardedAdOffer();
}
// Ad network callback
void OnShopAdCompleted(uint revenueCents)
{
const string placement = "Shop_WatchForFreeCoins";
KeewanoSDK.ReportAdRevenue(placement, revenueCents);
Keewano.Item[] freeCoins = { new Keewano.Item("Coins", 50) };
KeewanoSDK.ReportAdItemsGranted(placement, freeCoins);
}
static void ReportWindowOpen(string windowName)
Reports a window/popup open event.
Definition KeewanoSDK.cs:261

Scenario 7: Multiple Item Rewards

When a rewarded ad grants multiple different items.

// Ad network callback
void OnSpecialOfferAdCompleted(uint revenueCents)
{
const string placement = "SpecialOffer_BonusReward";
KeewanoSDK.ReportAdRevenue(placement, revenueCents);
// Grant multiple rewards
Keewano.Item[] bonusRewards = {
new Keewano.Item("Coins", 200),
new Keewano.Item("Energy", 10),
new Keewano.Item("Booster_Hammer", 1)
};
KeewanoSDK.ReportAdItemsGranted(placement, bonusRewards);
}

Best Practices

Always Use Ad Network Callbacks

NEVER do this:

// BAD: Hardcoding revenue estimates
void OnAdShown()
{
// This is inaccurate and will corrupt your revenue analytics!
KeewanoSDK.ReportAdRevenue("LevelComplete_Transition", 10); // ❌ Hardcoded estimate
}

ALWAYS do this:

// GOOD: Using actual revenue from your ad network's callback
void OnAdImpressionCallback(uint revenueFromAdNetwork)
{
const string placement = "LevelComplete_Transition";
// Use the actual revenue provided by the ad network
KeewanoSDK.ReportAdRevenue(placement, revenueFromAdNetwork);
}

Only Call ReportAdItemsGranted for Rewarded Ads

Not all ads grant items to the player:

// ✅ CORRECT: Interstitial between levels (no reward)
void OnInterstitialShown(uint revenue)
{
KeewanoSDK.ReportAdRevenue("LevelComplete_Transition", revenue);
// NO ReportAdItemsGranted - player gets nothing
}
// ✅ CORRECT: Rewarded video (grants items)
void OnRewardedAdCompleted(uint revenue)
{
const string placement = "LevelFailed_Watch5Moves";
KeewanoSDK.ReportAdRevenue(placement, revenue);
Keewano.Item[] items = { new Keewano.Item("Moves", 5) };
KeewanoSDK.ReportAdItemsGranted(placement, items); // Player gets reward
}

Use Consistent Placement Names

Use the same placement name for both revenue and item grant methods:

void OnRewardedAdCompleted(uint revenue)
{
const string placement = "LevelFailed_WatchFor5Moves";
KeewanoSDK.ReportAdRevenue(placement, revenue);
Keewano.Item[] items = { new Keewano.Item("Moves", 5) };
KeewanoSDK.ReportAdItemsGranted(placement, items); // Same placement
}

Only Report Actually Granted Items

Only call ReportAdItemsGranted() when items are successfully added to the player's account:

void OnRewardedAdCompleted(uint revenue)
{
const string placement = "LevelFailed_Watch5Moves";
KeewanoSDK.ReportAdRevenue(placement, revenue);
Keewano.Item[] items = { new Keewano.Item("Moves", 5) };
bool itemsGranted = AddRewardToPlayerInventory(items);
if (itemsGranted)
{
// Only report if grant succeeded
KeewanoSDK.ReportAdItemsGranted(placement, items);
}
}

Revenue Must Be in USD Cents

Always track revenue in USD cents as provided by the ad network:

// If ad network reports $0.05, use 5 cents
KeewanoSDK.ReportAdRevenue("LevelComplete_Transition", 5);
// If ad network reports $0.12, use 12 cents
KeewanoSDK.ReportAdRevenue("MainMenu_TopBanner", 12);

String Parameter Limits

Placement IDs and item names are limited to 255 characters and will be trimmed if longer. Empty or null strings will skip the event.

See Also