Skip to main content
Media buys represent the complete lifecycle of advertising campaigns in AdCP. The AdCP:Buy protocol provides a unified interface for managing media buys across multiple advertising platforms, from initial campaign creation through ongoing optimization and updates.

Overview

AdCP’s media buy management provides a unified interface for:
  • Campaign Creation from discovered products and packages
  • Lifecycle Management through all campaign states
  • Budget and Targeting Updates for ongoing optimization
  • Cross-Platform Orchestration with consistent operations
  • Asynchronous Operations with human-in-the-loop support

The Media Buy Lifecycle Phases

1. Creation Phase

Transform discovered products into active advertising campaigns using create_media_buy:
  • Package Configuration: Combine products with formats, targeting, and budget
  • Campaign Setup: Define timing, overall budget, and brand context
  • Validation & Approval: Automated checks with optional human approval
  • Platform Deployment: Campaign creation across advertising platforms
This phase may involve:
  • Immediate creation with active status (instant activation)
  • Deferred creation with pending_activation status (awaiting platform setup)
  • Human approval workflow via pending_manual task status (see Asynchronous Operations)
  • Permission requirements via pending_permission task status (see Asynchronous Operations)
pending_manual and pending_permission are task-level statuses from the human-in-the-loop queue — they describe whether the operation requires approval, not the media buy’s lifecycle state. The media buy itself enters pending_activation or active once the operation completes.
Platform Mapping:
  • Google Ad Manager: Creates an Order with LineItems
  • Kevel: Creates a Campaign with Flights
  • Triton Digital: Creates a Campaign with Flights

2. Creative Upload Phase

Once created, the media buy requires creative assets via sync_creatives:
  • Platform-specific format support (video, audio, display, custom)
  • Validation and policy review for creative compliance
  • Assignment to specific packages for targeted delivery

3. Activation & Delivery Phase

Monitor and manage active campaigns:
  • Status Tracking: Campaign transitions from pending_activation to active
  • Creative Assignment: Attach assets from the creative library
  • Delivery Monitoring: Track pacing and performance metrics with get_media_buy_delivery
  • Issue Resolution: Handle approval delays and platform issues

4. Optimization & Reporting Phase

Ongoing performance monitoring and data-driven campaign optimization using AdCP’s comprehensive reporting tools. Key activities include:
  • Performance monitoring with real-time and historical analytics
  • Campaign optimization through budget reallocation and targeting refinement
  • Dimensional reporting using the same targeting dimensions for consistent analysis
  • AI-driven insights through performance feedback loops
For complete details on optimization strategies, performance monitoring, standard metrics, and best practices, see Optimization & Reporting.

Key Concepts

Media Buy Structure

A media buy contains:
  • Campaign metadata (buyer reference, brand, timing)
  • Overall budget with currency and pacing preferences
  • Multiple packages representing different targeting/creative combinations
  • Status tracking through creation, approval, and execution phases

Package types

Three distinct types represent a package at different lifecycle stages:
TypeSchemaUsed inPurpose
PackageRequestmedia-buy/package-request.jsoncreate_media_buy requestWhat the buyer sends to create a package
Packagecore/package.jsoncreate_media_buy success responseWhat the seller returns after creation (confirmed state)
PackageStatusinline in media-buy/get-media-buys-response.jsonget_media_buys responseDelivery/reporting view — includes creative approvals and optional snapshot
When implementing create_media_buy, send a PackageRequest. The response returns Package objects. When calling get_media_buys to check status or delivery, the response contains PackageStatus items with delivery-specific fields.

Package model

Packages are the building blocks of media buys:
  • Single product selection from discovery results - when you buy a product, you buy the entire product (unless using property targeting)
  • Creative formats to be provided for this package
  • Targeting overlays for refinements including geo restrictions, frequency caps, and property targeting
  • Budget allocation as portion of overall media buy budget
  • Pricing option selection from product’s available pricing models
  • Pacing strategy for budget delivery (even, asap, or front_loaded)
  • Bid price for auction-based pricing models (when applicable)
  • Flight scheduling with optional start_time and end_time per package

