- Manual Mode: Provide
packagesarray with explicit line item configurations - Proposal Mode: Provide
proposal_idandtotal_budgetto execute a proposal fromget_products
completed, working < 120s, or submitted for hours/days)
Request Schema: /schemas/v3/media-buy/create-media-buy-request.json
Response Schema: /schemas/v3/media-buy/create-media-buy-response.json
Quick Start
Create a simple media buy with two packages:Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
account | account-ref | Yes | Account reference. Pass { "account_id": "..." } or { "brand": {...}, "operator": "..." } if the seller supports implicit resolution. Required for billing and policy evaluation. |
proposal_id | string | No* | ID of a proposal from get_products to execute. Alternative to providing packages. |
total_budget | TotalBudget | No* | Total budget when executing a proposal. Publisher applies allocation percentages. |
packages | Package[] | No* | Array of package configurations (see below). Required when not using proposal_id. |
brand | BrandRef | Yes | Brand reference — resolved to full identity at execution time. See brand.json |
start_time | string | Yes | "asap" or ISO 8601 date-time |
end_time | string | Yes | ISO 8601 date-time (UTC unless timezone specified) |
invoice_recipient | BusinessEntity | No | Override the account’s default billing entity for this buy. The seller MUST validate the recipient is authorized and include it in check_governance when governance agents are configured. |
po_number | string | No | Purchase order number |
idempotency_key | string | No | Unique key for safe retries. If a request with the same key and account has already been processed, the seller returns the existing media buy. MUST be unique per (seller, request) pair. Min 16 chars. |
context | object | No | Opaque correlation data echoed unchanged in the response. Use for internal tracking, trace IDs, or other caller-specific identifiers. |
reporting_webhook | ReportingWebhook | No | Automated reporting delivery configuration |
packages OR (proposal_id + total_budget) must be provided.
TotalBudget Object
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Total budget amount |
currency | string | Yes | ISO 4217 currency code |
Package Object
| Parameter | Type | Required | Description |
|---|---|---|---|
product_id | string | Yes | Product ID from get_products |
pricing_option_id | string | Yes | Pricing option ID from product’s pricing_options array |
format_ids | FormatID[] | Yes | Format IDs that will be used - must be supported by product |
budget | number | Yes | Budget in currency specified by pricing option |
impressions | number | No | Impression goal for this package |
paused | boolean | No | Create package in paused state (default: false) |
pacing | string | No | "even" (default), "asap", or "front_loaded" |
bid_price | number | No | Bid price for auction pricing. This is the exact bid/price to honor unless the selected pricing option has max_bid: true, in which case it is treated as the buyer’s maximum willingness to pay (ceiling). |
optimization_goals | OptimizationGoal[] | No | Optimization targets for this package. Each goal is either kind: "event" (conversion events with event_sources array, optional cost_per, per_ad_spend, or maximize_value target) or kind: "metric" (seller-native metric with optional cost_per or threshold_rate target). Event goals require conversion_tracking.supported_targets on the product; metric goals require metric_optimization.supported_metrics. |
targeting_overlay | TargetingOverlay | No | Additional targeting criteria (see Targeting) |
start_time | string | No | ISO 8601 date-time for this package’s flight start. When omitted, inherits the media buy’s start_time. Must fall within the media buy’s date range. Does not support "asap". |
end_time | string | No | ISO 8601 date-time for this package’s flight end. When omitted, inherits the media buy’s end_time. Must fall within the media buy’s date range. |
creative_assignments | CreativeAssignment[] | No | Assign existing library creatives with optional weights and placement targeting |
creatives | CreativeAsset[] | No | Upload new creative assets and assign (creative_id must not already exist in library) |
context | object | No | Opaque correlation data echoed unchanged in the package response. Use to map seller-assigned package_id back to your internal line items, campaign structure, or tracking state. |
Response
Success Response
| Field | Description |
|---|---|
media_buy_id | Seller’s unique identifier |
confirmed_at | ISO 8601 timestamp of order confirmation. A successful response constitutes confirmation. |
creative_deadline | ISO 8601 timestamp for creative upload deadline |
packages | Array of created packages with complete state. Packages may include per-package creative_deadline when different from the media buy deadline. |
Error Response
| Field | Description |
|---|---|
errors | Array of error objects explaining failure |
errors before accessing success fields.
Common Scenarios
Campaign with Targeting
Add geographic restrictions and frequency capping:Campaign with Conversion Optimization
Set a per_ad_spend target for conversion-optimized delivery. The product must declare support inconversion_tracking.supported_targets, and you must have an event source configured via sync_event_sources:
Catalog-driven packages
A catalog-driven package allocates a single budget envelope to an entire catalog of items. Instead of creating separate packages per item, the platform optimizes delivery across all catalog items based on performance. This is the AdCP equivalent of catalog-based campaign types such as Google Performance Max or Meta Dynamic Product Ads. Include thecatalogs field in a package to make it catalog-driven. Each catalog should have a distinct type (e.g., one product catalog, one store catalog). The referenced catalogs must already be synced via sync_catalogs.
Job campaign with synced job catalog:
test=false
test=false
get_media_buy_delivery which returns by_catalog_item breakdowns. Creative variants for catalog-driven packages represent individual catalog items rendered as ads.
Campaign with Inline Creatives
Upload creatives at the same time as creating the campaign:Campaign with Reporting Webhook
Receive automated reporting notifications:Executing a Proposal
Execute a proposal fromget_products without manually constructing packages:
- The publisher converts allocation percentages to actual budgets using
total_budget - Packages are created automatically based on the proposal’s allocations
- All other fields (brand, start_time, end_time, etc.) work the same as manual mode
Context for Correlation
Thecontext field is an opaque object that sellers echo unchanged in responses and webhooks. Use it to map seller-assigned IDs back to your internal systems without needing to maintain a separate lookup table.
Context works at two levels:
- Media buy level — echoed in the
create_media_buyresponse - Package level — echoed in each package’s response, useful for mapping
package_idback to your internal line items
test=false
test=false
Error Handling
Common errors and resolutions:| Error Code | Description | Resolution |
|---|---|---|
PRODUCT_NOT_FOUND | Invalid product_id | Verify product exists via get_products |
FORMAT_INCOMPATIBLE | Format not supported by product | Check product’s format_ids field |
BUDGET_TOO_LOW | Budget below product minimum | Increase budget or choose different product |
TARGETING_TOO_NARROW | Targeting yields zero inventory | Broaden geographic or audience criteria |
POLICY_VIOLATION | Brand/product violates policy | Review publisher’s content policies |
INVALID_PRICING_OPTION | pricing_option_id not found | Use ID from product’s pricing_options |
CREATIVE_ID_EXISTS | Creative ID already exists in library | Use a different creative_id, assign existing creatives via creative_assignments, or update via sync_creatives |
Key Concepts
Format Specification
Format IDs are required for each package because:- Publishers create placeholder creatives in ad servers
- Both parties know exactly what creative assets are needed
- Validation ensures products support requested formats
- Progress tracking shows which assets are missing
Brand reference
Thebrand field identifies the advertiser for policy compliance and business purposes.
Pricing & Currency
Each package specifies itspricing_option_id, which determines:
- Currency (USD, EUR, etc.)
- Pricing model (CPM, CPCV, CPP, etc.)
- Rate and whether it’s fixed or auction-based
Targeting Overlays
Use sparingly - most targeting should be in your brief and handled through product selection. Use overlays only for:- Geographic restrictions (RCT testing, regulatory compliance)
- Frequency capping
- AXE segment inclusion/exclusion (legacy — new integrations use TMP)
Format Workflow
Why Format Specification Matters
When creating a media buy, format specification enables:- Placeholder Creation - Publisher creates placeholders in ad server with correct specs
- Validation - System validates products support requested formats
- Clear Expectations - Both parties know exactly what’s needed
- Progress Tracking - Track which assets are missing vs. required
- Technical Setup - Ad server configured before creatives arrive
Complete Workflow
Format Validation
Publishers MUST validate:- All formats are supported by the product
- Format specifications match
list_creative_formatsoutput - Creative requirements can be fulfilled within timeline
Flight date validation
When a package specifiesstart_time or end_time, sellers SHOULD validate that:
- Both dates fall within the media buy’s date range
start_timeis beforeend_time
INVALID_REQUEST error:
Asynchronous Operations
This task can complete instantly or take days depending on complexity and approval requirements. The response includes astatus field that tells you what happened and what to do next.
| Status | Meaning | Your Action |
|---|---|---|
completed | Done immediately | Process the result |
working | Processing (~2 min) | Poll frequently or wait for webhook |
submitted | Long-running (hours/days) | Use webhooks or poll infrequently |
input-required | Needs your input | Read message, respond with info |
failed | Error occurred | Handle the error |
- MCP
- A2A
Immediate Success (completed)
The task completed synchronously. No async handling needed.Request:test=false
Long-Running (submitted)
The task is queued for manual approval. Configure a webhook to receive updates.Request with webhook:test=false
Error (failed)
Response:Usage Notes
- Total budget is distributed across packages based on individual
budgetvalues - Creative assets must be uploaded before deadline for campaign activation
- Impression-time targeting (audience, frequency, suitability) is handled by TMP
- Pending states (
working,submitted) are normal, not errors - Orchestrators MUST handle pending states as part of normal workflow
- Inline creatives: The
creativesarray creates NEW creatives only. To update existing creatives, usesync_creatives. To assign existing library creatives, usecreative_assignmentsinstead.
Content Standards
When a media buy includes content standards (via thegovernance.content_standards field on get_products responses or the media buy request), the buyer is requesting brand suitability enforcement during delivery.
Content standards are created by calling
create_content_standards on a verification agent (e.g., IAS, DoubleVerify). Standards MUST be calibrated with each seller before use in production to ensure the seller’s local evaluation model aligns with the verification agent’s interpretation. See the Content Standards overview for the full setup workflow: create → calibrate → activate → validate.Policy Compliance
Brand and products are validated during creation. Policy violations return errors:- Brand/products align with selected packages
- Creatives match declared brand/products
- Campaign complies with all advertising policies
Next Steps
After creating a media buy:- Upload Creatives: Use
sync_creativesbefore deadline - Monitor Status: Use
get_media_buy_delivery - Optimize: Use
provide_performance_feedback - Update: Use
update_media_buyto modify campaign
Learn More
- Media Buy Lifecycle - Complete campaign workflow
- get_products - Discover inventory
- Targeting - Targeting strategies
- Pricing Models - Currency and pricing