Skip to main content
Some ad servers can execute a campaign but can’t expose the wholesale commercial data — the price you’ll accept and how much inventory is available. Google Ad Manager is the common case: many publishers won’t grant access to run a pricing query against their network, so products sync with no price and can’t be sold. The wholesale avails & pricing module closes that gap. You upload a small, structured feed — one row per ad unit (or placement) — giving your percentile CPMs and monthly availability. The platform validates it deterministically, stores it with provenance and a freshness date, and prices your buyer-facing products from it. Your ad server still handles execution; you supply only the commercial data it can’t share.
This is a storefront-operator capability, and it’s opt-in per source: it only applies to sources you’ve explicitly enabled it on. A source that is simply unpriced is not asked for a feed — only sources whose ad server can’t expose pricing use this path.
You never need an internal Scope3 product id. Your ad-server selector — the GAM ad unit or placement id — is the key. It’s the same id the selector browser shows you, so it maps cleanly to the products it backs.

What you supply

One row per ad-server selector × country. Column order and header capitalization don’t matter; CSV and XLSX both work.

Copy the CSV template

Use the embedded template below. Copy the header and sample rows into a CSV or XLSX file, then replace them with your ad-unit or placement ids, countries, CPM percentiles, dates, and monthly availability.
An ad-unit export or targeting map is not enough by itself. Those files are useful for the ad_server_selector column, but the upload also needs country, currency, CPM percentiles, effective dates, and a source version.

Required columns

ColumnMeaning
ad_server_selectorThe ad server’s stable selector id. For GAM this is the numeric Ad Unit ID (GAM → Inventory → Ad units) or a placement id.
countryA country name (United States, Germany, …), an ISO-3166 alpha-2 code (US, GB, AU), or GLOBAL. One row per selector per country.
currencyA real ISO-4217 currency code (e.g. USD, EUR, GBP). Reserved or placeholder codes such as ZZZ are rejected.
pricing_modelcpm.
p25_cpm, p50_cpm, p75_cpmYour clearing-price distribution: the 25th, 50th (median), and 75th percentile CPMs. Non-decreasing (p25 ≤ p50 ≤ p75). p25/p50 may be 0 (common for run-of-network display that clears at $0 part of the time); p75 must be greater than 0 so the row has a sellable price. Scientific notation (e.g. 7.7e-7) is accepted. Values above 1,000 are rejected as likely unit mistakes or fat fingers; contact Scope3 if a CPM above that limit is intentional.
effective_start_date, effective_end_dateThe window this pricing is valid for, ISO YYYY-MM-DD (end after start).
source_versionAny label for the file version, e.g. 2026-Q3.

Optional columns

ColumnMeaning
selector_typead_unit or placement. If omitted, the upload assumes ad_unit.
selector_nameHuman name of the ad unit, for verification (e.g. Run of Site — Display).
monthly_impressionsMonthly available impressions for this selector and country, whole number. (available_impressions / avails are also accepted.) Values above 100,000,000,000 per selector/country/month are rejected as likely unit mistakes; split the row or contact Scope3 if that volume is intentional.
Any other columns are preserved as metadata and ignored by validation.

How pricing is used

You give the platform a price distribution per country, not a single number:
  • The floor is derived from p25 — the platform will not sell below your 25th-percentile clearing price. Where p25 is 0 (run-of-network display that clears at $0 part of the time), the floor is 0 and the product sells at open auction, guided by p50/p75.
  • p50 and p75 are guidance for pricing above the floor. The platform does not anchor the sell price on a percentile — the buyer’s agent chooses a price within your distribution.
  • Your per-country prices and availability stay per-country. Your ad units map to the buyer-facing products (a product can span several ad units), and each product carries a per-country forecast: the available impressions and the expected CPM range for each country you priced. A buyer targeting the US sees your US price and avails; one targeting the UK sees the UK’s — without splitting your catalog into a separate product per country.
Inventory that can’t be bought isn’t offered. A country is shown only if a buyer could actually purchase it: if its available impressions are too thin to reach your minimum line item without an unrealistic CPM, that country is left off the product. Your minimum line item — the smallest line-item spend worth booking — is a storefront setting; the platform reads it from your ad server when it can, otherwise you set it.

Example feed

Copy this template into a CSV file:
ad_server_selector,selector_type,selector_name,country,currency,pricing_model,p25_cpm,p50_cpm,p75_cpm,monthly_impressions,effective_start_date,effective_end_date,source_version
111942652,ad_unit,Run of Site Display,US,USD,cpm,4.00,6.00,9.00,12000000,2026-07-01,2026-09-30,2026-Q3
111942652,ad_unit,Run of Site Display,GB,USD,cpm,3.00,5.00,8.00,3000000,2026-07-01,2026-09-30,2026-Q3
289471120,ad_unit,6s 15s Video Pre-roll,GLOBAL,USD,cpm,10.00,14.00,20.00,4500000,2026-07-01,2026-09-30,2026-Q3

Uploading

All examples use the storefront base URL:
export BASE=https://api.interchange.io/api/v2/storefront
export SCOPE3_API_KEY=scope3_<your_api_key>

1. Enable the module on your source

curl -X POST "$BASE/inventory-sources/$SOURCE_ID/wholesale-pricing/module" \
  -H "Authorization: Bearer $SCOPE3_API_KEY"

2. Preview

Submit rows (or paste CSV) without confirmed to see exactly what will be accepted or rejected before anything is written:
curl -X POST "$BASE/inventory-sources/$SOURCE_ID/wholesale-pricing" \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "csvText": "ad_server_selector,selector_type,country,currency,pricing_model,p25_cpm,p50_cpm,p75_cpm,effective_start_date,effective_end_date,source_version\n111942652,ad_unit,US,USD,cpm,4.00,6.00,9.00,2026-07-01,2026-09-30,2026-Q3" }'
The response reports acceptedRowCount, rejectedRowCount, and a per-row rejected list — each with the row, the column, and why (for example, a missing p50_cpm, a fake currency code, a p25 > p50 ordering error, an implausible outlier, or a non-ISO date).

3. Commit

When the preview is clean, re-submit with confirmed: true. A commit is rejected if any row is still rejected — fix and re-preview first. Each commit fully replaces the prior feed for the source, so a selector you drop from the new file stops being sold. A successful commit refreshes the source’s storefront products automatically; no separate catalog refresh is required. The response’s catalogRefresh fields report whether cache invalidation and the immediate warm completed. A refresh failure does not roll back an accepted feed.
curl -X POST "$BASE/inventory-sources/$SOURCE_ID/wholesale-pricing" \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "confirmed": true, "csvText": "..." }'
An .xlsx or .csv file can be uploaded directly to POST /inventory-sources/$SOURCE_ID/wholesale-pricing/upload as multipart form-data (field file, plus confirmed=true to commit).

Readiness and freshness

Wholesale products on an enabled source aren’t shown to buyers until current pricing exists — a missing, invalid, or stale feed keeps them off the market. The most recent accepted feed goes stale after ~35 days; once stale, your wholesale products come off the market until you upload a refreshed file, and going live is blocked until a current feed exists. Keeping the feed current is what keeps your wholesale products sellable. When a source is marked for manual wholesale pricing, pricing-related source health asks for a pricing upload instead of asking you to reconnect ad-server pricing access. This applies only to wholesale pricing: your ad-server connection still needs to be connected for inventory sync, trafficking, delivery, and reporting.