AdCP 3.1.13 · Negotiation layer

AdCP Media Buy

AdCP Media Buy is a schema group of the Ad Context Protocol holding 11 of the 64 operations in release 3.1.13, covering product discovery, campaign creation and updates, delivery reporting, conversion tracking, and audience and catalog sync.

The media buy group covers the buying cycle itself: get_products for discovery, create_media_buy and update_media_buy for the buy, get_media_buy_delivery for reporting, and the sync_* operations for the audiences, catalogs and conversion sources a buy refers to.

7 of the 11 write state and require idempotency_key. The other 4 are reads. adcp_version on the wire takes "3.1": the patch component of 3.1.13 identifies the bundle of schema files these tables describe and is never sent.

The order these are called in

Nothing in the registry declares a sequence. One order the schemas permit is get_products to discover inventory, then create_media_buy to commit budget to it, then sync_creatives to attach creatives, then update_media_buy for every later change, pausing included, then get_media_buy_delivery to read what ran. sync_creatives is not in this group: it lives in the creative group, and a buy with no creatives sits in pending_creatives and does not serve. The buy clears either by polling or by passing create_media_buy a push_notification_config.

The sync_* operations and log_event run alongside that sequence rather than inside it. They load the audiences, catalogs and conversion sources a buy refers to, and continue to be called long after the campaign is set up.

What the 11 media buy operations do

Media Buy — 11 operations
Operation Request fields Response fields What it does
create_media_buy 22 13 create_media_buy task — create advertising campaigns in AdCP from discovered products.
get_media_buy_delivery 14 26 get_media_buy_delivery task — retrieve impressions, spend, pacing, and dimensional breakdowns for active AdCP campaigns.
get_media_buys 12 18 get_media_buys task — retrieve media buy status in AdCP including creative approvals, missing assets, configuration, and optional near-real-time delivery snapshots.
get_products 20 29 get_products task — discover advertising inventory in AdCP using natural language campaign briefs or structured filters.
list_creative_formats 20 20 Request parameters for discovering supported creative formats
log_event 8 13 log_event task — send conversion and marketing events to AdCP sellers in batches.
provide_performance_feedback 12 13 provide_performance_feedback task — share normalized performance scores with AdCP publishers so sellers can optimize delivery based on buyer-observed outcomes.
sync_audiences 8 13 sync_audiences task — upload hashed first-party CRM audiences to AdCP seller accounts for retargeting, suppression, and lookalike expansion.
sync_catalogs 12 13 sync_catalogs task — sync product feeds, store locations, and vertical catalogs (hotel, flight, vehicle, real estate) to AdCP seller accounts for catalog-driven campaigns.
sync_event_sources 8 13 sync_event_sources task — configure website pixels, mobile SDKs, server-to-server integrations, and seller- or platform-native event sources on AdCP seller accounts for conversion tracking and attribution.
update_media_buy 18 13 update_media_buy task — modify active AdCP campaigns with PATCH semantics.

Response shape for writes and reads

A client generated from these schemas types cleanly on the read side. Every write returns a union that has to be discriminated in client code. 7 of the 11 responses declare no fields of their own, so their response column repeats the same 13 envelope fields.

Every operation except report_plan_outcome and check_governance returns the full envelope. 13 keys, four of which carry the protocol behaviour: task_id to follow asynchronous work, status for the lifecycle of the task itself, adcp_error for fatal failures, and payload, which core/protocol-envelope.json calls a documentary construct and states is not a required wire field. Version, context and governance keys make up the rest.

In dist/schemas/3.1.13/media-buy/create-media-buy-response.json, properties is an empty object and the shape sits in three oneOf branches named CreateMediaBuySuccess, CreateMediaBuyError and CreateMediaBuySubmitted. Every operation declaring x-mutates-state: true carries its result in a branch like that. The 4 that omit the annotation put the result at the top level, where get_products returns products and get_media_buys returns media_buys.

Those same 7 are the only operations here that require idempotency_key. The annotation is opt-in and absent on reads rather than set false, so its absence carries no guarantee: si_terminate_session and comply_test_controller mutate state without requiring idempotency_key. Whether a call requires the key is stated in its request schema, not inferred from x-mutates-state.

<code>status</code> versus <code>media_buy_status</code>

status describes the task, not the object the task acted on. A media buy's own state (pending_creatives, pending_start, active, paused, completed, rejected, canceled) moved to media_buy_status in 3.1, and the response schema states it: "the status key is reserved for the envelope TaskStatus". Polling status returns the state of the last request, not the state of the campaign.

What the documentation tree lists