Flight scheduling

Packages can have independent flight dates within a media buy. This enables weekly (or any cadence) flight patterns where the same product appears as multiple packages with different date windows and budgets.
  • Inheritance: When start_time or end_time is omitted on a package, the package inherits the media buy’s dates. Each field inherits independently — a package may specify start_time while inheriting the media buy’s end_time, or vice versa.
  • Validation: Package dates must fall within the parent media buy’s date range. Sellers SHOULD reject packages where start_time is equal to or after end_time.
  • Overlapping flights: Multiple packages for the same product may have overlapping date ranges. Each package maintains its own independent budget.
  • Format: Plain ISO 8601 date-time — packages do not support "asap"
Weekly flights example: A display campaign running March 1-31, broken into weekly $2,000 flights with a dark period for lift measurement (abbreviated — see create_media_buy for the full request shape):
{
  "start_time": "2026-03-01T00:00:00Z",
  "end_time": "2026-03-31T23:59:59Z",
  "packages": [
    {
      "product_id": "prod_premium_display",
      "pricing_option_id": "cpm_usd_fixed",
      "budget": 2000,
      "start_time": "2026-03-01T00:00:00Z",
      "end_time": "2026-03-07T23:59:59Z"
    },
    {
      "product_id": "prod_premium_display",
      "pricing_option_id": "cpm_usd_fixed",
      "budget": 2000,
      "start_time": "2026-03-08T00:00:00Z",
      "end_time": "2026-03-14T23:59:59Z"
    },
    {
      "product_id": "prod_premium_display",
      "pricing_option_id": "cpm_usd_fixed",
      "budget": 2000,
      "start_time": "2026-03-22T00:00:00Z",
      "end_time": "2026-03-28T23:59:59Z"
    }
  ]
}
Week 3 is intentionally omitted — a dark period for lift measurement. Each flight gets its own budget, so pacing and spend are controlled per week. To adjust mid-campaign, update individual package budgets without affecting other flights.

Creative Assignment and Placement Targeting

When a product defines multiple placements, buyers can assign different creatives to different placements while still purchasing the entire product. Key Points:
  • Packages buy the entire product - you cannot target individual placements at the package level
  • Placement targeting happens only at the creative assignment level
  • Creatives without placement_ids run on all placements in the product
Example Workflow:
  1. Product defines placements:
{
  "product_id": "news_site_premium",
  "placements": [
    {
      "placement_id": "homepage_banner",
      "name": "Homepage Banner",
      "format_ids": [{"agent_url": "...", "id": "display_728x90"}]
    },
    {
      "placement_id": "article_sidebar",
      "name": "Article Sidebar",
      "format_ids": [{"agent_url": "...", "id": "display_300x250"}]
    }
  ]
}
  1. Buyer creates package (buys entire product) and assigns different creatives to each placement:
{
  "product_id": "news_site_premium",
  "creative_assignments": [
    {
      "creative_id": "creative_homepage",
      "placement_ids": ["homepage_banner"]
    },
    {
      "creative_id": "creative_article",
      "placement_ids": ["article_sidebar"]
    }
  ]
}
  1. Or assign one creative to all placements (omit placement_ids):
{
  "product_id": "news_site_premium",
  "creative_assignments": [
    {
      "creative_id": "creative_universal"
      // No placement_ids = runs on all placements in the product
    }
  ]
}
Use Cases:
  • Format-specific placements: Homepage takes 728x90, sidebar takes 300x250
  • A/B testing: Test different creatives on different placements
  • Geo-targeting: Different creatives for different DOOH screen locations
  • Dayparting: Different creatives for morning vs evening placements
See Media Products - Placements for complete placement documentation.

Property Targeting

