Documentation Index Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt
Use this file to discover all available pages before exploring further.
Modify an existing media buy using PATCH semantics. Supports campaign-level and package-level updates.
Response Time : Instant to days (status: completed, working < 120s, or submitted for manual review)
PATCH Semantics : Only specified fields are updated; omitted fields remain unchanged.
Request Schema : /schemas/v2/media-buy/update-media-buy-request.json
Response Schema : /schemas/v2/media-buy/update-media-buy-response.json
Quick Start
Create a media buy, then pause it:
import { testAgent } from '@adcp/client/testing' ;
import { CreateMediaBuyResponseSchema , UpdateMediaBuyResponseSchema } from '@adcp/client' ;
// First, create a media buy to update
const uniqueRef = `test_campaign_ ${ Date . now () } ` ;
// Use dates in the future
const startDate = new Date ();
startDate . setDate ( startDate . getDate () + 7 ); // Start 1 week from now
const endDate = new Date ();
endDate . setDate ( endDate . getDate () + 37 ); // End 5 weeks from now
const createResult = await testAgent . createMediaBuy ({
buyer_ref: uniqueRef ,
brand_manifest: {
name: 'Nike' ,
url: 'https://nike.com'
},
packages: [{
buyer_ref: 'display_pkg' ,
product_id: 'prod_d979b543' ,
pricing_option_id: 'cpm_usd_auction' ,
format_ids: [{
agent_url: 'https://creative.adcontextprotocol.org' ,
id: 'display_300x250_image'
}],
budget: 10000 ,
bid_price: 5.00
}],
start_time: startDate . toISOString (),
end_time: endDate . toISOString ()
});
if ( ! createResult . success ) {
throw new Error ( `Create failed: ${ createResult . error } ` );
}
const created = CreateMediaBuyResponseSchema . parse ( createResult . data );
if ( 'errors' in created && created . errors ) {
throw new Error ( `Create failed: ${ JSON . stringify ( created . errors ) } ` );
}
console . log ( `Created media buy ${ created . media_buy_id } ` );
// Now update it - pause the campaign
const updateResult = await testAgent . updateMediaBuy ({
buyer_ref: uniqueRef ,
paused: true
});
if ( ! updateResult . success ) {
throw new Error ( `Update failed: ${ updateResult . error } ` );
}
const updated = UpdateMediaBuyResponseSchema . parse ( updateResult . data );
if ( 'errors' in updated && updated . errors ) {
throw new Error ( `Update failed: ${ JSON . stringify ( updated . errors ) } ` );
}
console . log ( `Campaign ${ updated . media_buy_id } paused` );
Request Parameters
Parameter Type Required Description media_buy_idstring Yes* Publisher’s media buy identifier to update buyer_refstring Yes* Your reference for the media buy to update start_timestring No Updated campaign start time end_timestring No Updated campaign end time pausedboolean No Pause/resume entire media buy (true = paused, false = active) packagesPackageUpdate[] No Package-level updates (see below) creativesCreativeAsset[] No Upload and assign new creative assets inline creative_assignmentsCreativeAssignment[] No Update creative rotation weights and placement targeting
*Either media_buy_id OR buyer_ref is required (not both)
Package Update Object
Parameter Type Description package_idstring Publisher’s package identifier to update buyer_refstring Your reference for the package to update pausedboolean Pause/resume specific package (true = paused, false = active) budgetnumber Updated budget allocation impressionsnumber Updated impression goal for this package pacingstring Updated pacing strategy bid_pricenumber Updated bid price (auction products only) targeting_overlayTargetingOverlay Updated targeting restrictions creative_idsstring[] Replace assigned creatives
*Either package_id OR buyer_ref is required for each package update
Response
Success Response
Field Description media_buy_idMedia buy identifier buyer_refYour reference identifier implementation_dateISO 8601 timestamp when changes take effect (null if pending approval) affected_packagesArray of full Package objects showing complete state after update
Error Response
Field Description errorsArray of error objects explaining failure
Note : Responses use discriminated unions - you get either success fields OR errors, never both. Always check for errors before accessing success fields.
Common Scenarios
Update Package Budget
Increase budget for a specific package:
test=false JavaScript
test=false Python
import { testAgent } from '@adcp/client/testing' ;
import { UpdateMediaBuyResponseSchema } from '@adcp/client' ;
const result = await testAgent . updateMediaBuy ({
media_buy_id: 'mb_12345' ,
packages: [{
buyer_ref: 'ctv_package' ,
budget: 50000 // Increased from 30000
}]
});
if ( ! result . success ) {
throw new Error ( `Request failed: ${ result . error } ` );
}
const validated = UpdateMediaBuyResponseSchema . parse ( result . data );
if ( 'errors' in validated && validated . errors ) {
throw new Error ( `Update failed: ${ JSON . stringify ( validated . errors ) } ` );
}
const pkg = validated . affected_packages ?. find ( p => p . buyer_ref === 'ctv_package' );
if ( pkg ) {
console . log ( `Package budget updated to ${ pkg . budget } ` );
}
Change Campaign Dates
Extend campaign end date:
test=false JavaScript
test=false Python
import { testAgent } from '@adcp/client/testing' ;
import { UpdateMediaBuyResponseSchema } from '@adcp/client' ;
const result = await testAgent . updateMediaBuy ({
buyer_ref: 'summer_campaign_2025' ,
end_time: '2025-09-30T23:59:59Z'
});
if ( ! result . success ) {
throw new Error ( `Request failed: ${ result . error } ` );
}
const validated = UpdateMediaBuyResponseSchema . parse ( result . data );
if ( 'errors' in validated && validated . errors ) {
throw new Error ( `Update failed: ${ JSON . stringify ( validated . errors ) } ` );
}
console . log ( 'Campaign end date extended' );
console . log ( `Effective: ${ validated . implementation_date } ` );
Update Targeting
Add or modify geographic restrictions:
test=false JavaScript
test=false Python
import { testAgent } from '@adcp/client/testing' ;
import { UpdateMediaBuyResponseSchema } from '@adcp/client' ;
const result = await testAgent . updateMediaBuy ({
media_buy_id: 'mb_12345' ,
packages: [{
buyer_ref: 'ctv_package' ,
targeting_overlay: {
geo_country_any_of: [ 'US' , 'CA' ],
geo_region_any_of: [ 'CA' , 'NY' , 'TX' , 'ON' , 'QC' ]
}
}]
});
if ( ! result . success ) {
throw new Error ( `Request failed: ${ result . error } ` );
}
const validated = UpdateMediaBuyResponseSchema . parse ( result . data );
if ( 'errors' in validated && validated . errors ) {
throw new Error ( `Update failed: ${ JSON . stringify ( validated . errors ) } ` );
}
console . log ( 'Targeting updated successfully' );
Replace Creatives
Swap out creative assets for a package:
test=false JavaScript
test=false Python
import { testAgent } from '@adcp/client/testing' ;
import { UpdateMediaBuyResponseSchema } from '@adcp/client' ;
const result = await testAgent . updateMediaBuy ({
media_buy_id: 'mb_12345' ,
packages: [{
buyer_ref: 'ctv_package' ,
creative_ids: [ 'creative_video_v2' , 'creative_display_v2' ]
}]
});
if ( ! result . success ) {
throw new Error ( `Request failed: ${ result . error } ` );
}
const validated = UpdateMediaBuyResponseSchema . parse ( result . data );
if ( 'errors' in validated && validated . errors ) {
throw new Error ( `Update failed: ${ JSON . stringify ( validated . errors ) } ` );
}
const pkg = validated . affected_packages ?. find ( p => p . buyer_ref === 'ctv_package' );
const assignmentCount = pkg ?. creative_assignments ?. length || 0 ;
console . log ( `Assigned ${ assignmentCount } creatives` );
Multiple Package Updates
Update multiple packages in one call:
test=false JavaScript
test=false Python
import { testAgent } from '@adcp/client/testing' ;
import { UpdateMediaBuyResponseSchema } from '@adcp/client' ;
const result = await testAgent . updateMediaBuy ({
media_buy_id: 'mb_12345' ,
packages: [
{
buyer_ref: 'ctv_package' ,
budget: 50000 ,
pacing: 'front_loaded'
},
{
buyer_ref: 'audio_package' ,
budget: 30000 ,
paused: true
}
]
});
if ( ! result . success ) {
throw new Error ( `Request failed: ${ result . error } ` );
}
const validated = UpdateMediaBuyResponseSchema . parse ( result . data );
if ( 'errors' in validated && validated . errors ) {
throw new Error ( `Update failed: ${ JSON . stringify ( validated . errors ) } ` );
}
console . log ( `Updated ${ validated . affected_packages ?. length || 0 } packages` );
What Can Be Updated
Campaign-Level Updates
✅ Can update:
Start/end times (subject to seller approval)
Campaign status (active/paused)
❌ Cannot update:
Media buy ID
Buyer reference
Brand manifest
Original package product IDs
Package-Level Updates
✅ Can update:
Budget allocation
Pacing strategy
Bid prices (auction products)
Targeting overlays
Creative assignments
Package status (active/paused)
❌ Cannot update:
Package ID
Product ID
Pricing option ID
Format IDs (creatives must match existing formats)
Error Handling
Common errors and resolutions:
Error Code Description Resolution MEDIA_BUY_NOT_FOUNDMedia buy doesn’t exist Verify media_buy_id or buyer_ref PACKAGE_NOT_FOUNDPackage doesn’t exist Verify package_id or buyer_ref UPDATE_NOT_ALLOWEDField cannot be changed See “What Can Be Updated” above BUDGET_INSUFFICIENTNew budget below minimum Increase budget amount POLICY_VIOLATIONUpdate violates content policy Review policy requirements INVALID_STATEOperation not allowed in current state Check campaign status
Example error response:
{
"errors" : [{
"code" : "UPDATE_NOT_ALLOWED" ,
"message" : "Cannot change product_id for existing package" ,
"field" : "packages[0].product_id" ,
"suggestion" : "Create a new package with the desired product instead"
}]
}
Update Approval
Some updates require seller approval and return pending status:
Significant budget increases (threshold varies by seller)
Date range changes affecting inventory availability
Targeting changes that alter campaign scope
Creative changes requiring policy review
When approval is needed, implementation_date will be null:
{
"media_buy_id" : "mb_12345" ,
"buyer_ref" : "summer_campaign_2025" ,
"implementation_date" : null ,
"affected_packages" : []
}
PATCH Semantics
Only specified fields are updated - omitted fields remain unchanged:
{
"buyer_ref" : "summer_campaign_2025" ,
"packages" : [{
"buyer_ref" : "ctv_package" ,
"budget" : 50000
}]
}
Array replacement : When updating arrays (like creative_ids), provide the complete new array:
{
"packages" : [{
"buyer_ref" : "ctv_package" ,
"creative_ids" : [ "creative_video_v2" , "creative_display_v2" ]
}]
}
Asynchronous Operations
Updates may be asynchronous, especially with seller approval.
Response Patterns
Synchronous (completed immediately) :
{
"media_buy_id" : "mb_12345" ,
"buyer_ref" : "summer_campaign_2025" ,
"implementation_date" : "2025-06-15T10:00:00Z" ,
"affected_packages" : []
}
Asynchronous (processing) :
{
"status" : "working" ,
"message" : "Processing update..."
}
Poll for completion or use webhooks/streaming.
Manual Approval Required :
{
"status" : "submitted" ,
"message" : "Update requires seller approval (2-4 hours)"
}
Will take hours to days.
Protocol-Specific Handling
AdCP tasks work across multiple protocols (MCP, A2A, REST). Each protocol handles async operations differently:
Status checking : Polling, webhooks, or streaming
Updates : Protocol-specific mechanisms
Long-running tasks : Different timeout and notification patterns
See Task Management for protocol-specific async patterns and examples.
Best Practices
1. Use Precise Updates
Update only what needs to change - don’t resend unchanged values.
2. Budget Increases
Small incremental increases are more likely to be auto-approved than large jumps.
3. Pause Before Major Changes
Pause campaigns before making significant targeting or creative changes to avoid delivery issues.
4. Test with Small Changes
Test update workflows with minor changes before critical campaign modifications.
5. Monitor Status
Always check response status and implementation_date for approval requirements.
6. Validate Package State
Check affected_packages in response to confirm changes were applied correctly.
Usage Notes
Updates are atomic - either all changes apply or none do
Both media buys and packages can be referenced by buyer_ref or publisher IDs
Pending states (working, submitted) are normal, not errors
Orchestrators MUST handle pending states as part of normal workflow
implementation_date indicates when changes take effect (null if pending approval)
Next Steps
After updating a media buy:
Verify Changes : Use get_media_buy_delivery to confirm updates
Upload New Creatives : Use sync_creatives if creative_ids changed
Monitor Performance : Track impact of changes on campaign metrics
Optimize Further : Use provide_performance_feedback for ongoing optimization
Learn More