Membership of this group is decided by one file, dist/schemas/3.1.13/index.json, and no page in the documentation tree lists the same 11 operations. docs/media-buy/task-reference/index.mdx lists 13 tasks under All Tasks Overview: three of them (get_adcp_capabilities, sync_creatives, list_creatives) are registered under other schema groups, and the sales-agent list_creative_formats, which the registry does file under media buy, is absent from that table.

delete_missing turns a sync into a delete

All three sync_* operations here accept delete_missing, and it defaults off. Set it and the request stops being an upsert: it becomes the complete desired state of that collection on the account named in the required account field, and anything omitted is removed. The schema states the effect: "buyer-managed catalogs on the account not included in this sync will be removed".

The schema defines no way to signal a partial payload, so a request truncated by a client-side pagination failure removes every item it omitted. sync_catalogs accepts dry_run to rehearse against; sync_audiences and sync_event_sources do not.

Asynchronous replies and callbacks

4 operations here accept push_notification_config (create_media_buy, get_products, sync_catalogs, update_media_buy), and those are the 4 here with a published async response arm, out of seven registry-wide that publish one. sync_audiences is the exception: it can answer with a SyncAudiencesSubmitted branch, so it can defer, but it carries no push config, so no callback can be requested for it.

What a version pin covers

media_buy_status arriving in 3.1 was a permitted change. AdCP numbers releases VERSION.RELEASE.PATCH, and docs/reference/versioning.mdx allows a release to change schema at the margins: flip a field between required and optional, rename one with a documented alias, tighten validation, deprecate an object when its replacement ships in the same release. The compensating guarantee is that "implementations built against 3.0 will continue to function against any 3.x release".

Negotiation runs at release precision. The spec rejects an adcp_version value carrying a patch component, so a client pins to the release, sends "3.1", and can expect field-level movement inside it.

Two different operations are called list_creative_formats

list_creative_formats is registered twice in 3.1.13, once here and once in the creative group, against request schemas that differ. The variant documented here is the media buy version; both are set out on the schema registry page.

create_media_buy

create_media_buy task — create advertising campaigns in AdCP from discovered products.

Every field and edge case for create_media_buy

create_media_buy request — 22 fields, 5 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
idempotency_keystringrequiredClient-generated unique key for this request.
plan_idstringCampaign governance plan identifier.
accountaccount-refrequiredAccount to bill for this media buy.
proposal_idstringID of a committed proposal from get_products to execute.
total_budgetobjectTotal budget for the media buy when executing a proposal.
packagespackage-request[]Array of package configurations.
brandbrand-refrequiredBrand reference for this media buy.
advertiser_industryadvertiser-industryIndustry classification for this specific campaign. One of: automotive, automotive.electric_vehicles, automotive.parts_accessories, automotive.luxury, beauty_cosmetics, beauty_cosmetics.skincare, beauty_cosmetics.fragrance, beauty_cosmetics.haircare, cannabis, cpg, cpg.personal_care, cpg.household, dating, education, education.higher_education, education.online_learning, education.k12, energy_utilities, energy_utilities.renewable, fashion_apparel, fashion_apparel.luxury, fashion_apparel.sportswear, finance, finance.banking.
invoice_recipientbusiness-entityOverride the account's default billing entity for this specific buy.
io_acceptanceobjectAcceptance of an insertion order from a committed proposal.
po_numberstringPurchase order number for tracking
agency_estimate_numberstringAgency estimate or authorization number.
start_timestart-timingrequiredCampaign start timing: 'asap' or ISO 8601 date-time
end_timestringrequiredCampaign end date/time in ISO 8601 format
pausedbooleanCreate the media buy in a paused delivery state.
push_notification_configpush-notification-configOptional webhook configuration for async task status notifications.
reporting_webhookreporting-webhookOptional webhook configuration for automated reporting delivery
artifact_webhookobjectOptional webhook configuration for content artifact delivery.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
create_media_buy response — 13 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextPer-request opaque caller-supplied correlation object echoed unchanged in the response.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
create_media_buy — Example (javascript) — source
import { testAgent } from '@adcp/sdk/testing';
import { CreateMediaBuyResponseSchema } from '@adcp/sdk';

// Calculate dates dynamically - start tomorrow, end in 90 days
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(0, 0, 0, 0);
const endDate = new Date(tomorrow);
endDate.setDate(endDate.getDate() + 90);