For products with property_targeting_allowed: true, buyers can specify which properties to target using property_list in the targeting_overlay:
{
  "product_id": "flexible_news_network",
  "targeting_overlay": {
    "property_list": {
      "agent_url": "https://governance.example.com",
      "list_id": "pl_brand_safe_2024"
    }
  },
  "budget": 50000
}
Key Points:
  • Only valid for products with property_targeting_allowed: true
  • The package runs on the intersection of the product’s publisher_properties and the property_list
  • If omitted, the package runs on all of the product’s properties
  • If provided for a product with property_targeting_allowed: false, the seller SHOULD return a validation error
See Media Products - Property Targeting for more on how products declare targeting flexibility.

Lifecycle States

Media buys progress through defined states with explicit transition rules:
create_media_buy ──┬──▶ pending_activation ──▶ active
                   │                              ▲
                   └──▶ active                    │ resume
                        │    ▲                    │
               (pause)  │    │ (resume)           │
                        ▼    │                    │
                       paused ────────────────────┘

          active ───────┼──────────────▶ completed (terminal)
          paused ───────┘                ▲ flight ends / goal met / budget exhausted

pending_activation ──▶ rejected (terminal)  — seller rejects during setup

Any non-terminal ──── update(canceled: true) ──▶ canceled (terminal)
  • pending_activation: Created, awaiting platform setup or creative upload
  • active: Running and delivering impressions
  • paused: Temporarily stopped by buyer or seller
  • completed: Finished — flight ended, goal met, or budget exhausted
  • rejected: Declined by the seller (terminal)
  • canceled: Terminated before natural completion. Check cancellation.canceled_by to determine whether the buyer or seller initiated.
Order confirmation: A successful create_media_buy response constitutes order confirmation. The response includes confirmed_at with the confirmation timestamp. Terminal states: completed, rejected, and canceled are terminal — no transitions out. Sellers MUST reject updates to terminal-state media buys with error code INVALID_STATE. Discovering valid actions: The get_media_buys response includes valid_actions for each media buy — a list of actions the buyer can perform in the current state. Agents SHOULD use this instead of hardcoding the state machine:
{
  "media_buys": [{
    "media_buy_id": "mb_12345",
    "status": "active",
    "revision": 3,
    "valid_actions": ["pause", "cancel", "update_budget", "update_dates", "update_packages", "add_packages", "sync_creatives"],
    "packages": [...]
  }]
}
Revision tracking: Each media buy carries a revision number that increments on every change. Pass revision in update_media_buy for optimistic concurrency — the seller rejects with CONFLICT if the revision has changed since you last read it.

Core Operations

Creating Media Buys

The creation process handles:
  • Product validation ensuring discovered products are still available
  • Format compatibility checking creative requirements across packages
  • Budget distribution allocating spend across multiple packages
  • Platform coordination creating campaigns across multiple ad servers

Updating Media Buys

The operation type for each package is structurally explicit — determined by where it appears in the request:
OperationRequest fieldExample
Newnew_packages[]Add a line item mid-flight
Changedpackages[]Adjust budget, targeting, dates, creatives
Canceledpackages[] with canceled: trueCancel a line item (irreversible)
Campaign-level modifications include:
  • Budget adjustments for increased/decreased spend
  • Targeting updates to refine audience parameters
  • Schedule changes for extended or shortened campaign timing
  • Pause/resume for campaign-level delivery control

Canceling Media Buys

