Open
Conversation
0e86837 to
67bc9d5
Compare
67bc9d5 to
7bf029b
Compare
7bf029b to
ed0fdc8
Compare
ed0fdc8 to
d617678
Compare
d617678 to
ada2f71
Compare
ada2f71 to
c54a093
Compare
c54a093 to
50cc87b
Compare
50cc87b to
f4fd720
Compare
f4fd720 to
28ebc4e
Compare
28ebc4e to
6f9da08
Compare
6f9da08 to
ada5bed
Compare
ada5bed to
8c228a6
Compare
8c228a6 to
e388184
Compare
e388184 to
7ab90cb
Compare
7ab90cb to
25a5cb8
Compare
7a68530 to
51a574f
Compare
51a574f to
538efb6
Compare
4 tasks
538efb6 to
527ca7b
Compare
527ca7b to
45fe971
Compare
45fe971 to
89a04fa
Compare
89a04fa to
d5c8007
Compare
d5c8007 to
8c6ae45
Compare
8c6ae45 to
28adca9
Compare
28adca9 to
e77cafa
Compare
e77cafa to
04aa633
Compare
04aa633 to
077a465
Compare
077a465 to
7936d58
Compare
7936d58 to
20c3f1b
Compare
20c3f1b to
9a1aa4d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
mainis currently in pre mode so this branch has prereleases rather than normal releases. If you want to exit prereleases, runchangeset pre exitonmain.Releases
adcontextprotocol@3.0.0-beta.4
Major Changes
892da1d: Delete brand-manifest.json. The brand object in brand.json is now the single
canonical brand definition. Task schemas reference brands by domain + brand_id
instead of passing inline manifests. Brand data is always resolved from
brand.json or the registry.
5b8feea: BREAKING: Rename
catalogtocatalogs(array) on creative manifest. Formats can declare multiple catalog_requirements (e.g., product + inventory + store); the manifest now supports multiple catalogs to match. Each catalog'stypemaps to the corresponding catalog_requirements entry.7cf7476: Remove
estimated_exposuresfrom Product, replace with optionalforecastestimated_exposuresinteger field from the Product schemaforecastfield using the existingDeliveryForecasttype, giving buyers structured delivery estimates with time periods, metric ranges, and methodology context during product discovery811bd0e: Consolidate
feedback,product_ids, andproposal_idinto a singlerefineobject onget_productsThe previous refinement interface spread across three top-level fields. The new
refineobject consolidates all refinement intent:overalldirection, per-product actions (include,omit,more_like_this), and per-proposal adjustments. This is a breaking change — the oldfeedback,product_ids, andproposal_idfields are removed.544230b: Address schema gaps that block autonomous agent operation, plus consistency fixes.
Error handling (Error.code has no standardized vocabulary; agents cannot classify errors for autonomous recovery #1223)
Error: addrecoveryfield (transient | correctable | terminal) so agents can classify failures without escalating every error to humansenums/error-code.json: standard vocabulary (RATE_LIMITED,SERVICE_UNAVAILABLE,PRODUCT_UNAVAILABLE,PROPOSAL_EXPIRED,BUDGET_TOO_LOW,CREATIVE_REJECTED,UNSUPPORTED_FEATURE,AUDIENCE_TOO_SMALL,ACCOUNT_NOT_FOUND,ACCOUNT_PAYMENT_REQUIRED,ACCOUNT_SUSPENDED)Idempotency (create_media_buy has no idempotency key; agent retries risk duplicate spend commitments #1224)
UpdateMediaBuyRequest,SyncCreativesRequest: addidempotency_keyfor safe retries after timeoutsCreateMediaBuyRequest.buyer_ref: document deduplication semantics (buyer_ref is the idempotency key for create)Media buy lifecycle (MediaBuyStatus missing 'rejected' state; post-creation rejection has no protocol representation #1225)
MediaBuyStatus: addrejectedenum value for post-creation seller declinesMediaBuy: addrejection_reasonfield present whenstatus === rejectedProtocol version (Protocol version never sent on requests; sellers supporting v2+v3 simultaneously cannot dispatch correctly #1226)
GetAdCPCapabilitiesResponse.adcp.major_versions: document version negotiation via capabilities handshake; HTTP header is optionalAsync polling (Async tasks have no polling guidance; agents without webhook infrastructure have no recovery path #1227)
GetAdCPCapabilitiesResponse.adcp: addpollingobject (supported,recommended_interval_seconds,max_wait_seconds) for agents without persistent webhook endpointsPackage response (Package response type missing optimization_goals, catalog, and format_ids from PackageRequest #1229)
Package: addcatalogs(array) andformat_idsfields echoed from the create request so agents can verify what the seller storedSignal deactivation (No deactivate_signal operation; activated segments persist indefinitely after campaign end #1231)
ActivateSignalRequest: addaction: activate | deactivatefield withactivatedefault; deactivation removes segments from downstream platforms to support GDPR/CCPA complianceSignal metadata (GetSignalsResponse: categorical signals have no 'categories' field; buyers cannot construct valid targeting #1232)
GetSignalsResponsesignal entries: addcategories(forcategoricalsignals) andrange(fornumericsignals) so buyers can construct valid targeting valuesProperty list filters (PropertyListFilters.countries_all and channels_any are required; global or all-channel lists are not representable #1233)
PropertyListFilters: makecountries_allandchannels_anyoptional; omitting means no restriction (enables global lists and all-channel lists)Content standards response (UpdateContentStandardsResponse is not a discriminated union; inconsistent with all other write operations #1234)
UpdateContentStandardsResponse: replace flat object withUpdateContentStandardsSuccess | UpdateContentStandardsErrordiscriminated union (success: true/false) consistent with all other write operationsProduct refinement (No standalone get_forecast task; iterative planning requires repeated get_products calls #1235)
GetProductsRequest: addbuying_mode: "refine"withrefineobject for iterating on known products and proposals — each product declares an explicit action (include,omit,more_like_this) with optional adjustment notesCreative assignments (SyncCreativesRequest.assignments map has ambiguous key direction and missing weight/placement fields #1237)
SyncCreativesRequest.assignments: replace ambiguous{ creative_id: package_id[] }map with typed array{ creative_id, package_id, weight?, placement_ids? }[]Batch preview (PreviewBatchResultSuccess and PreviewBatchResultError are empty shells; batch preview is non-functional #1238)
PreviewBatchResultSuccess: add requiredsuccess: true,creative_id, properresponseobject withpreviewsandexpires_atPreviewBatchResultError: add requiredsuccess: false,creative_id,errors: Error[](referencing standard Error schema)Creative delivery pagination (GetCreativeDeliveryRequest uses offset pagination; inconsistent with protocol-wide cursor standard #1239)
GetCreativeDeliveryRequest.pagination: replace ad-hoclimit/offsetwith standardPaginationRequestcursor-based paginationSignals account consistency (signals: account_id field should use AccountReference discriminated union #1242)
GetSignalsRequest,ActivateSignalRequest: replaceaccount_id: stringwithaccount: $ref account-ref.jsonfor consistency with all other endpointsSignals field naming (activate-signal: deployments field should be named destinations for consistency #1244)
ActivateSignalRequest: renamedeploymentstodestinationsfor consistency withGetSignalsRequestCreative features billing (get-creative-features: request missing account context for billing #1245)
GetCreativeFeaturesRequest: add optionalaccountfield for governance agents that charge per evaluationConsent basis enum (schema: consent_basis should be a shared enum reference, not inline #1246)
enums/consent-basis.json: extract inline GDPR consent basis enum to shared schemaDate range extraction (schema: Period/date-range type is duplicated inline across multiple schemas #1247)
core/date-range.jsonandcore/datetime-range.json: extract duplicated inline period objects from financials, usage, and feedback schemasCreative features clarity (get-creative-features: endpoint name is ambiguous - consider rename to evaluate-creative or assess-creative #1248)
GetCreativeFeaturesRequest/Response: clarify description to make evaluation semantics explicitRemove non-standard keyword (sync-audiences-request: errorMessage keyword is an ajv extension, not valid JSON Schema draft-07 #1250)
SyncAudiencesRequest: remove ajv-specificerrorMessagekeyword that violates JSON Schema draft-07Package catalogs
Package,PackageRequest: changecatalog(single) tocatalogs(array) to support multi-catalog packages (e.g., product + store catalogs)4c33b99: Add required
buying_modediscriminator toget_productsrequest for explicit wholesale vs curated buying intent.Buyers with their own audience stacks (DMPs, CDPs, AXE integrations) can now set
buying_mode: "wholesale"to declare they want raw inventory without publisher curation. Buyers using curated discovery setbuying_mode: "brief"and includebrief. This removes ambiguity from legacy requests that omittedbuying_mode.When
buying_modeis"wholesale":briefmust not be provided (mutually exclusive)Minor Changes
f6336af: Serve AgenticAdvertising.org brand.json from hosted_brands database so it can be managed via Addie tools. Seed initial brand data including structured tone format with voice and attributes.
a9e118d: Introduce Accounts Protocol documentation as a named cross-protocol section covering commercial infrastructure:
sync_accounts,list_accounts, andreport_usage. Includes Accounts Protocol overview connecting brand registry, account establishment, and settlement into a transaction lifecycle. Moves account management tasks from Media Buy Protocol to the new Accounts Protocol section.142bcd5: Replace account_id with account reference, restructure account model.
account-ref.json: union type accepting{ account_id }or{ brand, operator }brand-ref.json(domain + brand_id) instead of flat house + brand_id in account schemasoperatorrequired everywhere (brand sets operator to its own domain when operating its own seat)account_resolutioncapability (string:explicit_account_idorimplicit_from_sync)operatororagentonly (brand-as-operator when brand pays directly)billingis now required insync_accountsrequest (previously optional). Existing callers that omitbillingwill receive validation errors. Billing is accept-or-reject — sellers cannot silently remap billing.accountrequired on create_media_buy, get_media_buys, sync_creatives, sync_catalogs, sync_audiences, sync_event_sourcesaccountrequired per record on report_usagesync_accountsno longer returnsaccount_id— the seller manages account identifiers internally. Buyers discover IDs vialist_accounts(explicit model) or use natural keys (implicit model).account_idrequired inaccount.json(remove conditional if/then — the schema is only used in seller responses where the seller always has an ID)account_scopeto account and sync_accounts response schemasACCOUNT_SETUP_REQUIREDandACCOUNT_AMBIGUOUSerror codesget_account_financialstask for operator-billed account financial statusff62171: Add
appcatalog type for mobile app install and re-engagement advertising.Introduces
AppItemschema with fields forbundle_id,apple_id,platform(ios/android), store metadata, and deep links. Maps to Google App Campaigns, Apple Search Ads, Meta App Ads, TikTok App Campaigns, and Snapchat App Install Ads.Also adds
app_idtocontent-id-typefor conversion event matching andAPP_ITEM_IDto universal macros for tracking URL substitution.8ec2ab3: Add
external_idfield to AudienceMember for buyer-assigned stable identifiers (CRM record ID, loyalty ID). Removeexternal_idfrom uid-type enum — it was not a universal ID and belongs as a dedicated field. Addexternal_idtosupported_identifier_typesin capabilities so sellers can advertise support.ce439ca: Brand registry lookup, unified enrichment, and membership inheritance
c872c94: Brand registry as primary company identity source. Member profiles now link to the brand registry via
primary_brand_domaininstead of storing logos and colors directly. Members set up their brand through the brand tools and get a hosted brand.json atagenticadvertising.org/brands/yourdomain.com/brand.json. Placing a one-line pointer at/.well-known/brand.jsonmakes AgenticAdvertising.org the authoritative brand source for any domain.1051929: Add optional
campaign_reffield toget_productsandcreate_media_buyfor grouping related operations under a buyer-defined campaign label. Echoed in media buy responses for CRM and ad server correlation.15a64e6: Refactor
CatalogFieldBindingschema to use akinddiscriminator field ("scalar","asset_pool","catalog_group") instead ofallOf + oneOfwith negativenotconstraints. Scalar and asset pool variants are extracted todefinitionsfor reuse inper_item_bindings. Generates a clean TypeScript discriminated union instead of triplicated intersections.5b8feea: Add catalog item macros for item-level attribution: SKU, GTIN, OFFERING_ID, JOB_ID, HOTEL_ID, FLIGHT_ID, VEHICLE_ID, LISTING_ID, STORE_ID, PROGRAM_ID, and DESTINATION_ID (mirroring the content_id_type enum), plus CATALOG_ID for catalog-level attribution and CREATIVE_VARIANT_ID for seller-assigned creative variant tracking. Enables closed-loop attribution from impression tracking through conversion events.
e2e68d3: Add typed catalog assets, field bindings, and feed field mappings.
Typed assets on vertical catalog items:
hotel,flight,job,vehicle,real_estate,education,destination, andappitem schemas now support anassetsarray usingOfferingAssetGroupstructure. Enables buyers to provide typed image pools (images_landscape,images_vertical,logo, etc.) alongside existing scalar fields, so formats can declare which asset group to use for each platform-specific slot rather than relying on a singleimage_url.Field bindings on format catalog requirements:
catalog_requirementsentries now supportfield_bindings— explicit mappings from format template slots (asset_id) to catalog item fields (dot-notation path) or typed asset pools (asset_group_id). Supports scalar field binding, asset pool binding, and repeatable group iteration over catalog items. Optional — agents can still infer without bindings.Feed field mappings on catalog: The
Catalogobject now acceptsfeed_field_mappingsfor normalizing external feeds duringsync_catalogsingestion. Supports field renames, named transforms (date,divide,boolean,split) with per-transform parameters, static literal injection, and placement of image URLs into typed asset pools. Eliminates the need to preprocess every non-AdCP feed before syncing.5622c51: Add build capability discovery to creative formats.
format.jsongainsinput_format_ids— the source creative formats a format accepts as input manifests (alongside the existingoutput_format_idsfor what can be produced).list_creative_formatsgains two new filter parameters:output_format_ids— filter to formats that can produce any of the specified outputsinput_format_ids— filter to formats that accept any of the specified formats as inputTogether these let agents ask a creative agent "what can you build?" and query in either direction: "given outputs I need, what inputs do you accept?" or "given inputs I have, what outputs can you produce?"
7b1d51e: Add
get_creative_featurestask for creative governanceIntroduces the creative analog of
get_property_features— a general-purpose task for evaluating creatives and returning feature values. Supports security scanning, creative quality assessment, content categorization, and any other creative evaluation through the same feature-based pattern used by property governance.New schemas:
get-creative-features-request.json— accepts a creative manifest and optional feature_ids filterget-creative-features-response.json— returns feature results with discriminated union (success/error)creative-feature-result.json— individual feature evaluation (value, confidence, expires_at, etc.)Also adds
creative_featuresto the governance section ofget_adcp_capabilitiesresponse, allowing agents to advertise which creative features they can evaluate.9652531: Add dimension breakdowns to delivery reporting and device_type targeting.
New enums:
device-type.json(desktop, mobile, tablet, ctv, dooh, unknown),audience-source.json(synced, platform, third_party, lookalike, retargeting, unknown),sort-metric.json(sortable numeric delivery-metrics fields). New shared schema:geo-breakdown-support.jsonfor declaring geographic breakdown capabilities. Adddevice_typeanddevice_type_excludeto targeting overlay. Addreporting_dimensionsrequest parameter toget_media_buy_deliveryfor opting into geo, device_type, device_platform, audience, and placement breakdowns with configurable sort and limit. Add corresponding `by_*arrays with truncation flags to the delivery response underby_package. Declare breakdown support inreporting_capabilities(product-level). Adddevice_typeto seller-level targeting capabilities inget_adcp_capabilities`.Note: the speculative
by_geographyexample in docs (never in the schema or spec) has been replaced with the formalby_geostructure.5289d34: Add 3-tier event visibility: public, invite-only listed, and invite-only unlisted. Invite-only events support explicit email invite lists and rule-based access (membership required, org allow-list). Adds
interestedas a distinct registration status for non-invited users who express interest.ca18472: Flatten
deliver_toinget_signalsrequest into top-leveldestinationsandcountriesfields.Previously, callers were required to construct a nested
deliver_toobject withdeploymentsandcountriessub-fields, even when querying a platform's own signal agent where the destination is implicit. Both fields are now optional top-level parameters:destinations: Filter signals to those activatable on specific agents/platforms. When omitted, returns all signals available on the current agent.countries: Geographic filter for signal availability.1590905: Add
geo_proximitytargeting for arbitrary-location proximity targeting. Three methods: travel time isochrones (e.g., "within 2hr drive of Düsseldorf"), simple radius (e.g., "within 30km of Heathrow"), and pre-computed GeoJSON geometry (buyer provides the polygon). Structured capability declaration inget_adcp_capabilitiesallows sellers to declare supported methods and transport modes independently.cb5af61: Add
get_media_buystask for operational campaign monitoring. Returns current media buy status, creative approval state per package, missing format IDs, and optional near-real-time delivery snapshots withstaleness_secondsto indicate data freshness. Complementsget_media_buy_deliverywhich is for authoritative reporting over date ranges.13919b5: Add keyword targeting for search and retail media platforms.
New fields in
targeting_overlay:keyword_targets— array of{keyword, match_type, bid_price?}objects for search/retail media targeting. Per-keywordbid_priceoverrides the package-level bid for that keyword and inheritsmax_bidinterpretation from the pricing option. Keywords identified by(keyword, match_type)tuple.negative_keywords— array of{keyword, match_type}objects to exclude matching queries from delivery.New fields in
package-update(incremental operations):keyword_targets_add— upsert keyword targets by(keyword, match_type)identity; adds new keywords or updatesbid_priceon existing oneskeyword_targets_remove— remove keyword targets by(keyword, match_type)identitynegative_keywords_add— append negative keywords to a live package without replacing the existing listnegative_keywords_remove— remove specific negative keyword+match_type pairs from a live packageNew field in delivery reporting (
by_package):by_keyword— keyword-grain breakdown with one row per(keyword, match_type)pair and standard delivery metricsNew capability flags in
get_adcp_capabilities:execution.targeting.keyword_targetsexecution.targeting.negative_keywordsNew reporting capability:
reporting_capabilities.supports_keyword_breakdownc782f66: Note: These changes are breaking relative to earlier betas but no fields removed here were ever in a stable release.
Add
sync_catalogstask and unifiedCatalogmodel. Replace separateofferings[]andproduct_selectorsfields onPromotedOfferingswith a typedCatalogobject that supports inline items, external URL references, and platform-synced catalogs. Expand catalog types beyond offerings and product to include inventory, store, and promotion feeds. Addsync_catalogstask with request/response schemas, async response patterns (working, input-required, submitted), per-catalog approval workflow, and item-level review status. Addcatalog_requirementsonFormatso formats can declare what catalog feeds they need and what fields each must provide. AddOfferingAssetGroupschema for structured per-offering creative pools,OfferingAssetConstraintfor format-level asset requirements, andgeo_targetsonOfferingfor location-specific offerings. Addaccount-stateconceptual doc framing Account as the central stateful container in AdCP 3.0. Rename promoted-offerings doc to catalogs to reflect its expanded scope. AddStoreItemschema for physical locations within store-type catalogs, with lat/lng coordinates, structured address, operating hours, and tags. AddCatchmentschema for defining store catchment areas via three methods: isochrone inputs (travel time + transport mode), simple radius, or pre-computed GeoJSON geometry. Addtransport-modeanddistance-unitenums. Add industry-vertical catalog types (hotel,flight,job,vehicle,real_estate,education,destination) with canonical item schemas for each, drawn from Google Ads, Meta, LinkedIn, and Microsoft platform feed specs. Add sharedPriceschema. Addlinkedin_jobsfeed format. RemovePromotedOfferingswrapper — catalogs are now first-class. Creatives reference catalogs viacatalogfield instead of embedding in assets. Removepromoted_offeringfrom media-buy and creative-manifest schemas. Addconversion_eventsandcontent_id_typeto Catalog for conversion attribution. Rename catalog typeofferingstoofferingfor consistency with other singular type names. Removeportfolio_reffrom Offering — structuredassets(OfferingAssetGroup) replaces external portfolio references. Replaceproduct_selectors(PromotedProducts) onget_productswithcatalog($ref catalog.json) — one concept, one schema. Deletepromoted-products.json. Addcatalog_typesto Product so products declare what catalog types they support. Addmatched_idsandmatched_counttocatalog_match, removematched_skus. Addcatalogfield topackage-requestandpackage-updatefor catalog-driven packages. Addstore_catchmentstargeting dimension referencing synced store catalogs. Addby_catalog_itemdelivery breakdown inget_media_buy_deliveryresponse for per-item reporting on catalog-driven packages. Updatecreative-variantdescription to clarify that catalog items rendered as ads are variants.0e96a78: Add capability declarations for metric optimization goals, cross-channel engagement metrics, video view duration control, and value optimization.
New metric kinds (
optimization_goalswithkind: 'metric'):engagements— direct ad interaction beyond viewing: social reactions/comments/shares, story/unit opens, interactive overlay taps on CTV, companion banner interactions on audiofollows— new followers, page likes, artist/podcast/channel subscribessaves— saves, bookmarks, playlist adds, pinsprofile_visits— visits to the brand's page, artist page, or channelVideo view duration control:
view_duration_secondson metric goals — minimum view duration (in seconds) that qualifies as acompleted_viewsevent (e.g., 2s, 6s, 15s). Sellers declare supported durations inmetric_optimization.supported_view_durations. Sellers must reject unsupported values.New event goal target kind:
maximize_value— maximize total conversion value within budget without a specific ROAS ratio target. Steers spend toward higher-value conversions. Requiresvalue_fieldon event sources.Product schema additions:
metric_optimization— declares which metric kinds a product can optimize for (supported_metrics), which view durations are available (supported_view_durations), and which target kinds are supported (supported_targets). Presence indicates support forkind: 'metric'goals without any conversion tracking setup.max_optimization_goals— maximum number of goals a package can carry. Most social platforms accept only 1.Product schema corrections:
conversion_tracking.supported_optimization_strategiesrenamed toconversion_tracking.supported_targetsfor consistency withmetric_optimization.supported_targets. Both fields answer the same question: "what can I put intarget.kind?"supported_targetsvalues (cost_per,threshold_rate,per_ad_spend,maximize_value) now exactly matchtarget.kindvalues on optimization goals — agents can do direct string comparison.conversion_trackingdescription clarified to be forkind: 'event'goals only.Delivery metrics additions:
engagements,follows,saves,profile_visitscount fields added to delivery-metrics.json so buyers can see performance against the new metric optimization goals.completed_viewsdescription updated to acknowledge configurable view duration threshold.Forecastable metrics additions:
engagements,follows,saves,profile_visitsadded to forecastable-metric.json for forecast completeness.Capabilities schema addition:
media_buy.conversion_tracking.multi_source_event_dedup— declares whether the seller can deduplicate events across multiple sources. When absent or false, buyers should use a single event source per goal.Optimization goal description clarifications:
event_sourcesreferences themulti_source_event_dedupcapability; explains first-source-wins fallback when dedup is unsupported.value_fieldandvalue_factorclarified as seller obligations (not optional hints). The seller must use these for value extraction and aggregation. They are not passed to underlying platform APIs.5b25ccd: Redesign optimization goals with multiple event sources, threshold rates, and attention metrics.
optimization_goal(singular) →optimization_goals(array) on packagesOptimizationGoalis a discriminated union onkind:kind: "event"— optimize for advertiser-tracked conversion events viaevent_sourcesarray of source-type pairs. Seller deduplicates byevent_idacross sources. Each entry can specifyvalue_fieldandvalue_factorfor value-based targets.kind: "metric"— optimize for a seller-native delivery metric with optionalcost_perorthreshold_ratetargetcost_per(cost per unit),threshold_rate(minimum per-impression value),per_ad_spend(return ratio on event values),maximize_value(maximize total conversion value)clicks,views,completed_views,viewed_seconds,attention_seconds,attention_score,engagements,follows,saves,profile_visitspriority(integer, 1 = highest) for multi-goal packagesproduct.conversion_tracking.supported_targets:cost_per,per_ad_spend,maximize_valueproduct.metric_optimization.supported_targets:cost_per,threshold_ratee6767f2: Add
overlaysto format asset definitions for publisher-controlled elements that render over buyer content.Publishers can now declare video player controls, publisher logos, and similar per-asset chrome as
overlayson individual assets. Each overlay includesbounds(pixel or fractional, relative to the asset's own top-left corner) and optionalvisualURLs for light and dark theme variants. Creative agents use this to avoid placing critical buyer content behind publisher chrome when composing creatives.dfcb522: Add structured pricing options to signals and content standards protocols.
get_signalsnow returnspricing_options(array of typed pricing option objects) instead of the legacypricing: {cpm, currency}field. This enables signals agents to offer time-based subscriptions, flat-rate, CPCV, and other pricing models alongside CPM.list_content_standards/get_content_standardsnow includepricing_optionson content standards objects as an optional field, using the same structure. Full billing integration for governance agents will be defined when the account setup flow for that protocol is designed.report_usagehas been simplified:kindandoperator_idare removed. The receiving vendor agent already knows what type of service it provides, and the billing operator is captured by the account reference (brand + operatorform or implied by account setup when usingaccount_id).report_usagenow accepts anidempotency_keyfield. Supply a client-generated UUID per request to prevent duplicate billing on retries.activate_signalnow acceptspricing_option_id. Pass the pricing option selected fromget_signalsto record the buyer's pricing commitment at activation time.2957069: Add promoted-offerings-requirement enum and
requiresproperty to promoted offerings asset requirements (Add required_fields constraint for structured asset types (e.g. promoted_offerings) #1040)a7feccb: Add property list check and enhancement to the AAO registry API.
Registry:
domain_classificationstable with typed entries (ad_server,intermediary,cdn,tracker), seeded with ~60 known ad tech infrastructure domainsproperty_check_reportstable stores full check results by UUID for 7 daysAPI:
POST /api/properties/check— accepts up to 10,000 domains, returns remove/modify/assess/ok buckets and a report IDGET /api/properties/check/:reportId— retrieve a stored reportTools:
check_property_listMCP tool — runs the check and returns a compact summary + report URL (avoids flooding agent context with thousands of domain entries)enhance_propertyMCP tool — analyzes a single unknown domain: WHOIS age check (< 90 days = high risk), adagents.json validation, AI site structure analysis, submits as pending registry entry for Addie review73e3639: Add reach as a metric optimization goal and expand frequency cap capabilities.
New metric optimization kind:
reachadded to themetricenum onkind: 'metric'optimization goalsreach_unitfield — specifies the measurement entity (individuals, households, devices, etc.). Must match a value inmetric_optimization.supported_reach_units.target_frequencyfield — optional{ min, max, window }band that frames frequency as an optimization signal, not a hard cap.windowis required (e.g.,'7d','campaign') — frequency bands are meaningless without a time dimension. The seller de-prioritizes impressions toward entities already within the band and shifts budget toward unreached entities. Can be combined withtargeting_overlay.frequency_capfor a hard ceiling.Product capability additions:
metric_optimization.supported_reach_units— declares which reach units the product supports for reach optimization goals. Required whensupported_metricsincludes'reach'.reachadded to thesupported_metricsenum inmetric_optimization.Frequency cap expansion:
max_impressions— maximum impressions per entity per window (integer, minimum 1).per— entity to count against, using the same values asreach-unitenum (individuals, households, devices, accounts, cookies, custom). Aligns withreach_uniton reach optimization goals so hard caps and optimization signals stay in sync.window— time window for the cap (e.g.,'1d','7d','30d','campaign'). Required whenmax_impressionsis set.suppress(formerlysuppress_minutes) — cooldown between consecutive exposures, now a duration object (e.g.{"interval": 60, "unit": "minutes"}). Optional — the two controls (cooldown vs. impression cap) serve different purposes and can be used independently or together.80afa97: Add sandbox mode as a protocol parameter on all task requests. Sellers declare support via
features.sandboxin capabilities. Buyers passsandbox: trueon any request to run without real platform calls or spend. Replaces the previously documented HTTP header approach (X-Dry-Run, X-Test-Session-ID, X-Mock-Time).2b8d6b6: Schema refinements for frequency caps, signal pricing, audience identifiers, keyword capabilities, and duration representation.
core/duration.jsonschema ({interval, unit}where unit is"minutes","hours","days", or"campaign"). Used consistently for all time durations. When unit is"campaign", interval must be 1 — the window spans the full campaign flight. (FrequencyCap: window field should be a defined string union, not bare string #1215)"7d") to a duration object (e.g.{"interval": 7, "unit": "days"}or{"interval": 1, "unit": "campaign"}). Also applied tooptimization_goal.target_frequency.window. (FrequencyCap: window field should be a defined string union, not bare string #1215)attribution_window.click_through/view_through(strings) becamepost_click/post_view(duration objects) on optimization goals, capability declarations, and delivery response. (FrequencyCap: window field should be a defined string union, not bare string #1215)periodfield (monthly | quarterly | annual | campaign) so buyers know the billing cadence for flat-fee signals. (FlatFeePricing: missing period field for signals flat-fee billing #1216)suppress(duration object, e.g.{"interval": 60, "unit": "minutes"}) as the preferred cooldown field.suppress_minutes(scalar) is deprecated but still accepted for backwards compatibility. (FrequencyCap: window field should be a defined string union, not bare string #1215)platform_customer_idfrom the identifier type enum. Addedsupports_platform_customer_idboolean to audience targeting capabilities — a binary capability flag is clearer than an enum value for this closed-ecosystem matching key. (external_id in supported_identifier_types is ambiguous with AudienceMember.external_id #1217)execution.targeting.keyword_targetsandexecution.targeting.negative_keywordsfrom boolean to objects withsupported_match_types: ("broad" | "phrase" | "exact")[], so buyers know which match types each seller accepts before sending. (Keyword targeting capabilities should declare supported match types per seller #1218)1c5bbb0: Add percent_of_media pricing model and transaction context to signals protocol:
signal-pricing.json: New schema for signal-specific pricing — discriminated union ofcpm(fixed CPM) andpercent_of_media(percentage of spend, with optionalmax_cpmcap for TTD-style hybrid pricing)signal-pricing-option.json: New schema wrappingpricing_option_id+signal-pricing. Theget_signalsresponse now uses this instead of the generic media-buypricing-option.jsonsignal-filters.json: Newmax_percentfilter for percent-of-media signalsget_signalsrequest: Optionalaccount_id(per-account rate cards) andbuyer_campaign_ref(correlate discovery with settlement)activate_signalrequest: Optionalaccount_idandbuyer_campaign_reffor transaction context8f26baf: Add Swiss (
ch_plz) and Austrian (at_plz) postal code systems to geo targeting.b61f271: Add
sync_audiencestask for CRM-based audience management.Buyers wrapping closed platforms (LinkedIn, Meta, TikTok, Google Ads) need to upload hashed CRM data before creating campaigns that target or suppress matched audiences. This adds a dedicated task for that workflow, parallel to
sync_event_sources.Schema:
sync_audienceswith request and response schemasaudience-member.json— hashed identifiers for CRM list members (email, phone, MAIDs)targeting.json: addaudience_includeandaudience_excludearrays for referencing audiences increate_media_buytargeting overlaysDocumentation:
docs/media-buy/task-reference/sync_audiences.mdxdocs/media-buy/advanced-topics/targeting.mdxwithaudience_include/audience_excludeoverlay documentation142bcd5: Add
rejectedaccount status for accounts that were never approved. Previously,closedcovered both "was active, now terminated" and "seller declined the request", which was counterintuitive. Nowpending_approval→rejected(declined) is distinct fromactive→closed(terminated).0cede41: Add CreativeBrief type to BuildCreativeRequest for structured campaign context
Patch Changes
24782c2: Add dedicated task reference pages for
sync_accountsandlist_accountsunder Media Buy Protocol Task Reference.719135b: Move accounts management from manage to admin; fix stale prospect links to removed organizations page.
5a90c55: Fix Addie billing status conflating active subscriptions with paid invoices.
cc6da0c: Increase Addie conversation history from 10 to 20 messages for longer debugging sessions.
53e1d65: Add property registry context to Addie's tool reference so she understands what the community property registry is, how data is managed across the three source tiers (authoritative/enriched/community), and when to use each property tool.
d4f7723: Empty changeset — internal Addie improvements (no protocol changes).
dce0090: Update Addie's test_adcp_agent tool to use @adcp/client 3.20.0 suite API.
acd9db7: Addie quality improvements from thread review: accurate spec claims, fictional example names, ads.txt knowledge, shorter deflections, agent type awareness, and session-level web feedback prompt.
2d072c1: Clarify push notification config flow in docs and schema.
push_notification_configplacement and naming in webhook docs (task body, not protocol metadata)push_notification_configexplicitly tocreate_media_buyrequest schemaoperation_iddescription: client-generated, echoed by publisher93e19a1: Remove generated_creative_ref from build_creative and preview_creative schemas. Creative refinement uses manifest passback and creative brief updates instead. Document iterative refinement patterns for build_creative and get_signals.
2b79286: Clarify that end_date is exclusive in get_media_buy_delivery documentation
24b972e: Document save endpoints for brands and properties in registry API docs.
b311f65: Fix Addie brand management: add missing brand tools to tool reference, prevent save_brand from overwriting enrichment data
5e5a3b7: Fix Addie streaming errors, MCP token expiry, and SSE error handling.
d447e71: Fix three brand identity bugs: has_manifest false when brand.json found, uploaded logo not showing on member card, and "Set up brand" link redirecting to dashboard.
5b8feea: Fix build_creative doc examples: remove catalog_id from inline catalogs, add missing offering_id to inline offering items.
29bfe08: fix: couple brand enrichment to save in public REST endpoint
34d2764: Fix incorrect data wrapper in get_products MCP response examples
9f70a06: fix: set CORS headers on MCP 401 responses so OAuth flow can start
894e9e9: Empty changeset — no protocol impact.
3378218:
cf3ebb3: Fix schema version alias resolution for prereleases
/v3/was resolving to3.0.0-beta.1instead of3.0.0-beta.3because prereleases were sorted ascending instead of descendingsync_event_sourcesandlog_eventdocs to use/v3/schema links (these schemas were added in v3)bf19909: Fix API key authentication for WorkOS keys using the new
sk_prefix. WorkOS changed their key format fromwos_api_key_tosk_, which caused all newer API keys to be rejected by the auth middleware before reaching validation.5418b93: Fix broken schema links in sync_audiences documentation. Changed from
/schemas/v2/to/schemas/v1/since this task was added after the v2.5.x and v3.0.0-beta releases and its schemas only exist inlatest(which v1 points to).3e7e545: Fix UTF-8 encoding corruption for non-ASCII characters in brand and agent registry files.
When external servers serve
.well-known/brand.jsonor.well-known/adagents.jsonwith a non-UTF-8 charset in theirContent-Typeheader (e.g.charset=iso-8859-1), axios was decoding the UTF-8 response bytes using that charset, corrupting multi-byte characters like Swedish ä/ö/å into mojibake.Fix: use
responseType: 'arraybuffer'on all external fetches so axios delivers raw bytes, then explicitly decode as UTF-8 regardless of what the server declares.751760a:
5b7cbb3: Add Lusha-powered company lookup to referral prospect search: domain-first create form auto-imports companies with full enrichment data.
5b7cbb3: Add /manage tier for kitchen cabinet governance access
5b7cbb3: Add member referral code system: invite prospects with a personalized landing page, lock the discount to their account on acceptance, and show a 30-day countdown in the membership dashboard.
333618c: Download brand logos from Brandfetch CDN to our own PostgreSQL-backed store when enriching brands. Logos are served from
/logos/brands/:domain/:idxso external agents can download them without hitting Brandfetch hotlinking restrictions.e6a62ad:
155bb4d: Add schema link checker workflow for docs PRs. The checker validates that schema URLs in documentation point to schemas that exist, and warns when schemas exist in source but haven't been released yet.
Update schema URLs from v1/v2 to v3 across documentation for schemas that are only available in v3:
Some of these schemas are already released in 3.0.0-beta.3, others will be available in the next beta release (3.0.0-beta.4).
b61fcd7: Register all tool sets for web chat, matching Slack channel parity. Previously web chat only had knowledge, billing, and schema tools — brand, directory, property, admin, events, meetings, collaboration, and other tools were missing, causing "Unknown tool" errors. Extracts shared baseline tool registration into a single module both channels import.
565fb86: Made font and tagline fields editable in brand registry on the UI