- Fixed packages: Provide
packageswith independent package budgets (legacy default) - Seller-optimized packages: Provide
packages,total_budget, andbudget_allocation.mode: "seller_optimized"so the seller allocates a shared budget across packages - Proposal execution: Provide
proposal_idandtotal_budget; the committed proposal determines whether allocation is fixed or seller-optimized
completed, working < 120s, or submitted for hours/days)
Request Schema: /schemas/3.2.0-beta.0/media-buy/create-media-buy-request.json
Response Schema: /schemas/3.2.0-beta.0/media-buy/create-media-buy-response.json
Quick Start
Create a simple media buy with two packages:Request Parameters
* Either
packages OR (proposal_id + total_budget) must be provided.
When executing a proposal through this 3.x compatibility facade, proposal_status determines whether create_media_buy is valid. The split 3.2 request and revise operations return drafts; refine_proposals with action: "finalize" returns the committed snapshot that can be accepted before expires_at. New callers use accept_proposal. Legacy get_products drafts require its finalize form, which remains supported throughout 3.x.
An unexpired committed proposal carries an inventory hold and cannot be rejected merely because the seller sold that reserved inventory elsewhere. After expires_at, the hold lapses and the seller returns PROPOSAL_EXPIRED.
TotalBudget Object
Package Object
For
targeting_overlay.geo_places and geo_places_exclude, create-time values
must be within the selected Product’s corresponding overlay_support tuple.
Unsupported dimensions, systems, countries, place types, or combinations return
UNSUPPORTED_FEATURE. A supported tuple with an invalid, unknown, or deprecated
ID—or an unsupported explicit catalog version—returns INVALID_REQUEST with
error.field on the offending field. A supported selection with no current
inventory returns PRODUCT_UNAVAILABLE, without silent substitution or
repricing. An accepted create confirms the selected terms for the complete
effective targeting.
| creatives | CreativeAsset[] | No | Upload new creative assets inline and assign. Requires media_buy.features.inline_creative_management: true; when the seller also advertises creative.has_creative_library: true, creative_id must not already exist in the library. |
| context | object | No | Opaque correlation data echoed unchanged in the package response, webhooks, and read surfaces. Use to map seller-assigned package_id back to your internal line items, campaign structure, or tracking state. Buyers targeting mixed seller populations SHOULD include a per-package correlation value here, commonly context.buyer_ref, for legacy sellers that do not echo product_id. |
| measurement_terms | MeasurementTerms | No | Buyer’s proposed billing measurement and makegood terms. Overrides product defaults. Seller accepts (echoed on confirmed package), rejects with TERMS_REJECTED, or adjusts. When omitted, product’s measurement_terms apply. |
| performance_standards | PerformanceStandard[] | No | Buyer’s proposed performance standards (viewability, IVT, completion rate, brand safety, attention score). Overrides product defaults. Seller accepts, rejects with TERMS_REJECTED, or adjusts. When omitted, product’s performance_standards apply. |
| committed_metrics | object[] | No | Buyer’s proposed reporting contract — metrics the buyer wants the seller to commit to populating in delivery reports. Same negotiation pattern as measurement_terms/performance_standards: each entry tags scope: "standard" (with metric_id from the closed enum) or scope: "vendor" (with vendor BrandRef + vendor’s metric_id). Request-side entries do NOT carry committed_at — that timestamp is stamped by the seller on accept. Seller accepts (echoes on response with committed_at), rejects with TERMS_REJECTED, or normalizes (echoes a different but compatible list). When omitted, the seller decides what to commit based on the product’s available_metrics plus any required_metrics filter the buyer passed at discovery. |
BiddingPolicy Object
optimization_goals select the objective; bidding constrains how the seller executes against it. Every monetary amount is in the media-buy currency, which is not repeated in the block. The pricing option contributes only the auction unit, never a second currency. Every package’s selected pricing option must declare the media-buy currency; split packages requiring another currency into a separate media buy.
automatic, bid_amount, cost_per, and roas are mutually exclusive primary modes. max_bid can stand alone or supplement cost_per/roas only where the relevant scope capability advertises the combination; bid_amount and max_bid cannot coexist.
Goal binding is determined by authored scope:
- A seller-optimized media-buy
cost_perorroasbinds to the primary goal inbudget_allocation.optimization_goals. - A package-authored override binds to that package’s primary
optimization_goalsgoal. - A fixed-allocation media-buy
cost_perbinds separately to every inheriting package and is valid only when their primary-goal result units are compatible. Metric goals must identify the same metric and result-defining qualifier; vendor metrics must identify the same vendor and metric; event goals must identify the same event-type/custom-name set and resolved attribution window. A fixed media-buyroasmay span different event identities, but every inheriting primary goal must be value-bearing.
bid_amount and max_bid use the selected pricing option’s auction unit, which permits a package conversion-cost target plus a max-CPC ceiling while keeping both monetary amounts in one currency. Auction-unit identity is the pricing model plus all billing-event qualifiers after defaults: for example CPV view threshold, CPP demographic, time unit, or flat-rate/DOOH parameters. A media-buy bid_amount or max_bid may be inherited only by packages with the same auction-unit identity; other packages need package overrides.
Precedence is complete-block inheritance:
- Package
biddingreplaces media-buybiddingfor that package. - An omitted package block inherits the complete media-buy block.
{automatic: true}is an explicit package override that disables inherited buyer controls for that package.- If both scopes are absent, provider automatic delivery applies.
- Sellers preserve authored scope on readback and never copy an inherited media-buy policy into every package.
BIDDING_PLACEMENT_CONFLICT; they never choose one conflicting package policy based on package order.
In independent-package budget mode, sellers normally write each effective policy to the package-native object. When a provider requires one campaign strategy and all effective package policies are identical, a seller may lift that policy to the native campaign, but readback still preserves whether the buyer authored it at media-buy or package scope.
Capability discovery is structured. Sellers advertise only the scopes, modes, strengths, and supplements they preserve, for example a package-only cost-cap implementation:
fixed and seller_optimized profiles so support in one allocation context makes no claim about the other. supported_combinations entries use kind: "max_bid_with_cost_per" or kind: "max_bid_with_roas" and list the exact cost/ROAS strengths supported in that combination. Presence of bidding_policy alone is not a blanket claim, and the former boolean form is invalid in 3.2.
During 3.2, sellers accept either canonical bidding or one legacy representation on an effective package, never both. Mixed input is rejected with AMBIGUOUS_BIDDING_POLICY. Legacy normalization is deterministic: bid_price plus pricing-option max_bid: true becomes bidding.max_bid; other bid_price becomes bidding.bid_amount; goal target.cost_per becomes bidding.cost_per with strength: "target"; and goal target.per_ad_spend becomes bidding.roas with strength: "target".
A provider portfolio bidding strategy illustrates the current abstraction boundary. This contract represents the numeric policy but does not model a provider portfolio resource or shared identity above a media buy. A seller may create and own a single-buy provider strategy to honor a portfolio-only ceiling. Selecting an existing strategy, sharing learning across media buys, or updating several buys atomically requires a future provider-neutral bidding-policy resource/reference; provider identity may be returned under ext until then.
Response
Success Response
Treat
packages[].formats_to_provide[] as the stable creative checklist established at booking time. Each full declaration can be matched against a creative agent’s live creative.supported_formats[].format, even when the product option has no format_option_id. After uploads or assignments, call get_media_buys: packages[].formats_pending[] contains the declarations that still lack creative coverage. The deprecated format_ids_to_provide / format_ids_pending projections exist only for older 3.x peers.
confirmed_at is seller commitment time, not a delivery-status timestamp. Do not update it when a buy later pauses, resumes, starts delivery, completes, or reports performance. A committed synchronous create stamps it immediately. Use the submitted response branch when no media_buy_id is being returned to the buyer. Sellers MAY instead return synchronous success with media_buy_id, packages, and confirmed_at: null for a provisional buy; such buys MUST be retrievable via get_media_buys and MUST transition by setting confirmed_at exactly once on commitment. A provisional buy with confirmed_at: null MUST NOT be active and MUST NOT include packages[].committed_metrics.
Reporting contract on confirmed packages
Each package in the response MAY carrycommitted_metrics — the binding reporting contract the seller has agreed to populate in delivery reports for this package. The field is a unified array carrying both standard metrics (from the closed available-metric.json enum) and vendor-defined metrics (anchored on a BrandRef), with each entry tagged by an explicit scope discriminator and timestamped via committed_at:
When confirmed_at is null, sellers MUST omit packages[].committed_metrics. The first response that sets confirmed_at MAY include the initial committed-metrics set, and each such entry’s committed_at MUST equal confirmed_at.
-
Day-1 entries share
committed_at = confirmed_at. The seller stamps the day-1 set on thecreate_media_buyresponse based on what they’re prepared to deliver from the product’sreporting_capabilities. -
Mid-flight additions are appended via
update_media_buy— append-only with their owncommitted_attimestamps. This lets a seller honestly say “Adelaide attention is now part of the contract from day 30 onward” without having to cancel and reissue the buy. -
Existing entries are immutable. Sellers MUST reject
update_media_buyrequests that attempt to modify or remove existing entries with avalidation_error(suggested code:IMMUTABLE_FIELD). New entries can be appended. -
Qualifiers on standard metrics. Some metrics have multiple incompatible measurement paths and need disambiguation:
viewability_standard— whenmetric_idis one ofviewable_impressions,viewable_rate,measurable_impressionsand the seller commits to a specific viewability standard (MRC and GroupM are materially different thresholds — see theviewability-standardenum), the entry MUST carryqualifier.viewability_standard. Symmetric onmissing_metrics: a buyer expecting MRC viewability flags a GroupM-only delivery report as missing the MRC commitment.completion_source— whenmetric_idiscompletion_rateand the seller commits to a specific source (the player/ad server’s own completion event vs. a third-party measurement vendor anchored onperformance_standard.vendor), the entry MUST carryqualifier.completion_source(seller_attestedorvendor_attested). The two paths can yield materially different rates, particularly in SSAI environments. Symmetric onmissing_metrics.attribution_methodology— whenmetric_idis an outcome metric (conversions,conversion_value,roas,cost_per_acquisition,incremental_sales_lift,brand_lift,foot_traffic,conversion_lift,brand_search_lift,units_sold,new_to_brand_rate,new_to_brand_units,leads) and the seller commits to a specific attribution methodology, the entry SHOULD carryqualifier.attribution_methodology(deterministic_purchasefor retail-media closed-loop;probabilistic,panel_based, ormodeledfor other paths). Two outcome rows under different methodologies are not interchangeable; symmetric onmissing_metrics.attribution_window— whenmetric_idis an outcome metric and the seller commits to a specific lookback window, the entry SHOULD carryqualifier.attribution_windowas a structured duration ({ interval: 14, unit: "days" }). Two outcome rows over different windows are reported as separate rows so buyers don’t accidentally aggregate across periods.
additionalProperties: false); new keys ship explicitly in subsequent minors. -
Reconciliation:
missing_metricsonget_media_buy_deliveryfilterscommitted_metricsto entries wherecommitted_at < reporting_period.end, then flags any that aren’t populated in the report. A metric committed mid-flight is only audited from its commitment timestamp forward. Qualifiers are matched verbatim — a committed{viewable_rate, mrc}is not satisfied by a deliveredviewable_ratecarryingviewability.standard: groupm. -
Optional in v1. Sellers without per-package snapshot infrastructure can adopt incrementally. Absence is conformant but carries a known audit gap: without the snapshot,
missing_metricsreconciles against the product’s liveavailable_metricsat report time, which may not reflect what was committed at create time. Sellers that omitcommitted_metricsaccept this risk; buyers SHOULD treat absence as “no audit-grade contract” rather than “clean delivery.” Expected to become required at the next major.
Error Response
Terminal and submitted responses never include
warnings. Each success warning carries typed affected_resource identity; codes follow the negotiated AdCP release.
Submitted Response
Returned when the buy cannot be confirmed synchronously — e.g., guaranteed buys awaiting IO signing, governance review queued, or batched processing. The completion artifact (delivered through AdCP polling or a push-notification webhook) carriesmedia_buy_id and packages. A2A profile callers poll with get_task_status; MCP sellers may also expose the legacy AdCP tasks/get name.
There is no proposal-specific acceptance webhook. Proposal execution that needs human approval, IO signing, or asynchronous processing uses this same submitted task envelope and the standard task/webhook completion path.
Note: Responses are mutually exclusive across these three shapes. Dispatch on
status first: "submitted" → async envelope, otherwise check errors before accessing success fields.
When to return Submitted vs synchronous Success (normative)
The choice betweensubmitted and synchronous success is per-call, driven by per-product attributes and the seller’s policy on each specific create — not a uniform per-seller rule. A sales-guaranteed seller may legitimately return synchronous success on some create_media_buy calls and submitted on others within the same session; conformant SDK skills MUST NOT instruct agents to return submitted for every create_media_buy regardless of input. Sellers that uniformly return submitted fail the non-IO-approval paths in the sales-guaranteed compliance storyboard.
Sellers MUST return submitted when:
- The request references one or more products with
delivery_type: "guaranteed"and the seller declares therequires_io_approvalcapability — the human-approval handshake cannot complete inside the response. The completion artifact is delivered through AdCP polling (get_task_statuson the A2A profile) or webhook once IO signing finishes. - The request triggers a seller-side governance review that cannot complete synchronously (e.g., manual brand-safety review for a regulated vertical).
- The request enters a batched-processing queue the seller cannot drain inside the response timeout.
- All referenced products have
delivery_type: "non_guaranteed". The buy is created and acknowledged in-line;media_buy_idandpackagesare issued immediately. This applies regardless of the seller’s specialism — a sales-guaranteed seller serving a non-guaranteed product returns synchronous success. - The request references guaranteed products and the seller does NOT declare
requires_io_approval(rare; typically retail-SKU or quoted-rate guaranteed flows where the seller has pre-cleared approval). - The buy enters a known non-terminal state immediately observable to the buyer (
pending_creatives/pending_start/active/paused).
create_buy_submitted scenario seeds a guaranteed product with requires_io_approval; four shared scenarios (measurement_terms_rejected, pending_creatives_to_start, inventory_list_targeting, invalid_transitions) seed non-guaranteed products and expect synchronous media_buy_id returns. Sellers that return submitted on the synchronous-expected scenarios fail compliance — see sales-guaranteed specialism for the fixture pattern (non-guaranteed products listed first so open-brief get_products calls resolve to a synchronous-create path).
This rule resolves the skill ↔ storyboard contradiction tracked at #3822: an SDK skill that instructs agents to “return a task envelope for every create_media_buy” is non-conformant; the correct skill instructs agents to dispatch on per-product delivery_type and the seller’s requires_io_approval capability.
Common Scenarios
Campaign with Targeting
Add geographic restrictions and frequency capping:Campaign with Conversion Optimization
Keep the purchase event as the objective, then express target ROAS and the max-CPC auction ceiling separately inbidding. 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.
Package with explicit signal targeting:
Use targeting_overlay.signal_targeting_groups when the buyer wants seller-offered signals applied to a specific package. The selected product must set signal_targeting_allowed: true and make the signal eligible through inline signal_targeting_options when present, through get_signals for wholesale products that omit inline options, and through signal_targeting_rules. The grouped expression shape is always used: top-level operator: "all" with child groups using operator: "any" for include groups and operator: "none" for exclusion groups. For simple include-only targeting, send one any group. For binary signals, send value: true in both include and exclusion groups; exclusion is expressed by the parent none group, not by value: false. Signals are referenced with signal_ref: use scope: "product" for a product-local signal option, scope: "data_provider" with data_provider_domain for a signal defined in a data provider’s published adagents.json signals[], or scope: "signal_source" with signal_source_url for a source-native signal. This is distinct from audience_include / audience_exclude, which only reference first-party audiences registered through sync_audiences. Send signal_agent_segment_id only when the selected product option or get_signals result exposed it as a separate execution handle required by the seller.
When a creative carries a build-time signal_condition (from build_creative’s signal_conditions fan-out, #5240), assigning it to a package whose signal targeting is incompatible — e.g. a sun creative to a rain-targeted package — is rejected with SIGNAL_TARGETING_INCOMPATIBLE. Compatibility is matched on the same shared signal_ref identity used here. See the signals specification for the normative trafficking-compatibility contract.
test=false
test=false
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 committed proposal finalized throughrefine_proposals without manually constructing packages:
- For fixed allocation, the publisher converts exact allocation percentages to package budgets using
total_budget - For seller-optimized allocation, the publisher preserves the shared allocation goals and converts minimum/maximum percentage constraints to package targets/caps
- Allocation-level pacing becomes subordinate package pacing; aggregate proposal pacing becomes media-buy pacing
- 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, webhooks, and read surfaces, useful for mapping
package_idback to your internal line items. For explicit package requests, sellers MUST also echoproduct_id.
context.buyer_ref as a legacy-safe fallback for older sellers that may not echo product_id.
Mapping to internal campaign and line item IDs:
test=false
test=false
Error Handling
Common errors and resolutions:
Example error response:
Key Concepts
Format Specification
Each package SHOULD specify the formats it will use viaformat_option_refs[] or a direct canonical selector (format_kind plus optional params). Omitting selectors defaults to all product options.
- Publish placeholder creatives in ad servers
- Pin exactly what creative assets are needed
- Validate that the product supports the requested formats
- Track which assets are missing
format_option_refs[] wins when present; otherwise direct format_kind/params is used; otherwise the package defaults to all product options. Deprecated format_ids[] is interpreted only on the negotiated legacy compatibility path and must normalize to the same canonical contract.
Before purchase, buyers SHOULD also inspect the selected declaration’s optional
locale_policy.accepted_language_ranges. These seller ranges use RFC 4647
Basic Filtering and let the buyer determine whether a planned or existing
creative has at least one eligible materialized locale variant. A constrained
option is canonical-only and must use a format-options-aware canonical path:
format_option_refs when published or needed for disambiguation, otherwise
direct format_kind with satisfying params. Legacy format_ids cannot
preserve the policy. Media buys may be created
before creatives exist, so discovery prevents incompatible planning while hard
enforcement occurs when a creative is assigned. When one assignment can serve
across several placements, the creative must satisfy each effective placement
locale policy independently or the buyer must narrow its placement scope.
3.1+ format-option example (buyer authoring against a publisher-scoped Product.format_options[] entry):
test=false
Brand reference
Thebrand field identifies the advertiser for policy compliance and business purposes.
Pricing & Currency
Each package specifies itspricing_option_id, which determines:
- Pricing model (CPM, CPCV, CPP, etc.)
- Rate and whether it’s fixed or auction-based
Budget & Pacing Controls
AdCP supports fixed package budgets and media-buy-level shared budgets.budget_allocation.mode makes the interpretation explicit; omission preserves the legacy fixed behavior.
Pacing modes (from
/schemas/3.2.0-beta.0/enums/pacing.json):
Example package with an even-paced budget over a fixed flight:
even pacing over the 31-day flight above, the seller spreads the 1,613/day — subject to the seller’s own pacing engine and available inventory.
Seller-optimized allocation
Seller-optimized allocation is a nested optimization:- Hard aggregate and package caps, flight windows, pauses, and policy restrictions always apply.
- Media-buy pacing controls how much the buy spends over time.
- Package pacing influences which eligible package receives that spend and MUST NOT cause aggregate delivery to exceed the media-buy pacing plan.
budget_allocation.optimization_goalschoose allocation across packages;packages[].optimization_goalsoptimize delivery within one package.- Media-buy
bidding.cost_per/roasbind to the primary cross-package allocation goal; package overrides bind to package goals and are allowed only when the provider can preserve their authored semantics under the shared strategy.
total_budget.currency, and every selected pricing option MUST declare that currency. This one-currency rule also applies to fixed AdCP-authored buys; packages requiring another denomination belong in a separate media buy. Every participating product MUST support the primary cross-package optimization goal. Sellers reject incompatible product combinations, currencies, pricing terms, or delivery constraints with TERMS_REJECTED or BIDDING_PLACEMENT_CONFLICT and identify the incompatible package.
Package caps may sum above the media-buy total; that headroom is what permits dynamic allocation. Minimum-spend targets must sum to no more than the total; sellers MUST reject over-subscribed aggregate minimums with INVALID_REQUEST before any provider mutation. If package caps cannot collectively spend the total, the seller rejects the request as infeasible. Sellers advertising this behavior declare media_buy.features.seller_optimized_budget: true in get_adcp_capabilities.
Continuous allocation decisions inside an accepted seller-optimized buy are delivery behavior. They do not mutate package caps, increment the media-buy revision, create history entries, or constitute separate reallocate_budget actions.
Daily budget cap
An optional media-buydaily_budget_cap sets a hard ceiling on aggregate spend per calendar day without creating package allocations. Optional package daily_budget_cap values add subordinate per-package ceilings. In seller-optimized mode, package caps may be omitted so the seller can allocate the aggregate daily allowance dynamically; a package cap is always a ceiling, never a reservation.
Daily caps are orthogonal to pacing. The media-buy cap bounds aggregate daily spend, package caps bound individual package spend, and pacing governs distribution within those limits. pacing: "asap" plus a cap is valid. Every cap on one media buy uses its accepted budget_cap_timezone. Without a buyer override, budget_capping.timezone_basis selects either the account’s operational timezone or the advertised feature-specific fixed_timezone; aggregate and package accounting then share that one boundary.
daily_budget_cap requires seller support: sellers advertise media_buy.budget_capping in get_adcp_capabilities, including supported scopes and the default timezone basis. A cap is always hard. Sellers MUST reject an undeclared scope with UNSUPPORTED_FEATURE rather than silently dropping or softening it, and echo accepted caps plus the resolved shared timezone on read surfaces.
When a seller does not support daily_budget_cap, approximate a daily rate with pacing: "even" and a budget ÷ flight_days calculation, or split a long flight into shorter packages each with its own budget — both are best-effort, not a guaranteed ceiling.
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
- Package selections match the product’s canonical
format_options[] - Creative requirements can be fulfilled within timeline
Flight date validation
For new media buys, the top-levelstart_time MUST be either "asap" or a
date-time that is not in the past. A past concrete start_time MUST return an
INVALID_REQUEST error.
When a package specifies start_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.
Note: For the complete status list see Task Lifecycle.
- MCP
- A2A
Immediate Success (completed)
The task completed synchronously. No async handling needed.Request:test=false
status is the envelope task-status (TaskStatus) — completed on synchronous success. The body-level media_buy_status carries the buy’s lifecycle state (pending_creatives, pending_start, active, or paused). The AdCP 3.2 source schema no longer permits the legacy top-level status: MediaBuyStatus form; see Media-buy status field migration below.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 or supplies package creatives inline. If the seller advertisescreative.has_creative_library: true, inline creatives enter the library; usesync_creativesto update existing library creatives andcreative_assignmentsto assign existing library creatives. If the seller advertisesinline_creative_management: truewithout a creative library, usepackages[].creativesoncreate_media_buyandupdate_media_buy; do not callsync_creatives. - Inline creative lifecycle: Library-backed inline creatives enter the library with the same lifecycle as
sync_creativesuploads. Inline-only sellers may keep the creative package-scoped and do not advertise later reuse bycreative_id. Creative review is independent of the buy outcome; sellers MUST NOT skip review solely because the buy did not activate. Retention of unassigned library creatives is seller-defined in 3.0. See Inline creatives on the package.
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:- Supply creatives: Use
sync_creativesfor library-backed sellers, orpackages[].creativesonupdate_media_buyfor inline-only sellers - Monitor Status: Use
get_media_buy_delivery - Optimize: Use
provide_performance_feedback - Update: Use
update_media_buyto modify campaign
Media-buy status field migration
3.1 split two enums that 3.0 collided at the same root key — envelopestatus (TaskStatus) at the top of every response, and body media_buy_status (MediaBuyStatus, new in 3.1) carrying the buy’s lifecycle state alongside. The legacy top-level status: MediaBuyStatus form was deprecated: true only in the 3.1 schema and is removed from the 3.2 source schema (#4906); nested status on get_media_buys, get_media_buy_delivery, and core/media-buy.json follow in 4.0 (#4905).
During the 3.1 migration window, buyers MUST prefer media_buy_status when present. The 3.1 compliance storyboards assert path: "media_buy_status" — a 3.1 seller emitting only the legacy status is schema-valid but fails certification. In 3.2, sellers MUST stop emitting the legacy lifecycle value; root status is reserved for TaskStatus.
Full migration: Migration › media_buy_status.
Learn More
- Media Buy Lifecycle - Complete campaign workflow
- get_products - Discover inventory
- Targeting - Targeting strategies
- Pricing Models - Currency and pricing