Cancel a media buy or individual package using update_media_buy with canceled: true:
{
  "media_buy_id": "mb_12345",
  "canceled": true,
  "cancellation_reason": "Campaign strategy changed"
}
Cancel a single package within an active media buy:
{
  "media_buy_id": "mb_12345",
  "packages": [
    {
      "package_id": "pkg_67890",
      "canceled": true,
      "cancellation_reason": "Underperforming — reallocating budget"
    }
  ]
}
  • Cancellation is irreversible — canceled media buys and packages cannot be reactivated
  • Sellers MAY reject cancellation with error code NOT_CANCELLABLE (e.g., contractual obligations, in-production print orders)
  • A canceled package does not affect other packages in the same media buy. When all packages are canceled, sellers that support add_packages allow the buyer to add new packages via new_packages in update_media_buy. Otherwise, the buyer SHOULD explicitly cancel the media buy.
  • Sellers MAY cancel media buys or packages (e.g., policy violation, inventory withdrawal). Seller-initiated cancellations set cancellation.canceled_by: "seller" and MUST trigger a webhook notification to the orchestrator.

Package Lifecycle

Packages follow the same pause/cancel pattern as media buys, with additional creative deadline enforcement:
  • paused: Temporarily stopped — can be resumed with paused: false
  • canceled: Permanently stopped — irreversible
  • creative_deadline: Per-package deadline for creative uploads or changes. After this deadline, creative changes are rejected with CREATIVE_REJECTED.
When creative_deadline is absent on a package, the media buy’s creative_deadline applies. This is important for mixed-channel orders — a print package may have an earlier material deadline than a digital package in the same media buy.

Status Management

Campaign state transitions:
  • Activation requests to start pending campaigns
  • Pause/resume operations for campaign control
  • Cancellation for buyer-initiated termination
  • Completion handling for successful campaign closure
  • Error recovery for failed operations

Response Times

Media buy operations use a unified status system with predictable timing:
  • create_media_buy: Instant to days
    • completed: Simple campaigns created immediately
    • working: Processing within 120 seconds (validation, setup)
    • submitted: Complex campaigns requiring hours to days (human approval)
  • update_media_buy: Instant to days
    • completed: Budget changes applied immediately
    • working: Targeting updates within 120 seconds
    • submitted: Package modifications requiring approval (hours to days)
  • get_media_buy_delivery: ~60 seconds (data aggregation)
  • Performance analysis: ~1 second (cached metrics)
Status Meanings:
  • completed: Operation finished, process results immediately
  • working: Processing, expect completion within 120 seconds
  • submitted: Long-running operation, provide webhook or poll with tasks/get

Best Practices

Campaign Planning

  • Start with clear objectives defined in your product discovery brief
  • Plan package structure around distinct audience/creative combinations
  • Set realistic budgets based on product pricing guidance
  • Allow time for approval in publisher workflows

Ongoing Management

  • Monitor daily pacing to ensure delivery against targets
  • Review performance weekly for optimization opportunities
  • Update targeting gradually to avoid disrupting delivery
  • Refresh creatives regularly to prevent audience fatigue

Budget Management

  • Allocate conservatively initially, then increase based on performance
  • Reserve budget for high-performing packages
  • Plan for seasonality in audience availability and pricing
  • Monitor spend efficiency across different targeting approaches
  • Budget Management: The system automatically recalculates impressions based on CPM when budgets are updated

Technical Implementation

  • Pause/Resume Strategy: Use campaign-level controls for maintenance, package-level for optimization
  • Performance Monitoring: Regular status checks and delivery reports ensure campaigns stay on track
  • Asynchronous Design: Design orchestrators to handle long-running operations gracefully
  • Task Tracking: Maintain persistent storage for pending task IDs
  • Webhook Integration: Implement webhooks for real-time updates
  • User Communication: Clearly communicate pending states to end users

Error Handling

For comprehensive error handling guidance including pending vs error states, response patterns, and recovery strategies, see Error Handling. Media buy specific error codes are documented in each task specification and the Error Handling Reference.

Asynchronous Operations and Human-in-the-Loop

The AdCP:Buy protocol is designed for asynchronous operations as a core principle. Orchestrators MUST handle pending states gracefully.

Human-in-the-Loop (HITL) Operations

