Skip to main content

Migrating pricing

AdCP 3.0 renames pricing fields for clarity and separates hard constraints (prices the publisher enforces) from soft hints (historical data to help buyers bid).

What changed

v2 fieldv3 fieldChange type
fixed_ratefixed_priceRenamed
price_guidance.floorfloor_priceMoved to top level
The pricing_model, currency, pricing_option_id, and price_guidance percentiles (p25, p50, p75, p90) are unchanged.

Hard constraints vs soft hints

v3 makes an explicit semantic distinction: Hard constraints — publisher-enforced prices that cause bid rejection if violated:
  • fixed_price — the exact price per unit (fixed-price deals)
  • floor_price — minimum acceptable bid (auction pricing)
These are mutually exclusive. A pricing option has either fixed_price (guaranteed rate) or floor_price (auction with minimum), never both. Soft hints — historical percentiles to help buyers calibrate bids:
  • price_guidance.p25 — 25th percentile of recent winning bids
  • price_guidance.p50 — median of recent winning bids
  • price_guidance.p75 — 75th percentile of recent winning bids
  • price_guidance.p90 — 90th percentile of recent winning bids

Deal type mapping

These fields map to standard programmatic deal types:
Deal typeAdCP fieldDescription
Programmatic Guaranteed (PG)fixed_priceFixed CPM, guaranteed delivery
Preferred Dealfixed_priceFixed CPM, non-guaranteed (buyer has first look)
Private Marketplace (PMP)floor_priceAuction with minimum bid
Open AuctionNeitherNo floor or fixed price — open bidding
PG and Preferred Deals both use fixed_price. The distinction between them is in delivery commitment, not pricing — PG guarantees delivery volume while Preferred Deals offer first-look access without volume guarantees.

Fixed-price deals

v2:
{
  "pricing_option_id": "cpm_usd_fixed",
  "pricing_model": "cpm",
  "currency": "USD",
  "fixed_rate": 25.00
}
v3:
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/pricing-options/cpm-option.json",
  "pricing_option_id": "cpm_usd_fixed",
  "pricing_model": "cpm",
  "currency": "USD",
  "fixed_price": 25.00
}
Rename fixed_rate to fixed_price. No structural changes.

Auction pricing

v2:
{
  "pricing_option_id": "cpm_usd_auction",
  "pricing_model": "cpm",
  "currency": "USD",
  "price_guidance": {
    "floor": 10.00,
    "p50": 15.00,
    "p75": 18.00
  }
}
v3:
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/pricing-options/cpm-option.json",
  "pricing_option_id": "cpm_usd_auction",
  "pricing_model": "cpm",
  "currency": "USD",
  "floor_price": 10.00,
  "price_guidance": {
    "p50": 15.00,
    "p75": 18.00
  }
}
Two changes:
  1. price_guidance.floor moves to top-level floor_price
  2. price_guidance retains only the percentile hints

Price guidance object

The v3 price_guidance object contains only statistical percentiles:
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/pricing-options/price-guidance.json",
  "p25": 8.50,
  "p50": 15.00,
  "p75": 18.00,
  "p90": 22.00
}
All fields are optional. Publishers include whichever percentiles they can provide.

Flat-rate pricing

v2 (DOOH with parameters, no type discriminator):
{
  "pricing_option_id": "dooh_times_square",
  "pricing_model": "flat_rate",
  "currency": "USD",
  "fixed_rate": 50000.00,
  "parameters": {
    "duration_hours": 24,
    "sov_percentage": 100,
    "estimated_impressions": 1500000
  }
}
v3:
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/pricing-options/flat-rate-option.json",
  "pricing_option_id": "dooh_times_square",
  "pricing_model": "flat_rate",
  "currency": "USD",
  "fixed_price": 50000.00,
  "parameters": {
    "type": "dooh",
    "duration_hours": 24,
    "sov_percentage": 100,
    "estimated_impressions": 1500000
  }
}
Two changes:
  1. fixed_rate renames to fixed_price (same as other pricing models)
  2. parameters gains a required "type": "dooh" discriminator for DOOH inventory
Sponsorship flat_rate options that had no parameters in v2 continue to omit it in v3. Note that fixed_price is optional on flat-rate options — when absent, the flat-rate is auction-based (uncommon but valid for some DOOH inventory).

Minimum spend

v3 adds an optional min_spend_per_package field to all pricing options:
{
  "$schema": "https://adcontextprotocol.org/schemas/v3/pricing-options/cpm-option.json",
  "pricing_option_id": "cpm_usd_premium",
  "pricing_model": "cpm",
  "currency": "USD",
  "floor_price": 15.00,
  "min_spend_per_package": 5000.00,
  "price_guidance": {
    "p50": 22.00,
    "p75": 28.00
  }
}
This lets publishers declare minimum spend requirements per package.

Transition period handling

During migration, readers may encounter both old and new field names. Consider checking for both:
test=false
const price = option.fixed_price ?? option.fixed_rate;
const floor = option.floor_price ?? option.price_guidance?.floor;
v3 writers should only emit the new field names. Old field names (fixed_rate, price_guidance.floor) are not recognized by v3 schema validation. Remove the v2 fallback once all upstream sellers have migrated to v3 schemas.

Migration steps

1

Rename fixed_rate

Rename fixed_rate to fixed_price in all pricing options.
2

Move floor

Move floor from inside price_guidance to top-level floor_price.
3

Clean up price_guidance

Remove floor from price_guidance objects (only percentiles remain).
4

Update readers

Update code to look for new field names. Consider temporary fallback for both during transition.
5

Test auction bids

Verify floor enforcement works with the new field location.
6

Validate against schemas

Each pricing model has its own schema in /schemas/v3/pricing-options/.

Media products

How products declare pricing options, channels, and capabilities.

Related: Channels | Geo targeting | Creatives | Catalogs | Attribution | AdCP 3.0 overview