From 9ee10331210232e817aa53b42ec723ea66740efe Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Wed, 11 Feb 2026 13:08:05 -0500 Subject: [PATCH] feat: Add TIME pricing model for duration-based sponsorships (#930) Add a new `time` pricing model that charges per time unit (hour, day, week, or month), enabling self-serve sponsorship buys where total cost scales with campaign duration. This complements `flat_rate` which represents a fixed total cost regardless of duration. Co-Authored-By: Claude Opus 4.6 --- .changeset/add-time-pricing.md | 5 ++ .../advanced-topics/pricing-models.mdx | 53 ++++++++++++++- .../product-discovery/media-products.mdx | 6 +- .../schemas/source/core/pricing-option.json | 3 + .../schemas/source/enums/pricing-model.json | 6 +- static/schemas/source/index.json | 4 ++ .../source/pricing-options/time-option.json | 68 +++++++++++++++++++ 7 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 .changeset/add-time-pricing.md create mode 100644 static/schemas/source/pricing-options/time-option.json diff --git a/.changeset/add-time-pricing.md b/.changeset/add-time-pricing.md new file mode 100644 index 0000000000..b812a810c0 --- /dev/null +++ b/.changeset/add-time-pricing.md @@ -0,0 +1,5 @@ +--- +"adcontextprotocol": minor +--- + +Add TIME pricing model for sponsorship-based advertising where price scales with campaign duration. Supports hour, day, week, and month time units with optional min/max duration constraints. diff --git a/docs/media-buy/advanced-topics/pricing-models.mdx b/docs/media-buy/advanced-topics/pricing-models.mdx index 7469c6f079..9d39a658b1 100644 --- a/docs/media-buy/advanced-topics/pricing-models.mdx +++ b/docs/media-buy/advanced-topics/pricing-models.mdx @@ -1,7 +1,7 @@ --- title: Pricing Models -description: Comprehensive guide to AdCP's flexible pricing models including CPM, CPCV, CPP, CPC, CPA, and DOOH support -keywords: [pricing models, CPM, CPCV, CPP, CPC, CPA, CPV, GRP, video pricing, DOOH, share of voice, measurement, conversions] +description: Comprehensive guide to AdCP's flexible pricing models including CPM, CPCV, CPP, CPC, CPA, Time, and DOOH support +keywords: [pricing models, CPM, CPCV, CPP, CPC, CPA, CPV, GRP, video pricing, DOOH, share of voice, measurement, conversions, time-based, sponsorship, daily rate] --- @@ -310,6 +310,54 @@ Buyers should verify the measurement provider meets their campaign requirements --- +### Time (Cost Per Time Unit) +**Cost per time unit** - Rate scales with campaign duration, enabling self-serve sponsorships. + +**Use Cases**: Homepage takeovers, section sponsorships, premium placements where price depends on booking duration + +**Example**: +```json +{ + "$schema": "https://adcontextprotocol.org/schemas/v2/pricing-options/time-option.json", + "pricing_option_id": "time_usd_daily", + "pricing_model": "time", + "fixed_price": 50000.00, + "currency": "USD", + "parameters": { + "time_unit": "day", + "min_duration": 1, + "max_duration": 30 + } +} +``` + +**Billing**: Cost = `fixed_price` x number of `time_unit`s in the campaign flight. For example, a 3-day campaign at $50,000/day = $150,000 total. + +**Parameters**: +- `time_unit` (required): `"hour"`, `"day"`, `"week"`, or `"month"` +- `min_duration` (optional): Minimum booking duration in time units +- `max_duration` (optional): Maximum booking duration in time units + +**Time Unit Calculation**: + +| Time Unit | Calculation | +|-----------|-------------| +| `hour` | rate x hours in flight | +| `day` | rate x calendar days in flight | +| `week` | rate x weeks (seller-defined rounding) | +| `month` | rate x months (seller-defined pro-rating) | + +**Comparison with Flat Rate**: + +| Aspect | Flat Rate | Time | +|--------|-----------|------| +| Semantics | Fixed total cost | Rate x duration | +| `fixed_price` means | Total campaign cost | Cost per time unit | +| Buyer flexibility | Must negotiate duration | Self-serve any duration | +| Use case | Fixed sponsorships | Scalable sponsorships | + +--- + ## Digital Out-of-Home (DOOH) Pricing DOOH advertising uses existing pricing models—typically **CPM** or **flat_rate**—with optional parameters to describe the inventory allocation. @@ -459,6 +507,7 @@ Different pricing models report different primary metrics: | CPC | clicks | impressions, ctr, spend | | CPA | conversions | conversion_value, cost_per_acquisition, roas, spend | | Flat Rate | N/A | impressions, reach, frequency | +| Time | N/A | impressions, reach, frequency | ## Example: Multi-Model CTV Product diff --git a/docs/media-buy/product-discovery/media-products.mdx b/docs/media-buy/product-discovery/media-products.mdx index 34416c54a3..240c09e597 100644 --- a/docs/media-buy/product-discovery/media-products.mdx +++ b/docs/media-buy/product-discovery/media-products.mdx @@ -7,7 +7,7 @@ A **Product** is the core sellable unit in AdCP. This document details the Produ **Pricing Models** -Products declare which pricing models they support. Buyers select a specific pricing option when creating media buys. See the complete [Pricing Models Guide](/docs/media-buy/advanced-topics/pricing-models) for details on CPM, CPCV, CPP, CPC, vCPM, and flat rate pricing. +Products declare which pricing models they support. Buyers select a specific pricing option when creating media buys. See the complete [Pricing Models Guide](/docs/media-buy/advanced-topics/pricing-models) for details on CPM, CPCV, CPP, CPC, CPA, vCPM, flat rate, and time-based pricing. ## The Product Model @@ -41,10 +41,10 @@ Publishers declare which pricing models they support for each product. Buyers se - **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 +- **CPA** (Cost Per Acquisition) - Cost per conversion event (purchase, lead, signup, etc.) - **CPP** (Cost Per Point) - Cost per Gross Rating Point (TV/audio) - **Flat Rate** - Fixed cost regardless of delivery volume +- **Time** - Cost per time unit (day, week, month) that scales with campaign duration #### PricingOption Structure diff --git a/static/schemas/source/core/pricing-option.json b/static/schemas/source/core/pricing-option.json index b7062ebce4..62ff37e847 100644 --- a/static/schemas/source/core/pricing-option.json +++ b/static/schemas/source/core/pricing-option.json @@ -27,6 +27,9 @@ }, { "$ref": "/schemas/pricing-options/flat-rate-option.json" + }, + { + "$ref": "/schemas/pricing-options/time-option.json" } ] } diff --git a/static/schemas/source/enums/pricing-model.json b/static/schemas/source/enums/pricing-model.json index 273c0aa539..7a92e2c262 100644 --- a/static/schemas/source/enums/pricing-model.json +++ b/static/schemas/source/enums/pricing-model.json @@ -12,7 +12,8 @@ "cpv", "cpp", "cpa", - "flat_rate" + "flat_rate", + "time" ], "enumDescriptions": { "cpm": "Cost Per Mille - cost per 1,000 impressions", @@ -22,6 +23,7 @@ "cpv": "Cost Per View - cost per view at publisher-defined threshold (e.g., 50% completion)", "cpp": "Cost Per Point - cost per Gross Rating Point or Target Rating Point (TV/audio)", "cpa": "Cost Per Acquisition - cost per conversion event (purchase, lead, signup, etc.)", - "flat_rate": "Flat Rate - fixed cost regardless of delivery volume (sponsorships, takeovers)" + "flat_rate": "Flat Rate - fixed cost regardless of delivery volume (sponsorships, takeovers)", + "time": "Time - cost per time unit (hour, day, week, or month) that scales with campaign duration" } } diff --git a/static/schemas/source/index.json b/static/schemas/source/index.json index 4c29ae6417..81c4533e29 100644 --- a/static/schemas/source/index.json +++ b/static/schemas/source/index.json @@ -552,6 +552,10 @@ "flat-rate-option": { "$ref": "/schemas/pricing-options/flat-rate-option.json", "description": "Flat rate pricing for DOOH and sponsorships - supports fixed rate and auction modes" + }, + "time-option": { + "$ref": "/schemas/pricing-options/time-option.json", + "description": "Time-based pricing - cost per time unit (hour, day, week, month) that scales with campaign duration" } } }, diff --git a/static/schemas/source/pricing-options/time-option.json b/static/schemas/source/pricing-options/time-option.json new file mode 100644 index 0000000000..e7a876232b --- /dev/null +++ b/static/schemas/source/pricing-options/time-option.json @@ -0,0 +1,68 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "/schemas/pricing-options/time-option.json", + "title": "Time-Based Pricing Option", + "description": "Cost per time unit (hour, day, week, or month) - rate scales with campaign duration. If fixed_price is present, it's fixed pricing. If absent, it's auction-based.", + "type": "object", + "properties": { + "pricing_option_id": { + "type": "string", + "description": "Unique identifier for this pricing option within the product" + }, + "pricing_model": { + "type": "string", + "const": "time", + "description": "Cost per time unit - rate scales with campaign duration" + }, + "currency": { + "type": "string", + "description": "ISO 4217 currency code", + "pattern": "^[A-Z]{3}$", + "examples": ["USD", "EUR", "GBP", "JPY"] + }, + "fixed_price": { + "type": "number", + "description": "Cost per time unit. If present, this is fixed pricing. If absent, auction-based.", + "minimum": 0 + }, + "floor_price": { + "type": "number", + "description": "Minimum acceptable bid per time unit for auction pricing (mutually exclusive with fixed_price). Bids below this value will be rejected.", + "minimum": 0 + }, + "price_guidance": { + "description": "Optional pricing guidance for auction-based bidding", + "$ref": "/schemas/pricing-options/price-guidance.json" + }, + "parameters": { + "type": "object", + "description": "Time-based pricing parameters", + "required": ["time_unit"], + "properties": { + "time_unit": { + "type": "string", + "enum": ["hour", "day", "week", "month"], + "description": "The time unit for pricing. Total cost = fixed_price × number of time_units in the campaign flight." + }, + "min_duration": { + "type": "integer", + "minimum": 1, + "description": "Minimum booking duration in time_units" + }, + "max_duration": { + "type": "integer", + "minimum": 1, + "description": "Maximum booking duration in time_units. Must be >= min_duration when both are present." + } + }, + "additionalProperties": true + }, + "min_spend_per_package": { + "type": "number", + "description": "Minimum spend requirement per package using this pricing option, in the specified currency", + "minimum": 0 + } + }, + "required": ["pricing_option_id", "pricing_model", "currency", "parameters"], + "additionalProperties": true +}