create_media_buy
Create a media buy from selected packages. This task handles the complete workflow including validation, approval if needed, and campaign creation. Response Time: Instant to days (returnscompleted, working < 120s, or submitted for hours/days)
Pricing & Currency: Each package specifies its own pricing_option_id, which determines currency, pricing model (CPM, CPCV, CPP, etc.), and rates. Packages can use different currencies when sellers support it—sellers validate and reject incompatible combinations. See Pricing Models for details.
Format Specification Required: Each package must specify the creative formats that will be used. This enables placeholder creation in ad servers and ensures both parties have clear expectations for creative asset requirements.
Request Schema: /schemas/v1/media-buy/create-media-buy-request.json
Response Schema: /schemas/v1/media-buy/create-media-buy-response.json
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
buyer_ref | string | Yes | Buyer’s reference identifier for this media buy |
packages | Package[] | Yes | Array of package configurations (see Package Object below) |
brand_manifest | BrandManifestRef | Yes | Brand information identifying the advertiser. Required so publishers know who they’re doing business with for policy compliance and business purposes. Minimal manifests (just name/URL) are acceptable for sales agents - additional details like colors, fonts, and assets are only needed for creative generation and optimization. Can be provided as an inline object or URL reference to a hosted manifest. Can be cached and reused across multiple requests. See Brand Manifest for details and minimal usage patterns. |
promoted_products | PromotedProducts | No | Products or offerings being promoted in this media buy. Useful for campaign-level reporting, policy compliance, and publisher understanding of what’s being advertised. Selects from brand manifest’s product catalog using SKUs, tags, categories, or natural language queries. |
po_number | string | No | Purchase order number for tracking |
start_time | string | Yes | Campaign start time: "asap" to start as soon as possible, or ISO 8601 date-time for scheduled start |
end_time | string | Yes | Campaign end date/time in ISO 8601 format (UTC unless timezone specified) |
reporting_webhook | ReportingWebhook | No | Optional webhook configuration for automated reporting delivery (see Reporting Webhook Object below) |
Package Object
| Parameter | Type | Required | Description |
|---|---|---|---|
buyer_ref | string | Yes | Buyer’s reference identifier for this package |
product_id | string | Yes | Product ID for this package |
pricing_option_id | string | Yes | Pricing option ID from the product’s pricing_options array - specifies pricing model and currency for this package. See Pricing Models for details. |
format_ids | FormatID[] | Yes | Array of structured format ID objects that will be used for this package - must be supported by the product |
budget | number | Yes | Budget allocation for this package in the currency specified by the pricing option |
pacing | string | No | Pacing strategy: "even" (default), "asap", or "front_loaded" |
bid_price | number | No | Bid price for auction-based pricing options (required when pricing_option.is_fixed is false) |
targeting_overlay | TargetingOverlay | No | Additional targeting criteria for this package (see Targeting Overlay Object below) |
creative_ids | string[] | No | Creative IDs to assign to this package at creation time (references existing library creatives) |
creatives | CreativeAsset[] | No | Full creative objects to upload and assign to this package at creation time (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives. Max 100 per package. |
Targeting Overlay Object
Note: Targeting overlays should be rare. Most targeting should be expressed in your brief and handled by the publisher through product selection. Use overlays only for geographic restrictions (RCT testing, regulatory compliance) or frequency capping.| Parameter | Type | Required | Description |
|---|---|---|---|
geo_country_any_of | string[] | No | Restrict delivery to specific countries (ISO codes). Use for regulatory compliance or RCT testing. |
geo_region_any_of | string[] | No | Restrict delivery to specific regions/states. Use for regulatory compliance or RCT testing. |
geo_metro_any_of | string[] | No | Restrict delivery to specific metro areas (DMA codes). Use for regulatory compliance or RCT testing. |
geo_postal_code_any_of | string[] | No | Restrict delivery to specific postal/ZIP codes. Use for regulatory compliance or RCT testing. |
axe_include_segment | string | No | AXE segment ID to include for targeting |
axe_exclude_segment | string | No | AXE segment ID to exclude from targeting |
frequency_cap | FrequencyCap | No | Frequency capping settings (see Frequency Cap Object below) |
Frequency Cap Object
| Parameter | Type | Required | Description |
|---|---|---|---|
suppress_minutes | number | Yes | Minutes to suppress after impression (applied at package level) |
Reporting Webhook Object
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Webhook endpoint URL for reporting notifications |
auth_type | string | Yes | Authentication type: "bearer", "basic", or "none" |
auth_token | string | No* | Authentication token or credentials (required unless auth_type is “none”) |
reporting_frequency | string | Yes | Reporting frequency: "hourly", "daily", or "monthly". Must be supported by all products in the media buy. |
requested_metrics | string[] | No | Optional list of metrics to include in webhook notifications. If omitted, all available metrics are included. Must be subset of product’s available_metrics. |
- One notification per frequency period during the campaign
- One final notification when the campaign completes
- If reporting data is delayed beyond the product’s
expected_delay_minutes, a notification with"delayed"status will be sent to avoid appearing as a missed notification
reporting_capabilities.timezone) determines when periods begin/end. Ensure alignment between your systems and the publisher’s timezone to avoid confusion about reporting period boundaries.
Response (Message)
The response includes a human-readable message that:- Confirms the media buy was created with budget and targeting details
- Explains next steps and deadlines
- Describes any approval requirements
- Provides implementation details and status updates
- MCP: Returned as a
messagefield in the JSON response - A2A: Returned as a text part in the artifact
Response (Payload)
Field Descriptions
- media_buy_id: Publisher’s unique identifier for the created media buy
- buyer_ref: Buyer’s reference identifier for this media buy
- creative_deadline: ISO 8601 timestamp for creative upload deadline
- packages: Array of created packages
- package_id: Publisher’s unique identifier for the package
- buyer_ref: Buyer’s reference identifier for the package
Protocol-Specific Examples
The AdCP payload is identical across protocols. Only the request/response wrapper differs.MCP Request
MCP Response (Synchronous)
MCP Response (Partial Success with Errors)
MCP Response (Asynchronous)
A2A Request
Natural Language Invocation
Explicit Skill Invocation
A2A Response (with streaming)
Initial response:Key Differences
- MCP: May return synchronously or asynchronously with updates via:
- Polling (calling status endpoints)
- Webhooks (push notifications to callback URLs)
- Streaming (WebSockets or SSE)
- A2A: Always returns task with updates via:
- Server-Sent Events (SSE) for real-time streaming
- Webhooks (push notifications) for long-running tasks
- Payload: The
inputfield in A2A contains the exact same structure as MCP’sarguments
Human-in-the-Loop Examples
MCP with Manual Approval (Polling Example)
This example shows polling, but MCP implementations may also support webhooks or streaming for real-time updates. Initial Request:A2A with Manual Approval (SSE Example)
A2A can use Server-Sent Events for real-time streaming or webhooks for push notifications. Initial Request with SSE:A2A with Webhooks (Long-Running Task)
Initial Request with Webhook Configuration:A2A with Input Required
If the system needs clarification (e.g., ambiguous targeting): SSE Update requesting input:Scenarios
Media Buy with Inline Creatives (Single Atomic Operation)
Create a media buy and upload creatives in a single API call. This eliminates the need for a separatesync_creatives call and ensures creatives and campaign are created together atomically.
- Single API call - Creates media buy and uploads both static and generative creatives atomically
- Simplified workflow - No need to manage creative library separately for new campaigns
- Atomic operation - If media buy fails, creatives aren’t orphaned in library
- Mixed creative types - Combine static assets (video) with generative formats (display) in same request
- Brand context - Generative creatives leverage brand_manifest for creation
creative_ids to reference existing library creatives, or creatives to upload new ones.
Standard Media Buy Request
Retail Media Buy Request
Response - Success
Message: “Successfully created your $50,000 media buy targeting pet owners in CA and NY. The campaign will reach 2.5M users through Connected TV and Audio channels. Please upload creative assets by January 30 to activate the campaign. Campaign scheduled to run Feb 1-29.” Payload:Response - Retail Media Success
Message: “Successfully created your $75,000 retail media campaign targeting competitive dog food buyers. The campaign will reach 450K Albertsons shoppers with deterministic purchase data. Creative assets must include co-branding and drive to Albertsons.com. Upload by January 30 to activate. Campaign runs Feb 1 - Mar 31.” Payload:Response - Pending Manual Approval
Message: “Your $50,000 media buy has been submitted for approval. Due to the campaign size, it requires manual review by our sales team. Expected approval time is 2-4 hours during business hours. You’ll receive a notification once approved. Campaign scheduled for Feb 1 - Mar 31.” Payload:Platform Behavior
Different advertising platforms handle media buy creation differently:- Google Ad Manager (GAM): Creates Order with LineItems, requires approval
- Kevel: Creates Campaign with Flights, instant activation
- Triton: Creates Campaign for audio delivery
Status Values
Both protocols use standard task states:working: Task is in progress (includes waiting for approvals, processing, etc.)input-required: Needs clarification or additional information from clientcompleted: Task finished successfullyfailed: Task encountered an errorcancelled: Task was cancelledrejected: Task was rejected (e.g., policy violation)
Asynchronous Behavior
This operation can be either synchronous or asynchronous depending on the publisher’s implementation and the complexity of the request.Synchronous Response
When the operation can be completed immediately (rare), the response includes the created media buy details directly.Asynchronous Response
When the operation requires processing time, the response returns immediately with:- A tracking identifier (
context_idfor MCP,taskIdfor A2A) - Initial status (
"working"for both MCP and A2A) - Updates can be received via:
- Polling: Call status endpoints periodically (MCP and A2A)
- Webhooks: Register callback URLs for push notifications (MCP and A2A)
- Streaming: Use SSE or WebSockets for real-time updates (MCP and A2A)
Status Checking
MCP Status Checking
Option 1: Polling (create_media_buy_status)
For MCP implementations using polling, use this endpoint to check the status of an asynchronous media buy creation.Request
Response Examples
Processing:Option 2: Webhooks (MCP)
Register a callback URL to receive push notifications for long-running operations. Webhooks are ONLY used when the initial response issubmitted.
Configuration:
completed- Synchronous success, webhook NOT called (you have the result)working- Will complete within ~120s, webhook NOT called (wait for response)submitted- Long-running operation, webhook WILL be called on status changes
submitted operations):
Webhook POST for human approval needed:
result object for the task-specific payload of that status. See Task Management: Webhook Integration for complete details.
A2A Status Checking
A2A supports both SSE streaming and webhooks as shown in the examples above. Choose based on your needs:- SSE: Best for real-time updates with persistent connection
- Webhooks: Best for long-running tasks or when client may disconnect
Polling Guidelines (when using polling):
- First 10 seconds: Every 1-2 seconds
- Next minute: Every 5-10 seconds
- After 1 minute: Every 30-60 seconds
- For manual approval (when message indicates approval needed): Every 5 minutes
Handling Pending States
Orchestrators MUST handle pending states as normal operation flow:- Store the context_id for tracking
- Monitor for updates via configured method (polling, webhooks, or streaming)
- Handle eventual completion, rejection, or manual approval
Example Pending Operation Flow
Platform Mapping
How media buy creation maps to different platforms:- Google Ad Manager: Creates an Order with LineItems
- Kevel: Creates a Campaign with Flights
- Triton Digital: Creates a Campaign with Flights
Format Workflow and Placeholder Creatives
Why Format Specification is Required
When creating a media buy, format specification serves critical purposes:- Placeholder Creation: Publisher creates placeholder creatives in ad server with correct format specifications
- Validation: System validates that selected products actually support the requested formats
- Clear Expectations: Both parties know exactly what creative formats are needed
- Progress Tracking: Track which creative assets are missing vs. required
- Technical Setup: Ad server configuration completed before actual creatives arrive
Workflow Integration
The complete media buy workflow with format awareness:Format Validation
Publishers MUST validate that:- All specified formats are supported by the product in each package
- Format specifications match those returned by
list_creative_formats - Creative requirements can be fulfilled within campaign timeline
Brand Manifest for Sales Agents
Thebrand_manifest field is required so publishers know who the advertiser is. This is essential for:
- Policy compliance: Publishers need to verify advertisers meet their standards
- Business relationship: Knowing your customer (KYC) requirements
- Legal accountability: Clear identification of who’s running ads
When You Need Creative Generation or Optimization
Provide a full brand manifest with guidelines, assets, colors, fonts, and product catalog. See Brand Manifest for complete documentation.When You’re Only Creating Media Buys
Minimal manifests are perfectly acceptable. You just need to identify who the advertiser is:- Advertiser identity: Publishers know who’s buying ads
- Policy validation: Publishers can check the brand against their policies
- Business records: Clear tracking of which brands are running campaigns
- Brand colors, fonts, or logos (only needed for creative generation)
- Product catalogs (only needed if using
promoted_productsfield or creative generation) - Tone or guidelines (only needed for AI-powered creative generation)
Usage Notes
- A media buy represents a complete advertising campaign with one or more packages
- Each package is based on a single product with specific targeting, budget allocation, and format requirements
- Format specification is required for each package - this enables placeholder creation and validation
- Both media buys and packages have
buyer_reffields for the buyer’s reference tracking - The
brand_manifestfield is required and provides brand identity, context, and product catalog (see section above for minimal usage patterns) - Publishers will validate the promoted offering against their policies before creating the media buy
- Package-level targeting overlay applies additional criteria on top of product-level targeting
- The total budget is distributed across packages based on their individual
budgetsettings (or proportionally if not specified) - Budget supports multiple currencies via ISO 4217 currency codes
- AXE segments (
axe_include_segmentandaxe_exclude_segment) enable advanced audience targeting within the targeting overlay - Creative assets must be uploaded before the deadline for the campaign to activate
- Pending states are normal operational states, not errors
- Orchestrators MUST NOT treat pending states as errors - they are part of normal workflow
Policy Compliance
Thepromoted_offering is validated during media buy creation. If a policy violation is detected, the API will return an error:
- The promoted offering aligns with the selected packages
- Any uploaded creatives match the declared offering
- The campaign complies with all applicable advertising policies
Implementation Guide
Generating Helpful Messages
Themessage field should provide a concise summary that includes:
- Total budget and key targeting parameters
- Expected reach or inventory details
- Clear next steps and deadlines
- Approval status and expected timelines