Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
fbc4435
feat: add support for non-impression pricing models (CPM, CPCV, CPP, …
bokelley Oct 4, 2025
6c9a94d
feat: add DOOH support and measurement transparency, remove CPA/CPL
bokelley Oct 12, 2025
fdaa79a
docs: clarify CPP measurement requirements
bokelley Oct 12, 2025
436af1e
refactor: simplify measurement to use unstructured text fields
bokelley Oct 12, 2025
2cebb01
docs: simplify DOOH section and clarify details per feedback
bokelley Oct 12, 2025
af5c456
refactor: rename min_spend to min_spend_per_package for clarity
bokelley Oct 12, 2025
c884856
refactor: extract delivery metrics into shared schema
bokelley Oct 12, 2025
07374fa
fix: resolve pricing model validation and measurement requirements
bokelley Oct 12, 2025
f25c86b
docs: add pricing_option_id to all remaining examples
bokelley Oct 12, 2025
07e9fa9
docs: clarify reach/frequency measurement and pricing model parameters
bokelley Oct 12, 2025
b5e7e41
refactor: remove format_selection, require format_ids for all packages
bokelley Oct 12, 2025
1565aff
refactor: separate pricing option schemas per model for maintainability
bokelley Oct 12, 2025
256027c
refactor: split CPM fixed vs auction, remove auction support from oth…
bokelley Oct 12, 2025
0ab5654
fix: address schema review comments
bokelley Oct 12, 2025
1abbbad
fix: change package budget from object to number to avoid pacing redu…
bokelley Oct 12, 2025
6708130
refactor: simplify budget to plain number, remove currency redundancy
bokelley Oct 12, 2025
c11e277
Merge branch 'main' into non-impression-pricing
bokelley Oct 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
483 changes: 483 additions & 0 deletions docs/media-buy/advanced-topics/pricing-models.md

Large diffs are not rendered by default.

191 changes: 152 additions & 39 deletions docs/media-buy/product-discovery/media-products.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,90 @@ A **Product** is the core sellable unit in AdCP. This document details the Produ
- `description` (string, required)
- `formats` (list[Format], required): See [Creative Formats](../../creative/formats.md).
- `delivery_type` (string, required): Either `"guaranteed"` or `"non_guaranteed"`.
- `is_fixed_price` (bool, required): `true` if the price is fixed, `false` if it is auction-based.
- `cpm` (float, optional): The fixed Cost Per Mille. **Required** if `is_fixed_price` is `true`.
- `price_guidance` (PriceGuidance, optional): Pricing guidance for auction-based products. **Required** if `is_fixed_price` is `false`.
- `min_spend` (float, optional): Minimum budget requirement in USD.
- `pricing_options` (list[PricingOption], required): Array of available pricing models for this product. See [Pricing Models](#pricing-models).
- `measurement` (Measurement, optional): Included measurement capabilities. Common for retail media products.
- `creative_policy` (CreativePolicy, optional): Creative requirements and restrictions.
- `is_custom` (bool, optional): `true` if the product was generated for a specific brief.
- `expires_at` (datetime, optional): If `is_custom`, the time the product is no longer valid.

### Deprecated Fields

- `is_fixed_price` (bool): **DEPRECATED in v1.7.0** - Use `pricing_options` instead.
- `cpm` (float): **DEPRECATED in v1.7.0** - Use `pricing_options` instead.
- `min_spend` (float): **DEPRECATED in v1.7.0** - Use `pricing_options[].min_spend` instead.

### Pricing Models

AdCP supports two pricing models, determined by the `is_fixed_price` flag.
Publishers declare which pricing models they support for each product. Buyers select from the available options when creating a media buy. This approach supports:

- **Multiple pricing models per product** - Publishers can offer the same inventory via different pricing structures
- **Multi-currency support** - Publishers declare supported currencies; buyers must use a supported currency
- **Flexible pricing** - Support for CPM, CPCV, CPP (GRP-based), CPA, and more

#### Supported Pricing Models

#### Guaranteed, Fixed-Price Products
These products represent reserved inventory with a predictable price and delivery.
- `delivery_type`: `"guaranteed"`
- `is_fixed_price`: `true`
- `cpm`: A fixed float value (e.g., `45.00`).
- **CPM** (Cost Per Mille) - Cost per 1,000 impressions (traditional display)
- **CPC** (Cost Per Click) - Cost per click on the ad
- **CPCV** (Cost Per Completed View) - Cost per 100% video/audio completion
- **CPV** (Cost Per View) - Cost per view at publisher-defined threshold
- **CPA** (Cost Per Action) - Cost per conversion/acquisition
- **CPL** (Cost Per Lead) - Cost per lead generated
- **CPP** (Cost Per Point) - Cost per Gross Rating Point (TV/audio)
- **Flat Rate** - Fixed cost regardless of delivery volume

#### PricingOption Structure

Each pricing option includes:
```json
{
"pricing_option_id": "cpcv_usd_guaranteed",
"pricing_model": "cpcv",
"rate": 0.15,
"currency": "USD",
"is_fixed": true,
"parameters": {
"view_threshold": 1.0
},
"min_spend_per_package": 5000
}
```

For auction-based pricing (`is_fixed: false`), include `price_guidance`:
```json
{
"pricing_option_id": "cpm_usd_auction",
"pricing_model": "cpm",
"currency": "USD",
"is_fixed": false,
"price_guidance": {
"floor": 10.00,
"p25": 12.50,
"p50": 15.00,
"p75": 18.00,
"p90": 22.00
}
}
```

#### Non-Guaranteed, Variable-Price Products
These products represent inventory available in an auction. The final price is not fixed.
- `delivery_type`: `"non_guaranteed"`
- `is_fixed_price`: `false`
- `price_guidance`: A `PriceGuidance` object that helps the buyer make an informed bid.
#### Delivery Measurement (Required)

**Example `PriceGuidance`:**
All products MUST declare their measurement provider:
```json
{
"floor": 10.00,
"p25": 12.50,
"p50": 15.00,
"p75": 18.00,
"p90": 22.00
"delivery_measurement": {
"provider": "Google Ad Manager with IAS viewability verification",
"notes": "MRC-accredited viewability. 50% in-view for 1s display / 2s video."
}
}
```

Common provider examples:
- `"Google Ad Manager with IAS viewability"`
- `"Nielsen DAR for P18-49 demographic measurement"`
- `"Geopath DOOH traffic counts updated monthly"`
- `"Comscore vCE for video completion tracking"`
- `"Self-reported impressions from proprietary ad server"`

### Measurement Object

For products that include measurement (common in retail media):
Expand Down Expand Up @@ -80,53 +128,118 @@ A server can offer a general catalog, but it can also return:

## Product Examples

### Standard Product
### Standard CTV Product (Multiple Pricing Options)
```json
{
"product_id": "connected_tv_prime",
"name": "Connected TV - Prime Time",
"description": "Premium CTV inventory 8PM-11PM",
"format_ids": ["video_standard"],
"format_ids": ["video_15s", "video_30s"],
"delivery_type": "guaranteed",
"is_fixed_price": true,
"cpm": 45.00
"pricing_options": [
{
"pricing_option_id": "cpm_usd_guaranteed",
"pricing_model": "cpm",
"rate": 45.00,
"currency": "USD",
"is_fixed": true,
"min_spend_per_package": 10000
},
{
"pricing_option_id": "cpcv_usd_guaranteed",
"pricing_model": "cpcv",
"rate": 0.18,
"currency": "USD",
"is_fixed": true,
"min_spend_per_package": 10000
},
{
"pricing_option_id": "cpp_usd_p18-49",
"pricing_model": "cpp",
"rate": 250.00,
"currency": "USD",
"is_fixed": true,
"parameters": {
"demographic": "P18-49",
"min_points": 50
},
"min_spend_per_package": 12500
}
],
"delivery_measurement": {
"provider": "Nielsen DAR for P18-49 demographic measurement",
"notes": "Panel-based measurement for GRP delivery. Impressions measured via Comscore vCE."
}
}
```

### Custom Product
### Auction-Based Display Product
```json
{
"product_id": "custom_abc123",
"name": "Custom - Gaming Enthusiasts",
"description": "Custom audience package for gaming campaign",
"format_ids": ["display_300x250"],
"format_ids": ["display_300x250", "display_728x90"],
"delivery_type": "non_guaranteed",
"is_fixed_price": false,
"price_guidance": {
"floor": 5.00,
"p50": 8.00,
"p75": 12.00
"pricing_options": [
{
"pricing_option_id": "cpm_usd_auction",
"pricing_model": "cpm",
"currency": "USD",
"is_fixed": false,
"price_guidance": {
"floor": 5.00,
"p50": 8.00,
"p75": 12.00
}
},
{
"pricing_option_id": "cpc_usd_auction",
"pricing_model": "cpc",
"currency": "USD",
"is_fixed": false,
"price_guidance": {
"floor": 0.50,
"p50": 1.20,
"p75": 2.00
}
}
],
"delivery_measurement": {
"provider": "Google Ad Manager with IAS viewability",
"notes": "MRC-accredited viewability. 50% in-view for 1s display."
},
"is_custom": true,
"expires_at": "2024-02-15T00:00:00Z"
"expires_at": "2025-02-15T00:00:00Z"
}
```

### Retail Media Product
### Retail Media Product with Measurement
```json
{
"product_id": "albertsons_pet_category_offsite",
"name": "Pet Category Shoppers - Offsite Display & Video",
"description": "Target Albertsons shoppers who have purchased pet products in the last 90 days. Reach them across premium display and video inventory.",
"format_ids": [
"display_300x250",
"display_728x90",
"video_15s_vast"
"display_728x90",
"video_15s"
],
"delivery_type": "guaranteed",
"is_fixed_price": true,
"cpm": 13.50,
"min_spend": 10000,
"pricing_options": [
{
"pricing_option_id": "cpm_usd_guaranteed",
"pricing_model": "cpm",
"rate": 13.50,
"currency": "USD",
"is_fixed": true,
"min_spend_per_package": 10000
}
],
"delivery_measurement": {
"provider": "Self-reported impressions from proprietary ad server",
"notes": "Impressions counted per IAB guidelines. Viewability measured via IAS."
},
"measurement": {
"type": "incremental_sales_lift",
"attribution": "deterministic_purchase",
Expand Down
Loading