Trusted Arbiter
Compare CloudX bids with supported third-party bids in React Native apps
Trusted Arbiter compares a loaded CloudX bid with supported third-party bids and returns the selected platform. React Native support is backed by the CloudX native SDKs and supports CloudX, Unity LevelPlay, PubMatic, and custom publisher-supplied bid inputs.
Use loaded ad objects or ad info objects from each SDK to populate bid values:
import { CloudX, CloudXArbiterBid } from 'cloudx-react-native';
// cloudXAdInfo is the CloudXAdInfo object from a CloudX load callback.
// levelPlayAdInfo is the Unity LevelPlay ad info object.
// pubMaticPrice and pubMaticPartnerName come from the PubMatic/OpenWrap bid object.
const result = await CloudX.arbiter({
bids: [
CloudXArbiterBid.cloudX(cloudXAdInfo),
CloudXArbiterBid.levelPlay({
networkName: levelPlayAdInfo.adNetwork,
revenue: levelPlayAdInfo.revenue,
precision: levelPlayAdInfo.precision,
}),
CloudXArbiterBid.pubMatic({
price: pubMaticPrice,
partnerName: pubMaticPartnerName,
}),
],
});
console.log('Selected platform:', result.platform);If the arbiter service is unavailable, the SDK falls back to the highest comparable USD bid among the supplied supported bid inputs.
AdMob and Google Ad Manager
CloudX compares a loaded CloudX ad with a loaded AdMob or Google Ad Manager ad. AdMob and Ad Manager are separate demand sources, so both may bid in the same arbitration. This applies to publisher-managed mediation setups, including accounts described commercially as AdMob Pro; there is no separate AdMob Pro SDK API.
Google demand does not normally reveal the price of a loaded ad before it is shown, so there is no pre-bid price for the arbiter to compare against CloudX’s bid. CloudX estimates the bid price from the prior performance of similar ad units, so you do not need to supply a price. No pre-bid pricing API is required.
If your AdMob account exposes impression-level revenue data pre-bid, you can supply that exact price yourself instead of using the estimate — see Manual input with pre-bid ILRD below.
Report Google paid events back to CloudX (required)
Reporting Google’s impression-level revenue is a required part of the Trusted Arbiter AdMob and Ad Manager integration, not an optional analytics extra. After you show an AdMob or Ad Manager ad that won an arbitration, forward Google’s paid event into the CloudX SDK. Without those events CloudX never learns the realized price of Google demand, and the estimates it supplies to future arbitrations degrade.
Call CloudX.reportRevenueData() from your Google paid-event handler. Revenue is a currency-unit number, not micros — react-native-google-mobile-ads already reports event.value in currency units.
import { CloudX, CloudXRevenuePlatform, CloudXRevenuePrecision } from 'cloudx-react-native';
// event is the paid event from your Google ad (react-native-google-mobile-ads onPaid).
const reportGooglePaidEvent = (event, adFormat, adUnitId) =>
CloudX.reportRevenueData({
platform: CloudXRevenuePlatform.ADMOB, // use CloudXRevenuePlatform.GAM for Ad Manager
revenue: event.value,
adFormat,
currencyCode: event.currency,
precision: CloudXRevenuePrecision.ESTIMATED,
networkName: 'admob',
adUnitId,
});Report the ad unit id you passed to the arbiter bid so CloudX can attribute the realized price to the right ad unit. See Publisher-Reported Revenue Data for the full field reference and the precision mapping.
Create the bid from the ad unit id of the ad you loaded:
// networkName is optional; pass the winning ad source when you know it.
const adMobBid = CloudXArbiterBid.adMob({
adUnitId: adMobAdUnitId,
networkName: adMobNetworkName ?? 'admob',
});
// An Ad Manager ad unit id takes the form /NNNNNNN/placement/name.
const adManagerBid = CloudXArbiterBid.gam({
adUnitId: '/21775744923/example/interstitial',
});
const result = await CloudX.arbiter({
bids: [CloudXArbiterBid.cloudX(cloudXAdInfo), adMobBid, adManagerBid],
});
if (result.platform === 'ADMOB') {
// show the AdMob ad
} else if (result.platform === 'GAM') {
// show the Ad Manager ad
}A winning Google bid reports its own platform — the string 'ADMOB' or 'GAM'. You no longer need to inspect result.platformName to tell these sources apart, as you would for a custom bid.
Pass a blank ad unit id and the bid still builds rather than crashing your app, but it carries no usable identity: it is never priced and the server rejects it.
Manual input with pre-bid ILRD
Some AdMob accounts expose impression-level revenue data pre-bid: the ad value for the loaded ad is available at load time, before the ad is shown. This is a legacy, account-gated capability, so check with your Google account team whether it is enabled for your account. An exact per-impression price that you know before show is the one case where supplying your own price beats CloudX’s estimate.
Pass the pre-bid ad value as manualRevenuePerImpressionUSD and it overrides the estimate:
const adMobBid = CloudXArbiterBid.adMob({
adUnitId: adMobAdUnitId,
manualRevenuePerImpressionUSD: preBidPricePerImpressionUSD,
});The unit you receive depends on the native SDK underneath: the Google Mobile Ads SDK reports ad values in micros on Android and in currency units on iOS, so convert to a per-impression USD amount before passing it in.
How the value is treated:
0.0is a real price. It means this bid is worth nothing — not that the price is missing.- Negative and non-finite values are not prices, so they are treated as absent and logged.
- A blank ad unit id drops the manual price entirely, because a bid with no identity cannot be validated.
manualRevenuePerImpressionUSD is revenue for a single impression, in USD — not CPM, and a non-USD amount must be converted to USD first. See the Android and iOS pages for the per-platform unit-conversion rules for AdMob ad values.
Supported Formats
The arbiter is format-agnostic: it takes any loaded CloudX ad, and the same field mapping applies regardless of format. Banner, MREC, Interstitial, and Rewarded are all supported.
Banner and MREC
Auto-refresh conflicts with arbitration: a refresh can swap the ad after the arbiter has already picked a winner. Disable auto-refresh in the CloudX dashboard and call stopAutoRefresh() on the banner or MREC ad, and disable auto-refresh on the other arbitrated networks as well.
CloudXBannerAd.stopAutoRefresh(adUnitId);
// CloudXMRECAd.stopAutoRefresh(adUnitId);Only show the winning bid’s ad with showAd(adUnitId); keep the rest hidden with hideAd(adUnitId) (or never shown).
Recommended refresh flow: after the winner’s impression, load a new fill from the winning network only; retain non-winning ads that already have a fill and re-request just the unfilled networks; rerun the arbiter once responses return. Refresh the displayed ad every 20-30 seconds — shorter intervals decrease CPM performance.
Custom Bid Inputs
Use CloudXArbiterBid.custom() when you want Trusted Arbiter to compare CloudX with a third-party platform that does not have a dedicated bid factory.
const customBid = CloudXArbiterBid.custom({
platformName: 'my_mediation_platform',
networkName: 'winning_demand_source',
revenuePerImpressionUSD: 0.00125,
precision: 'EXACT',
extras: { ad_unit: 'third-party-ad-unit-id' },
});
const result = await CloudX.arbiter({
bids: [CloudXArbiterBid.cloudX(cloudXAdInfo), customBid],
});
console.log('Selected platform:', result.platform);When a custom bid wins, result.platform is 'CUSTOM' and result.platformName contains the platformName supplied on the bid. Pass revenuePerImpressionUSD as revenue for one impression in USD, not CPM. Use 'EXACT', 'ESTIMATED', 'PUBLISHER_DEFINED', or 'UNDEFINED' for precision to describe that revenue value. The React Native bid object requires networkName; pass '' if your source does not provide a winning-network name. A custom bid missing a non-blank platformName, revenue, or precision is dropped with a warning and does not compete.