const result = await testAgent.createMediaBuy({
  brand: {
    domain: 'acmecorp.com'
  },
  packages: [
    {
      product_id: 'prod_d979b543',
      pricing_option_id: 'cpm_usd_auction',
      format_option_refs: [{ scope: 'product', format_option_id: 'display_300x250_image' }],
      budget: 2500,
      bidding: { bid_amount: 5.00 }
    },
    {
      product_id: 'prod_e8fd6012',
      pricing_option_id: 'cpm_usd_auction',
      format_option_refs: [{ scope: 'product', format_option_id: 'display_300x250_html' }],
      budget: 2500,
      bidding: { bid_amount: 4.50 }
    }
  ],
  start_time: tomorrow.toISOString(),
  end_time: endDate.toISOString()
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

// Validate response against schema
const validated = CreateMediaBuyResponseSchema.parse(result.data);

// Check for errors (discriminated union response)
if ('errors' in validated && validated.errors) {
  throw new Error(`Failed to create media buy: ${JSON.stringify(validated.errors)}`);
}

if ('media_buy_id' in validated) {
  console.log(`Created media buy ${validated.media_buy_id}`);
  console.log(`Upload creatives by: ${validated.creative_deadline}`);
  console.log(`Packages created: ${validated.packages.length}`);
}

get_media_buy_delivery

get_media_buy_delivery task — retrieve impressions, spend, pacing, and dimensional breakdowns for active AdCP campaigns.

get_media_buy_delivery request — 14 fields, 0 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
accountaccount-refFilter delivery data to a specific account.
media_buy_idsstring[]Array of media buy IDs to get delivery data for
status_filterone of severalFilter by status.
start_datestringStart date for reporting period (YYYY-MM-DD).
end_datestringEnd date for reporting period (YYYY-MM-DD).
include_package_daily_breakdownbooleanWhen true, include daily_breakdown arrays within each package in by_package.
time_granularityreporting-frequencyPer-window slice granularity for the pull, using the same vocabulary as reporting_webhook.reporting_frequency. One of: hourly, daily, monthly.
include_window_breakdownbooleanWhen true, the response includes media_buy_deliveries[].windows[] — an array of per-window delivery slices over the date range at the requested time_granularity.
attribution_windowobjectAttribution window to apply for conversion metrics.
reporting_dimensionsobjectRequest dimensional breakdowns in delivery reporting.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
get_media_buy_delivery response — 26 fields, 4 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextOpaque correlation data that is echoed unchanged in responses.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
notification_typestringType of webhook notification (only present in webhook deliveries): scheduled = regular periodic update, final = campaign completed, delayed = data not yet available, adjusted = resending period with corrected data (same… One of: scheduled, final, delayed, adjusted, window_update.
partial_databooleanIndicates if any media buys in this webhook have missing/delayed data (only present in webhook deliveries)
unavailable_countintegerNumber of media buys with reporting_delayed or failed status (only present in webhook deliveries when partial_data is true)
sequence_numberintegerSequential notification number (only present in webhook deliveries, starts at 1)
next_expected_atstringISO 8601 timestamp for next expected notification (only present in webhook deliveries when notification_type is not 'final')
reporting_periodobjectrequiredDate range for the report.
currencystringrequiredISO 4217 currency code
attribution_windowattribution-windowAttribution methodology and lookback windows used for conversion metrics in this response.
aggregated_totalsobjectCombined metrics across all returned media buys.
media_buy_deliveriesobject[]requiredArray of delivery data for media buys.
errorserror[]Task-specific errors and warnings (e.g., missing delivery data, reporting platform issues)
sandboxbooleanWhen true, this response contains simulated data from sandbox mode.
extextExtension object for platform-specific, vendor-namespaced parameters.
get_media_buy_delivery — Example (json) — source
{
  "aggregated_totals": {
    "impressions": 1000000,
    "spend": 5000.00,
    "media_buy_count": 3,
    "metric_aggregates": [
      {
        "scope": "standard",
        "metric_id": "viewable_rate",
        "qualifier": { "viewability_standard": "mrc" },
        "value": 0.7286,
        "measurable_impressions": 700000,
        "viewable_impressions": 510000
      },
      {
        "scope": "standard",
        "metric_id": "viewable_rate",
        "qualifier": { "viewability_standard": "groupm" },
        "value": 0.55,
        "measurable_impressions": 180000,
        "viewable_impressions": 99000
      }
    ]
  }
}

get_media_buys

get_media_buys task — retrieve media buy status in AdCP including creative approvals, missing assets, configuration, and optional near-real-time delivery snapshots.

get_media_buys request — 12 fields, 0 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
accountaccount-refAccount to retrieve media buys for.
media_buy_idsstring[]Array of media buy IDs to retrieve.
status_filterone of severalFilter by status.
include_snapshotbooleanWhen true, include a near-real-time delivery snapshot for each package.
include_historyintegerWhen present, include the last N revision history entries for each media buy (returns min(N, available entries)).
include_webhook_activitybooleanWhen true, each returned media buy includes a `webhook_activity` array describing recent delivery-report webhook fires for the calling principal.
webhook_activity_limitintegerMaximum number of webhook delivery records to return per media buy, ordered most-recent first.
paginationpagination-requestCursor-based pagination controls.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
get_media_buys response — 18 fields, 2 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextOpaque correlation data that is echoed unchanged in responses.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
media_buysobject[]requiredArray of media buys with status, creative approval state, and optional delivery snapshots
errorserror[]Task-specific errors (e.g., media buy not found)
paginationpagination-responsePagination metadata for the media_buys array.
sandboxbooleanWhen true, this response contains simulated data from sandbox mode.
extextExtension object for platform-specific, vendor-namespaced parameters.
get_media_buys — Example (typescript) — source
import { testAgent } from '@adcp/sdk/testing';
import { GetMediaBuysResponseSchema, type WebhookActivityRecord } from '@adcp/sdk';

// The WebhookActivityRecord type is regenerated by the SDK from
// /schemas/core/webhook-activity-record.json — once the SDK rebuilds against this
// branch's schemas the import resolves. The same type appears on every AdCP resource
// that surfaces webhook_activity[], so debug helpers can be written once and reused.
function latestAttempt(trail: WebhookActivityRecord[]): WebhookActivityRecord {
  return trail.reduce((a, b) => (a.attempt >= b.attempt ? a : b));
}

const result = await testAgent.getMediaBuys({
  media_buy_ids: ['mb_12345'],
  include_webhook_activity: true,
  webhook_activity_limit: 20,
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = GetMediaBuysResponseSchema.parse(result.data);

for (const mediaBuy of validated.media_buys) {
  // Three-state semantics — distinguish "seller does not surface" from "no recent fires".
  if (mediaBuy.webhook_activity === undefined) {
    console.log(`${mediaBuy.media_buy_id}: seller does not surface webhook activity for this buy`);
    continue;
  }

  const fires = mediaBuy.webhook_activity;
  if (fires.length === 0) {
    console.log(`${mediaBuy.media_buy_id}: no recent fires for this principal`);
    continue;
  }

  // Group attempts by idempotency_key so we can see the retry trail per logical fire.
  const trails = new Map();
  for (const fire of fires) {
    const trail = trails.get(fire.idempotency_key) ?? [];
    trail.push(fire);
    trails.set(fire.idempotency_key, trail);
  }

  for (const [idempotencyKey, trail] of trails) {
    // Pick the latest attempt by `attempt` number — robust against any iteration order.
    const latest = latestAttempt(trail);
    if (latest.status === 'success') continue;

    const detail = latest.error_message ?? latest.http_status_code ?? '—';
    console.log(
      `${mediaBuy.media_buy_id} ${idempotencyKey} ` +
      `(${latest.notification_type} seq=${latest.sequence_number}): ` +
      `${latest.status} after ${trail.length} attempt(s) — ${detail}`
    );
  }
}

get_products

get_products task — discover advertising inventory in AdCP using natural language campaign briefs or structured filters.

Every field and edge case for get_products

get_products request — 20 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
buying_modestringrequiredDeclares buyer intent for this request. One of: brief, wholesale, refine.
briefstringNatural language description of campaign requirements.
refineobject[]Array of change requests for iterating on products and proposals from a previous get_products response.
brandbrand-refBrand reference for product discovery context.
catalogcatalogCatalog of items the buyer wants to promote.
accountaccount-refAccount for product lookup.
preferred_delivery_typesdelivery-type[]Delivery types the buyer prefers, in priority order.
filtersproduct-filtersStructured filters for product discovery
property_listproperty-list-ref[AdCP 3.0] Reference to an externally managed property list.
fieldsstring[]Specific product fields to include in the response. One of: product_id, name, description, publisher_properties, channels, video_placement_types, audio_distribution_types, sponsored_placement_types, social_placement_surfaces, format_ids, format_options, placements, delivery_type, exclusivity, pricing_options, forecast, outcome_measurement, delivery_measurement, reporting_capabilities, creative_policy, catalog_types, metric_optimization, conversion_tracking, data_provider_signals.
time_budgetobjectMaximum time the buyer will commit to this request.
push_notification_configpush-notification-configOptional webhook configuration for async terminal completion/failure notifications on curated discovery.
paginationpagination-requestCursor-based pagination controls for get_products.
if_wholesale_feed_versionstringOpaque wholesale_feed_version token returned by a prior wholesale-mode get_products response from this agent.
if_pricing_versionstringOpaque pricing_version token from a prior get_products response.
contextcontextOpaque correlation data that is echoed unchanged in responses.
required_policiesstring[]Registry policy IDs that the buyer requires to be enforced for products in this response.
extextExtension object for platform-specific, vendor-namespaced parameters.
get_products response — 29 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextOpaque correlation data that is echoed unchanged in responses.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
productsproduct[]Array of matching products
extensionsobjectBundled platform-extension definitions referenced by any product in `products`.
proposalsproposal[]Optional array of proposed media plans with budget allocations across products.
errorserror[]Task-specific errors and warnings (e.g., product filtering issues)
property_list_appliedboolean[AdCP 3.0] Indicates whether property_list filtering was applied.
catalog_appliedbooleanWhether the seller filtered results based on the provided catalog.
refinement_appliedobject[]Seller's response to each change request in the refine array, matched by position.
incompleteobject[]Declares what the seller could not finish within the buyer's time_budget or due to internal limits.
filter_diagnosticsobjectOptional non-fatal diagnostic block describing how the request's `filters` narrowed the candidate set.
paginationpagination-responseCursor metadata for paginated get_products responses.
wholesale_feed_versionstringOpaque token representing the version of the wholesale product feed state used to compose this response.
pricing_versionstringOpaque token representing the version of the pricing layer, including product pricing_options and nested signal_targeting_options pricing_options.
cache_scopestringDeclares whether the wholesale_feed_version and pricing_version on this response describe a universal layer or an account-specific overlay. One of: public, account.
unchangedbooleanPresent and `true` ONLY on wholesale-mode responses when the request carried if_wholesale_feed_version (and/or if_pricing_version) matching the seller's current version for the buyer's cache_scope, in which case product…
sandboxbooleanWhen true, this response contains simulated data from sandbox mode.
extextExtension object for platform-specific, vendor-namespaced parameters.
get_products — Example (javascript) — source
import { testAgent } from '@adcp/sdk/testing';
import { GetProductsResponseSchema } from '@adcp/sdk';

const result = await testAgent.getProducts({
  buying_mode: 'brief',
  brief: 'Premium athletic footwear with innovative cushioning',
  brand: {
    domain: 'acmecorp.com'
  }
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

// Validate response against schema
const validated = GetProductsResponseSchema.parse(result.data);
if (validated.status === 'rejected') {
  console.log(`Seller declined the brief: ${validated.reason}`);
  for (const suggestion of validated.suggestions ?? []) {
    console.log(`- ${suggestion}`);
  }
} else {
  console.log(`Found ${validated.products.length} products`);

  // Access validated product fields
  for (const product of validated.products) {
    console.log(`- ${product.name} (${product.delivery_type})`);
    console.log(`  Formats: ${product.format_options.map(option => option.format_kind).join(', ')}`);
  }
}

list_creative_formats

Request parameters for discovering supported creative formats

list_creative_formats request — 20 fields, 0 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
format_idsformat-id[]Return only these specific format IDs (e.g., from get_products response)
asset_typesasset-content-type[]Filter to formats that include these asset types.
max_widthintegerMaximum width in pixels (inclusive).
max_heightintegerMaximum height in pixels (inclusive).
min_widthintegerMinimum width in pixels (inclusive).
min_heightintegerMinimum height in pixels (inclusive).
is_responsivebooleanFilter for responsive formats that adapt to container size.
name_searchstringSearch for formats by name (case-insensitive partial match)
publisher_domainstringFilter to formats supported by the named publisher.
property_idproperty-idFilter to formats supported on the named property within the publisher's catalog.
wcag_levelwcag-levelFilter to formats that meet at least this WCAG conformance level (A < AA < AAA) One of: A, AA, AAA.
disclosure_positionsdisclosure-position[]Filter to formats that support all of these disclosure positions.
disclosure_persistencedisclosure-persistence[]Filter to formats where each requested persistence mode is supported by at least one position in disclosure_capabilities.
output_format_idsformat-id[]Filter to formats whose output_format_ids includes any of these format IDs.
input_format_idsformat-id[]Filter to formats whose input_format_ids includes any of these format IDs.
paginationpagination-requestStandard cursor-based pagination parameters for list operations
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
list_creative_formats response — 20 fields, 2 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextOpaque correlation data that is echoed unchanged in responses.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
formatsformat[]requiredFull format definitions for all formats this agent supports.
sourcestringWhich tier of the resolution order produced this `formats[]` list when the request carried a `publisher_domain` filter. One of: publisher, aao_mirror, agent_derived.
creative_agentsobject[]Optional: Creative agents that provide additional formats.
errorserror[]Task-specific errors and warnings (e.g., format availability issues)
paginationpagination-responseStandard cursor-based pagination metadata for list responses
sandboxbooleanWhen true, this response contains simulated data from sandbox mode.
extextExtension object for platform-specific, vendor-namespaced parameters.

log_event

log_event task — send conversion and marketing events to AdCP sellers in batches.

log_event request — 8 fields, 3 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
event_source_idstringrequiredEvent source configured on the account via sync_event_sources
test_event_codestringTest event code for validation without affecting production data.
eventsevent[]requiredEvents to log
idempotency_keystringrequiredClient-generated unique key for this request.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
log_event response — 13 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextPer-request opaque caller-supplied correlation object echoed unchanged in the response.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
log_event — Example (javascript) — source
import { testAgent } from "@adcp/sdk/testing";
import { LogEventResponseSchema } from "@adcp/sdk";

const result = await testAgent.logEvent({
  event_source_id: "website_pixel",
  events: [
    {
      event_id: "evt_purchase_12345",
      event_type: "purchase",
      event_time: "2026-01-15T14:30:00Z",
      action_source: "website",
      event_source_url: "https://www.example.com/checkout/confirm",
      user_match: {
        click_id: "abc123def456",
        click_id_type: "gclid",
      },
      custom_data: {
        value: 149.99,
        currency: "USD",
        order_id: "order_98765",
        num_items: 3,
      },
    },
  ],
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

// Validate response against schema
const validated = LogEventResponseSchema.parse(result.data);

// Check for operation-level errors first (discriminated union)
if ("errors" in validated && validated.errors) {
  throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
}

if ("events_received" in validated) {
  console.log(`Received: ${validated.events_received}, Processed: ${validated.events_processed}`);
  if (validated.match_quality !== undefined) {
    console.log(`Match quality: ${(validated.match_quality * 100).toFixed(0)}%`);
  }
}

provide_performance_feedback

provide_performance_feedback task — share normalized performance scores with AdCP publishers so sellers can optimize delivery based on buyer-observed outcomes.

provide_performance_feedback request — 12 fields, 4 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
media_buy_idstringrequiredSeller's media buy identifier
idempotency_keystringrequiredClient-generated unique key for this request.
measurement_perioddatetime-rangerequiredTime period for performance measurement
performance_indexnumberrequiredNormalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)
package_idstringSpecific package within the media buy (if feedback is package-specific)
creative_idstringSpecific creative asset (if feedback is creative-specific)
metric_typemetric-typeThe business metric being measured One of: overall_performance, conversion_rate, brand_lift, click_through_rate, completion_rate, viewability, brand_safety, cost_efficiency.
feedback_sourcefeedback-sourceSource of the performance data One of: buyer_attribution, third_party_measurement, platform_analytics, verification_partner.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
provide_performance_feedback response — 13 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextPer-request opaque caller-supplied correlation object echoed unchanged in the response.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
provide_performance_feedback — Example (json) — source
{
  "success": "boolean",
  "message": "string"
}

sync_audiences

sync_audiences task — upload hashed first-party CRM audiences to AdCP seller accounts for retargeting, suppression, and lookalike expansion.

sync_audiences request — 8 fields, 2 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
idempotency_keystringrequiredClient-generated unique key for at-most-once execution.
accountaccount-refrequiredAccount to manage audiences for.
audiencesobject[]Audiences to sync (create or update).
delete_missingbooleanWhen true, buyer-managed audiences on the account not included in this sync will be removed.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
sync_audiences response — 13 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextPer-request opaque caller-supplied correlation object echoed unchanged in the response.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
sync_audiences — Example (javascript) — source
import { testAgent } from "@adcp/sdk/testing";
import { SyncAudiencesResponseSchema } from "@adcp/sdk";
import { createHash } from "crypto";

const hashEmail = (email) =>
  createHash("sha256").update(email.toLowerCase().trim()).digest("hex");

const hashPhone = (e164Phone) =>
  createHash("sha256").update(e164Phone).digest("hex");

const result = await testAgent.syncAudiences({
  account: { account_id: "acct_12345" },
  audiences: [
    {
      audience_id: "existing_customers",
      name: "Existing customers",
      add: [
        { external_id: "crm_1001", hashed_email: hashEmail("alice@example.com") },
        { external_id: "crm_1002", hashed_email: hashEmail("bob@example.com"), hashed_phone: hashPhone("+12065551234") },
      ],
    },
  ],
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

const validated = SyncAudiencesResponseSchema.parse(result.data);

// Three-shape discriminated union: errors | submitted | audiences
if ("status" in validated && validated.status === "submitted") {
  // Whole sync queued asynchronously — poll tasks/get with task_id or await webhook
  console.log(`Sync queued as task ${validated.task_id}: ${validated.message ?? ""}`);
} else if ("errors" in validated && validated.errors && !("audiences" in validated)) {
  throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
} else if ("audiences" in validated) {
  for (const audience of validated.audiences) {
    console.log(`${audience.audience_id}: ${audience.action} (${audience.status ?? "n/a"})`);
    if (audience.status === "ready") {
      console.log(`  Matched ${audience.matched_count} of ${audience.uploaded_count} members (this sync)`);
    }
  }
}

sync_catalogs

sync_catalogs task — sync product feeds, store locations, and vertical catalogs (hotel, flight, vehicle, real estate) to AdCP seller accounts for catalog-driven campaigns.

sync_catalogs request — 12 fields, 2 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
idempotency_keystringrequiredClient-generated unique key for at-most-once execution.
accountaccount-refrequiredAccount that owns these catalogs.
catalogscatalog[]Array of catalog feeds to sync (create or update).
catalog_idsstring[]Optional filter to limit sync scope to specific catalog IDs.
delete_missingbooleanWhen true, buyer-managed catalogs on the account not included in this sync will be removed.
dry_runbooleanWhen true, preview changes without applying them.
validation_modevalidation-modeValidation strictness. One of: strict, lenient.
push_notification_configpush-notification-configOptional webhook configuration for async sync notifications.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
sync_catalogs response — 13 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextPer-request opaque caller-supplied correlation object echoed unchanged in the response.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
sync_catalogs — Example (json) — source
{
  "account": { "account_id": "acct_acmecorp" },
  "catalogs": [
    {
      "catalog_id": "product-feed",
      "name": "Acme Product Catalog",
      "type": "product",
      "url": "https://feeds.acmecorp.com/products.xml",
      "feed_format": "google_merchant_center",
      "update_frequency": "daily"
    }
  ]
}

sync_event_sources

sync_event_sources task — configure website pixels, mobile SDKs, server-to-server integrations, and seller- or platform-native event sources on AdCP seller accounts for conversion tracking and attribution.

sync_event_sources request — 8 fields, 2 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
idempotency_keystringrequiredClient-generated unique key for at-most-once execution.
accountaccount-refrequiredAccount to configure event sources for.
event_sourcesobject[]Event sources to sync (create or update).
delete_missingbooleanWhen true, event sources not included in this sync will be removed
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
sync_event_sources response — 13 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextPer-request opaque caller-supplied correlation object echoed unchanged in the response.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
sync_event_sources — Example (javascript) — source
import { testAgent } from "@adcp/sdk/testing";
import { SyncEventSourcesResponseSchema } from "@adcp/sdk";

const result = await testAgent.syncEventSources({
  account: { account_id: "acct_12345" },
  event_sources: [
    {
      event_source_id: "website_pixel",
      name: "Main Website Pixel",
      event_types: ["purchase", "lead", "add_to_cart"],
      allowed_domains: ["www.example.com", "shop.example.com"],
    },
  ],
});

if (!result.success) {
  throw new Error(`Request failed: ${result.error}`);
}

// Validate response against schema
const validated = SyncEventSourcesResponseSchema.parse(result.data);

// Check for operation-level errors first (discriminated union)
if ("errors" in validated && validated.errors) {
  throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
}

if ("event_sources" in validated) {
  for (const source of validated.event_sources) {
    console.log(`${source.event_source_id}: ${source.action}`);
    if (source.setup?.snippet) {
      console.log(`  Install: ${source.setup.snippet_type}`);
    }
  }
}

update_media_buy

update_media_buy task — modify active AdCP campaigns with PATCH semantics.

update_media_buy request — 18 fields, 3 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
accountaccount-refrequiredAccount that owns this media buy.
media_buy_idstringrequiredSeller's ID of the media buy to update
revisionintegerExpected current revision for optimistic concurrency.
pausedbooleanPause/resume the entire media buy (true = paused, false = active)
canceledbooleanCancel the entire media buy.
cancellation_reasonstringReason for cancellation.
start_timestart-timingCampaign start timing: 'asap' or ISO 8601 date-time
end_timestringNew end date/time in ISO 8601 format
packagespackage-update[]Package-specific updates for existing packages
invoice_recipientbusiness-entityUpdate who receives the invoice for this buy.
new_packagespackage-request[]New packages to add to this media buy.
reporting_webhookreporting-webhookOptional webhook configuration for automated reporting delivery.
push_notification_configpush-notification-configOptional webhook configuration for async update notifications.
idempotency_keystringrequiredClient-generated idempotency key for safe retries.
contextcontextOpaque correlation data that is echoed unchanged in responses.
extextExtension object for platform-specific, vendor-namespaced parameters.
update_media_buy response — 13 fields, 1 required
FieldTypeRequiredDescription
adcp_versionstringRelease-precision AdCP version (VERSION.RELEASE, e.g.
adcp_major_versionintegerDEPRECATED in favor of adcp_version (release-precision string).
context_idstringSession/conversation identifier for tracking related operations across multiple task invocations.
contextcontextPer-request opaque caller-supplied correlation object echoed unchanged in the response.
task_idstringUnique identifier for tracking asynchronous operations.
statustask-statusrequiredCurrent task execution state. One of: submitted, working, input-required, completed, canceled, failed, rejected, auth-required, unknown.
messagestringHuman-readable summary of the task result.
timestampstringISO 8601 timestamp when the response was generated.
replayedbooleanSet to true when this response was returned from the idempotency cache rather than from a fresh execution.
adcp_errorerrorTransport-envelope error signal for fatal task failures.
push_notification_configpush-notification-configPush notification configuration for async task updates (A2A and REST protocols).
governance_contextstringGovernance context token issued by the account's governance agent during check_governance.
payloadobjectConceptual grouping for the task-specific response data defined by individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json).
update_media_buy — Example (javascript) — source
import { testAgent } from '@adcp/sdk/testing';
import { CreateMediaBuyResponseSchema, UpdateMediaBuyResponseSchema } from '@adcp/sdk';

// 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({
  brand: { domain: 'acmecorp.com' },
  packages: [{
    product_id: 'prod_d979b543',
    pricing_option_id: 'cpm_usd_fixed',
    format_option_refs: [{ scope: 'product', format_option_id: 'display_300x250_image' }],
    budget: 800,
    bidding: { bid_amount: 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({
  account: { brand: { domain: 'acmecorp.com' }, operator: 'acmecorp.com' },
  media_buy_id: created.media_buy_id,
  revision: created.revision,
  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`);

Pausing and cancelling a media buy

No operation name in the registry contains "pause", "stop" or "resume". The two names carrying a destructive verb are delete_property_list and delete_collection_list, and both act on governance lists rather than on campaigns.

Pause state is carried by a field. update_media_buy takes paused: true to hold the whole buy and paused: false to release it, and each entry in packages[] carries its own paused, so one package can be held while the rest keeps serving. A buy can also start held: create_media_buy accepts paused to "create the media buy in a paused delivery state".

canceled is declared "const": true, so true is the only value the schema accepts and no un-cancel is expressible. The description reads: "Cancellation is irreversible — canceled media buys cannot be reactivated. Sellers MAY reject with NOT_CANCELLABLE if the media buy cannot be canceled in its current state." NOT_CANCELLABLE is one of 92 codes in enums/error-code.json.

A paused buy reports the state in media_buy_status, one of that field's seven values, and not in the envelope's status.

Two agents editing the same buy

update_media_buy takes a revision. It is optional, for backward compatibility, and no other field in the protocol carries a concurrency token. When it is sent, the seller must reject a stale write with CONFLICT and must make that comparison atomically with the write. The value comes from get_media_buys or from the most recent create or update response.

If revision is omitted, the seller performs the write unconditionally. Concurrent updates resolve last-write-wins, both callers receive a success response, and no field records the overwrite. Where more than one system can modify a buy — a bidder and an operator in a UI — revision is the guard the protocol defines for it.

Conversion tracking: event sources, logging and feedback

sync_event_sources registers where events come from. A source supplies one required field, its event_source_id; the action_source tag (website, app, in_store and six others) is optional, as is everything else. The response returns a seller_id for each source, the seller's own handle for it, and a setup block carrying the tag or pixel URL that activates it. log_event then posts batches of events against an event_source_id, one of only three required fields on that request and the one that determines whether anything attributes.

get_media_buy_delivery takes an attribution_window and returns conversion metrics. provide_performance_feedback runs the other way: the buyer sends a performance_index to the seller so delivery can be optimised against outcomes the seller cannot observe. The score is normalised rather than absolute: 1.0 means the campaign performed as expected, and the schema sets a floor at 0 with no upper bound. Each submission is tagged with one of eight metric_type values and one of four feedback_source values. The upstream conversion-tracking guide stops earlier: its flow diagram ends at the delivery read, and provide_performance_feedback appears nowhere in it.

The other 9 AdCP areas

Related