AdCP 3.0 Proposal - This specification is under development for AdCP 3.0. Feedback welcome via GitHub Discussions.
Abstract
The Media Buy Protocol defines a standard interface for AI-powered advertising automation. This protocol enables AI agents to discover advertising inventory, create and manage campaigns, synchronize creative assets, and track performance through natural language interactions.Protocol Overview
The Media Buy Protocol provides:- Natural language inventory discovery based on campaign briefs
- Campaign creation with package-level budget and targeting
- Creative asset management and synchronization
- Performance tracking and optimization feedback
- Human-in-the-loop approval workflows
Transport Requirements
Sales agents MUST support at least one of the following transports:| Transport | Protocol | Description |
|---|---|---|
| MCP | Model Context Protocol | Tool-based interaction via JSON-RPC |
| A2A | Agent-to-Agent | Message-based interaction |
get_adcp_capabilities:
Core Concepts
Request Roles
Every media buy request involves three entities:- Orchestrator: The platform making the API request (e.g., DSP, trading desk)
- Account: The billing relationship—who gets billed and what rates apply (identified by
account_id) - Agent: The entity placing the buy (identified by authentication token)
Sales Agent Types
Publisher Sales Agents — represent a single publisher’s inventory:- Sales agents MUST only return products for inventory they are authorized to sell
- Sales agents MUST validate authorization via
adagents.jsonwhen applicable
- Sales agents MUST clearly identify the source publisher for each product
- Sales agents MUST NOT misrepresent inventory provenance
Identifiers
-
media_buy_id: Unique identifier for a media buy. Sales agents MUST return this on successful creation. Orchestrators MUST use this for all subsequent operations on the media buy. -
package_id: Unique identifier for a package within a media buy. Sales agents MUST return this for each package created. -
idempotency_key: Client-generated unique key for safe retries. Sales agents that receive a duplicate key for the same account MUST return the original response rather than re-executing.
Asynchronous Operations
The Media Buy Protocol is asynchronous by design. Operations MAY return immediately or MAY require extended processing:- Synchronous responses: Sales agents MAY return completed results immediately
- Asynchronous responses: Sales agents MAY return
status: "submitted"orstatus: "working"with a task reference - Human-in-the-loop: Sales agents MAY require manual approval, indicated by
status: "pending_approval" - Rejection: Sales agents MAY reject a media buy in
pending_activationstatus when platform setup reveals the order cannot be fulfilled (e.g., inventory sold out, policy issue discovered during ad server setup). Orchestrators MUST treatrejectedas a terminal state. If the seller does not want to accept the order at create time, it SHOULD failcreate_media_buywith an error rather than creating a media buy inrejectedstatus.
Media Buy State Transitions
Media buys progress through a defined set of states. Terminal states (completed, rejected, canceled) allow no further transitions.
- Sales agents MAY return
activeorpending_activationfromcreate_media_buy(seller’s choice based on platform setup time) - Sales agents MUST transition media buys from
pending_activationtoactivewhen platform setup is complete. Sales agents SHOULD notify orchestrators via webhook when this transition occurs. - A successful
create_media_buyresponse constitutes order confirmation. Sales agents MUST includeconfirmed_atin the response. - Sales agents MUST include
revisionin create and update responses. The revision number MUST increment on every state change or update. active↔pausedtransitions useupdate_media_buywithpaused: trueorpaused: falseactiveorpaused→completedwhen the flight ends, goal is met, or budget is exhausted (seller-initiated)- Buyer-initiated cancellation uses
update_media_buywithcanceled: trueand optionalcancellation_reason - Seller-initiated cancellation (e.g., policy violation, inventory withdrawal) transitions the media buy to
canceledwithcancellation.canceled_by: "seller". Sellers MUST notify orchestrators via webhook when performing seller-initiated cancellation. - Seller-initiated rejection (from
pending_activation) MUST also notify orchestrators viapush_notification_config. The webhook payload MUST includemedia_buy_id,status: "rejected", andrejection_reason. - Sales agents MUST include a
cancellationobject withcanceled_atandcanceled_bywhen transitioning a media buy or package tocanceled - Sales agents MAY reject buyer cancellation with error code
NOT_CANCELLABLE - Sales agents MUST reject updates to media buys in terminal states (
completed,rejected,canceled) with error codeINVALID_STATE - Rejection (
rejectedstatus) is only valid frompending_activation. Sales agents MUST NOT reject media buys that have already transitioned toactive. - Seller-initiated cancellation notifications MUST use the
push_notification_configwebhook provided by the orchestrator duringcreate_media_buyorupdate_media_buy. The webhook payload MUST includemedia_buy_id,status: "canceled", and acancellationobject withcanceled_at,canceled_by: "seller", andreason. - The
canceledfield on update requests uses"const": true— onlytrueis valid. Sendingcanceled: falsefails schema validation. Cancellation is irreversible; there is no “uncancel” operation.
- Packages MAY have a
creative_deadline— after this deadline, creative changes to the package are rejected withCREATIVE_DEADLINE_EXCEEDED. When absent, the media buy’screative_deadlineapplies.CREATIVE_REJECTEDis reserved for content policy failures. - Package cancellation (
canceled: truein a package update) is irreversible and independent of the media buy’s status — a single package can be canceled while the media buy remains active. - Sales agents MUST retain delivery data for canceled packages. When
include_snapshotis true, sales agents SHOULD return a final snapshot reflecting delivery state at the time of cancellation. - When all packages in a media buy are canceled, the media buy itself remains in its current status (
activeorpaused). Sellers that support mid-flight package additions advertiseadd_packagesinvalid_actions— the buyer can add new packages vianew_packagesinupdate_media_buy. Otherwise, the buyer SHOULD explicitly cancel the media buy. Sales agents SHOULD notify orchestrators (viacontext.notesin the update response) when the last active package is canceled. Sales agents MAY auto-transition the media buy tocanceledafter a seller-defined grace period if no new activity occurs.
Creative Approval on Packages
Schema:enums/creative-approval-status.json
Each package tracks per-creative approval status separately from the creative’s library-level status. A creative may be approved in the library but rejected on a specific package (e.g., wrong format for the placement).
| Status | Description |
|---|---|
pending_review | Creative submitted and awaiting platform review |
approved | Creative approved for delivery on this package |
rejected | Creative rejected for this package; see rejection_reason |
sync_creatives, which resets the approval to pending_review. The resubmission path:
- Check
rejection_reasononget_media_buysresponse - Fix the creative (update assets, adjust manifest)
- Resubmit via
sync_creatives - Approval resets to
pending_review
creative_deadline: If a creative is rejected after the package’s creative_deadline, the buyer MAY still resubmit — sellers SHOULD accept resubmissions for rejected creatives even past the deadline, since the buyer is correcting a seller-identified issue. Sellers that cannot accept late resubmissions MUST return CREATIVE_DEADLINE_EXCEEDED.
Tasks
The Media Buy Protocol defines the following tasks. See task reference pages for complete request/response schemas and examples.get_products
Schema:media-buy/get-products-request.json / media-buy/get-products-response.json
Reference: get_products task
Discover advertising inventory using natural language briefs or explicit wholesale intent.
Requirements:
- Orchestrators MUST set
buying_modeto"brief","wholesale", or"refine" - Orchestrators MUST include
briefwhenbuying_modeis"brief" - Orchestrators MUST NOT include
briefwhenbuying_modeis"wholesale"or"refine" - Orchestrators MUST include
refinewhenbuying_modeis"refine" - Orchestrators MUST NOT include
refinewhenbuying_modeis"brief"or"wholesale" - Orchestrators MUST provide
scope,id, andactionfor each product and proposal entry inrefine - Orchestrators MUST NOT include multiple entries for the same product ID or proposal ID in a single
refinearray - Sales agents MUST return products matching the brief criteria when a brief is provided
- Sales agents MUST include
product_idandpricing_optionsfor each product - Sales agents SHOULD include relevance scoring when multiple products match
get_products request with buying_mode: "refine" is self-contained — sales agents MUST NOT depend on transport-level session state. The refine array and filters on each request fully specify the refinement intent. Sellers maintain their own product and proposal registries; “stateless” means the protocol exchange carries no implicit state between calls. This enables stateless implementations and safe retries.
- Sales agents MUST omit products with
action: "omit"from the response - Sales agents MUST omit proposals with
action: "omit"from the response - Sales agents MUST return products with
action: "include", with updated pricing - Sales agents SHOULD fulfill the
askon product entries withaction: "include" - Sales agents SHOULD return additional products similar to those with
action: "more_like_this", plus the original product - Sales agents SHOULD consider request-level asks (
scope: "request") when composing the response — this MAY result in additional products beyond those explicitly referenced. Per-product actions take precedence over request-level direction. - Sales agents SHOULD fulfill the
askon proposal entries withaction: "include" - Sales agents SHOULD include
refinement_appliedin the response, with one entry per change request matched by position - Sales agents MAY return proposals alongside products in refine mode, even when the orchestrator did not include proposal entries
list_creative_formats
Schema:media-buy/list-creative-formats-request.json / media-buy/list-creative-formats-response.json
Reference: list_creative_formats task
Discover creative format requirements and specifications.
Requirements:
- Sales agents MUST return all supported creative formats
- Sales agents MUST include technical specifications for each format
- Sales agents SHOULD reference standard format IDs from the Creative Protocol when applicable
create_media_buy
Schema:media-buy/create-media-buy-request.json / media-buy/create-media-buy-response.json
Reference: create_media_buy task
Create a media buy from selected packages or execute a proposal.
Requirements:
- Orchestrators MUST include either
packagesarray orproposal_id - Orchestrators MUST include
start_timeandend_timefor the campaign - Sales agents MUST return
media_buy_idon successful creation - Sales agents MUST return
confirmed_at— a successful response constitutes order confirmation - Sales agents MUST return
creative_deadlineindicating when creatives must be uploaded - Sales agents MUST validate budget against pricing options
- On validation failure, sales agents MUST return an
errorsarray
update_media_buy
Schema:media-buy/update-media-buy-request.json / media-buy/update-media-buy-response.json
Reference: update_media_buy task
Modify an existing media buy’s budget, targeting, or settings.
Package operations are structurally explicit — the operation type is determined by where the package appears in the request:
| Operation | Request location | Description |
|---|---|---|
| New | new_packages[] | Add a package to the media buy |
| Changed | packages[] | Modify an existing package (budget, targeting, dates, creatives) |
| Canceled | packages[] with canceled: true | Cancel an existing package (irreversible) |
- Orchestrators MUST include
media_buy_id - Sales agents MUST apply PATCH semantics: only specified fields are updated; omitted fields remain unchanged
- Sales agents MUST reject updates to media buys in terminal states (
completed,rejected,canceled) with error codeINVALID_STATE - Orchestrators MAY cancel a media buy by setting
canceled: truewith optionalcancellation_reason - Sales agents MUST transition the media buy to
canceledstatus upon accepting cancellation - Sales agents MAY reject cancellation with error code
NOT_CANCELLABLE - Orchestrators MAY cancel individual packages by setting
canceled: trueon a package update - Sales agents MUST reject creative changes to packages past their
creative_deadlinewith error codeCREATIVE_DEADLINE_EXCEEDED - Orchestrators MAY add new packages to an existing media buy via
new_packages. Sales agents that support this MUST advertiseadd_packagesinvalid_actions. Sales agents that do not support adding packages MUST reject withUNSUPPORTED_FEATURE. - When
canceled: trueis present alongside other fields in an update request, sales agents MUST apply cancellation and MUST ignore all other fields exceptcancellation_reason. Cancellation takes precedence over concurrent mutations. Sales agents SHOULD include a warning in the responsecontextwhen non-cancellation fields were present and ignored. - Sales agents MUST return
affected_packagescontaining the state of each directly modified package after the update is applied (or the proposed state if pending approval); an empty array is valid when only campaign-level fields (e.g.,paused,start_time) are updated - When manual approval is required, sales agents MUST persist the pending update request, MUST return
implementation_date: null, and MUST NOT return emptyaffected_packages - Sales agents SHOULD return the updated media buy state
sync_catalogs
Schema:media-buy/sync-catalogs-request.json / media-buy/sync-catalogs-response.json
Reference: sync_catalogs task
Synchronize catalogs (products, inventory, stores, and vertical feeds) on a seller account.
Requirements:
- Orchestrators MUST include
account_id - When
catalogsis provided, it MUST contain at least one catalog - When
catalogsis omitted, the call is discovery-only and returns existing catalogs without modification - Sales agents MUST return per-catalog outcomes, including what action was taken and any item-level issues
- Sales agents SHOULD support
dry_runfor validation without applying changes
list_creatives
list_creatives is defined in the Creative Protocol. Sales agents that host creative libraries MAY implement list_creatives as part of the Creative Protocol. See the list_creatives task reference.sync_creatives
sync_creatives is defined in the Creative Protocol. Any agent that hosts a creative library implements sync_creatives as part of the Creative Protocol. See the sync_creatives task reference.get_media_buys
Schema:media-buy/get-media-buys-request.json / media-buy/get-media-buys-response.json
Reference: get_media_buys task
Retrieve operational media buy state, including package status, creative approvals, missing formats, and optional delivery snapshots.
Requirements:
- Orchestrators MAY filter by
account_id,media_buy_ids, andstatus_filter - Orchestrators SHOULD use cursor pagination (
pagination.max_results/pagination.cursor) for broad scope queries - Sales agents MUST return current media buy status and package-level operational state for each matched media buy
- Sales agents SHOULD include
valid_actionsfor each media buy, listing the actions the buyer can perform in the current state. This eliminates the need for agents to internalize the state machine. Expected mapping:
| Status | Expected valid_actions |
|---|---|
pending_activation | cancel, sync_creatives |
active | pause, cancel, update_budget, update_dates, update_packages, add_packages, sync_creatives |
paused | resume, cancel, update_budget, update_dates, update_packages, add_packages, sync_creatives |
completed / rejected / canceled | (empty array) |
cancel when contractual obligations prevent it, omit add_packages when the platform does not support mid-flight additions).
valid_actions contains only mutation operations — read-only operations (get_media_buys, get_media_buy_delivery) are always permitted regardless of state. Agents SHOULD use valid_actions as an optimization hint but MUST handle INVALID_STATE errors gracefully, since valid_actions may not reflect real-time state changes from concurrent operations. Absence of an action means “not declared by this seller,” not necessarily “forbidden.”
- Orchestrators MAY request revision history by setting
include_historyto the number of most-recent entries desired. Sales agents SHOULD return ahistoryarray per media buy wheninclude_history > 0, containing revision number, timestamp, server-derived actor identity, action type, and optional summary. History entries MUST be ordered most-recent-first. - Sales agents MUST include a media-buy currency and MUST denominate monetary fields consistently (
snapshot.currency->package.currency->media_buy.currency) - Sales agents SHOULD include creative approval outcomes and pending format requirements when available
- If
include_snapshotis true and snapshot data is omitted for a package, sales agents MUST returnsnapshot_unavailable_reason - When
include_snapshotis true and snapshots are returned, each snapshot MUST includeas_ofandstaleness_seconds - Default
status_filter: ["active"]applies only whenmedia_buy_idsis omitted
get_media_buy_delivery
Schema:media-buy/get-media-buy-delivery-request.json / media-buy/get-media-buy-delivery-response.json
Reference: get_media_buy_delivery task
Track performance metrics and campaign delivery.
Requirements:
- Orchestrators MUST include
media_buy_id - Sales agents MUST return delivery metrics at the package level
- Sales agents SHOULD include dimensional breakdowns when requested
- Sales agents MUST include
as_oftimestamp indicating data freshness
provide_performance_feedback
Schema:media-buy/provide-performance-feedback-request.json / media-buy/provide-performance-feedback-response.json
Reference: provide_performance_feedback task
Submit performance signals to enable publisher optimization.
Requirements:
- Orchestrators MUST include
media_buy_idand performance metrics - Sales agents MUST acknowledge receipt of feedback
- Sales agents SHOULD use feedback to optimize delivery within campaign constraints
sync_event_sources
Schema:media-buy/sync-event-sources-request.json / media-buy/sync-event-sources-response.json
Reference: sync_event_sources task
Configure event sources on a seller account for conversion tracking with upsert semantics.
Requirements:
- Orchestrators MUST include
account_id - When
event_sourcesis provided, it MUST contain at least one event source - When
event_sourcesis omitted, the call is discovery-only and returns all event sources on the account without modification - Sales agents MUST return per-source results with
actionindicating what happened - Sales agents MUST include seller-managed event sources in the response when present
- Sales agents SHOULD return
setupinstructions for newly created event sources - Sales agents MAY include
seller_idfor cross-referencing in the seller’s platform
log_event
Schema:media-buy/log-event-request.json / media-buy/log-event-response.json
Reference: log_event task
Send conversion or marketing events for attribution and optimization.
Requirements:
- Orchestrators MUST include
event_source_idreferencing a configured event source - Orchestrators MUST include at least one event with
event_id,event_type, andevent_time - Sales agents MUST return
events_receivedandevents_processedcounts - Sales agents MUST deduplicate events by
event_id+event_type+event_source_id - Sales agents SHOULD report
partial_failuresfor individually failed events - Sales agents SHOULD return
match_qualityscore when user matching is attempted
sync_audiences
Schema:media-buy/sync-audiences-request.json / media-buy/sync-audiences-response.json
Reference: sync_audiences task
Manage first-party CRM audiences on a seller account. Upload hashed customer lists, check matching status, and reference the resulting audiences in targeting overlays.
Requirements:
- Orchestrators MUST include
account_id - Orchestrators MUST include at least one audience with hashed member data
- Sales agents MUST return per-audience outcomes with matching status
- Sales agents SHOULD support
push_notification_configfor async matching completion - Sales agents MUST accept SHA-256 hashed identifiers for privacy compliance
Error Handling
Sales agents MUST return errors using the standard AdCP error schema. Common error codes:MEDIA_BUY_NOT_FOUND: Referenced media buy does not existPACKAGE_NOT_FOUND: Referenced package does not existPRODUCT_NOT_FOUND: Referenced product does not existBUDGET_EXCEEDED: Operation would exceed allocated budgetCREATIVE_REJECTED: Creative failed content policy reviewCREATIVE_DEADLINE_EXCEEDED: Creative change submitted after the package’screative_deadlineINVALID_STATE: Operation is not permitted for the resource’s current status (e.g., updating a completed or canceled media buy)NOT_CANCELLABLE: Media buy or package cannot be canceled in its current stateVALIDATION_ERROR: Request format or parameter errorsAUTH_REQUIRED: Authentication is required to access this resource
Security Considerations
Transport Security
All Media Buy Protocol communications MUST use HTTPS with TLS 1.2 or higher.Authentication
- Orchestrators MUST authenticate with sales agents using valid credentials
- Sales agents MUST validate credentials before processing requests
- Sales agents MUST use account context to determine inventory access
Budget Authorization
- Sales agents MUST validate that accounts are authorized for requested budget levels
- Sales agents MUST NOT exceed authorized budget limits without explicit approval
Creative Security
- Sales agents MUST validate creative content for policy compliance
- Sales agents SHOULD scan creatives for malware and malicious content
- Sales agents MUST NOT serve creatives that fail security validation
Conformance
Sales Agent Conformance
A conformant Media Buy Protocol sales agent MUST:- Support at least one specified transport (MCP or A2A)
- Implement all tasks per their schemas
- Return required fields as defined in response schemas
- Use specified error codes
- Handle asynchronous operations appropriately
- Enforce authentication and authorization
Orchestrator Conformance
A conformant Media Buy Protocol orchestrator MUST:- Authenticate with sales agents
- Include required fields as defined in request schemas
- Handle asynchronous responses (submitted, working, pending_approval)
- Use
media_buy_idto reference media buys in subsequent operations - Respect
creative_deadlinefor creative uploads
Implementation Notes
Response Time Expectations
Sales agents SHOULD target the following response times:| Operation Type | Target Latency |
|---|---|
| Simple lookups (list_creative_formats) | < 1 second |
| Discovery with AI/LLM (get_products) | < 60 seconds |
| Reporting queries (get_media_buy_delivery) | < 60 seconds |
| Campaign operations (create, update, sync) | Async acceptable |
Idempotency
Sales agents SHOULD support idempotent operations usingidempotency_key:
- If an
idempotency_keyhas been seen before for the same account, sales agents SHOULD return the existing resource - This enables safe retries without duplicate creation
update_media_buy, sync_creatives), orchestrators MAY include an idempotency_key (16-255 characters) for safe retries. If a request fails without a response, resending with the same idempotency_key guarantees at-most-once execution.
Human-in-the-Loop
Sales agents MAY require human approval for any operation. When approval is required:- Sales agents MUST return
status: "pending_approval" - Sales agents SHOULD provide an estimated approval timeline
- Orchestrators SHOULD implement webhook handlers for status updates