Many publishers require manual approval for automated operations. The protocol supports this through the HITL task queue:
  1. Operation Request: Orchestrator calls any modification task
  2. Pending Response: Server returns pending_manual status with task ID
  3. Task Monitoring: Orchestrator polls or receives webhooks
  4. Human Review: Publisher reviews and approves/rejects
  5. Completion: Original operation executes upon approval

HITL Task States

pending → assigned → in_progress → completed/failed

              escalated

Orchestrator Requirements

Orchestrators MUST:
  1. Handle pending_manual and pending_permission as normal states
  2. Store task IDs for tracking pending operations
  3. Implement retry logic with exponential backoff
  4. Handle eventual rejection of operations gracefully
  5. Support webhook callbacks for real-time updates (recommended)

Standard Metrics

All platforms must support these core metrics:
  • impressions: Number of ad views
  • spend: Amount spent in currency
  • clicks: Number of clicks (if applicable)
  • ctr: Click-through rate (clicks/impressions)
Optional standard metrics:
  • conversions: Post-click/view conversions
  • viewability: Percentage of viewable impressions
  • completion_rate: Video/audio completion percentage
  • engagement_rate: Platform-specific engagement metric

Platform-Specific Considerations

Different platforms offer varying reporting and optimization capabilities:
  • Orders can contain multiple LineItems
  • LineItems map 1:1 with packages
  • Sophisticated targeting and frequency capping
  • Requires creative approval process
  • Reporting: Comprehensive dimensional reporting, real-time and historical data, advanced viewability metrics

Kevel

  • Campaigns contain Flights
  • Flights map 1:1 with packages
  • Real-time decisioning engine
  • Supports custom creative templates
  • Reporting: Real-time reporting API, custom metric support, flexible aggregation options

Triton Digital

  • Optimized for audio advertising
  • Campaigns contain Flights for different dayparts
  • Strong station/stream targeting capabilities
  • Audio-only creative support
  • Reporting: Audio-specific metrics (completion rates, skip rates), station-level performance data, daypart analysis

Advanced Analytics

Cross-Campaign Analysis

  • Portfolio performance across multiple campaigns
  • Audience overlap and frequency management
  • Budget allocation optimization across campaigns

Predictive Insights

  • Performance forecasting based on historical data
  • Optimization recommendations from AI analysis
  • Trend prediction for proactive adjustments

Integration Patterns

Discovery to Media Buy

Seamless flow from product discovery to campaign creation:
  1. Use get_products to find inventory
  2. Select products that align with campaign objectives
  3. Configure packages with appropriate targeting and formats
  4. Create media buy with create_media_buy

Creative Integration

Coordinate with creative management:
  1. Understand format requirements from selected products
  2. Prepare assets using Creative Management
  3. Assign creatives during campaign creation or via updates
  4. Monitor creative performance and refresh as needed

Performance Optimization

Data-driven campaign improvement leveraging comprehensive analytics:
  1. Track delivery with get_media_buy_delivery
    • Monitor real-time delivery metrics and pacing analysis
    • Get package-level performance breakdown for optimization opportunities
    • Track performance across different targeting approaches
  2. Analyze performance across packages and targeting
    • Use dimensional reporting for granular insights
    • Monitor performance index scores for AI-driven optimization
    • Identify high and low performing segments
  3. Update campaigns with update_media_buy
    • Reallocate budgets between high and low performing packages
    • Adjust targeting based on performance data
    • Pause underperforming packages and scale successful ones
  4. Iterate based on performance data and business outcomes
    • Feed performance data back into optimization algorithms
    • Continuously refine targeting and creative assignments
    • Scale successful strategies across similar campaigns

Optimization Best Practices

  1. Report Frequently: Regular reporting improves optimization opportunities
  2. Track Pacing: Monitor delivery against targets to avoid under/over-delivery
  3. Analyze Patterns: Look for performance trends across dimensions
  4. Consider Latency: Some metrics may have attribution delays
  5. Normalize Metrics: Use consistent baselines for performance comparison