Tool

Score a campaign brief

Paste a campaign brief and get the AdCP get_products request and the AAMP CampaignBrief it produces, every value labelled stated, derived, assumed or missing, against 30 typed AdCP filter fields and the AAMP required set.

Rule-based and deterministic: same words in, same payloads out. Nothing is sent anywhere, no account, no email. Paste the brief, read the two scores, then work down the list of what a seller will guess or drop.

Paste the brief

Pre-filled with a worked example. The results below are its output. Replace it with yours and score it. Scoring again clears any accepted assumptions.

The four labels

stated
You said it. The exact words are quoted back with the value.
derived
Unambiguously implied, and the rule that fired is printed next to it. United States to countries: ["US"] is a derivation. A channel split is not.
assumed
The engine picked it. Off by default and listed on its own; it reaches neither payload until you tick its box.
missing
Not present and not derivable. The seller will guess it or drop it.

A value can be read correctly, labelled stated, and still reach neither payload, because neither protocol has a field to carry it.

Scored. Transactable 5 of 10. Expressive 4 of 30. 56 things a seller will guess or drop, 5 of them blocking.

The score

Transactable gate

5 of 10

AAMP CampaignBrief's eight required fields, plus a budget_pct on every channel allocation, plus one check that the AdCP get_products request validates. Counted against the emitted payloads, not your sentences.

5 fail:

  • Advertiser identifier (CampaignBrief.advertiser_id) — The AAMP brief will not construct, so nothing downstream of the buyer agent runs.
  • Campaign name (CampaignBrief.campaign_name) — The AAMP brief will not construct, and on the AdCP side the campaign has no human-readable handle in any artefact the seller sees.
  • Campaign objective (CampaignBrief.objective) — The AAMP brief will not construct, and no downstream allocation logic knows whether to optimise for reach or for conversion.
  • Budget currency (CampaignBrief.currency) — AAMP rejects the brief, and AdCP rejects `budget_range` entirely — `currency` is its only required key.
  • Budget split by channel (CampaignBrief.channels[].budget_pct) — The AAMP brief will not construct: `budget_pct` is required on every channel allocation, must be `0 < pct <= 100`, and the values must sum to 100.

Expressive coverage, not a target

4 of 30

AdCP filters.* fields your brief populates. The other 26 go to the seller empty, so nothing in them is filtered on. Every populated filter is a hard constraint that deletes products: brief vs filters has the routing rule.

Populated: channels countries end_date start_date

AdCP schema 3.1.13 · buying mode brief · relative dates resolved against 2026-08-13

Relative dates use today's date. Write absolute dates for a result that holds next week.

Every field, and where it came from

4 stated, 5 derived, 0 assumed, 55 missing, of 64 the two protocols can express between them.

One row per concept, including the ones this brief says nothing about.
FieldWhat it isValueLabelEvidence
Identity
advertiser_id Advertiser identifier no value missing The AAMP brief will not construct, so nothing downstream of the buyer agent runs.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
brand_domain Brand domain no value missing The seller cannot resolve brand identity at execution time, so category exclusivity and competitive separation cannot be applied to your buy.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
brand_industries Advertiser industry no value missing Publishers holding category-exclusive inventory cannot tell whether your buy conflicts with a competitor already on the property.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
agency_id Agency identifier no value missing Billing and seat attribution fall to whatever the buying platform infers.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
campaign_name Campaign name no value missing The AAMP brief will not construct, and on the AdCP side the campaign has no human-readable handle in any artefact the seller sees.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
buying_mode Buying mode brief derived buying_mode: 'brief' comes from AnalyzeOptions.buyingMode, not from the brief. It is the only unconditionally required property of get-products-request.json and it describes the call, not the campaign.Request-shaping field: no span, because no words in the brief produced it.
brief_prose Campaign description (residual prose) Q4 holiday campaign for a CPG snack brand. Channels: CTV plus digital display and online video. Budget: $500,000 net. Market: United States… stated Q4 holiday campaign for a CPG snack brand. Channels: CTV plus digital display and online …The whole input. AdCP `brief` and AAMP `description` carry it verbatim so the prose that mapped to no structured field is not lost; `residual` reports which ranges those are.
internal_notes Internal notes no value missing Internal caveats stay in email instead of travelling with the brief.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
objective Campaign objective no value missing The AAMP brief will not construct, and no downstream allocation logic knows whether to optimise for reach or for conversion.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
Timing
start_date Flight start date 2026-11-01 derived 'November 1' carries no year; the year 2026 stated at the close of the range was applied to its opening date.…: adults 25-54. Flight: November 1 - December 31, 2026. Go…
end_date Flight end date 2026-12-31 stated …4. Flight: November 1 - December 31, 2026. Goal: drive incrementa…
Budget
budget_total Total budget 500000 stated …d online video. Budget: $500,000 net. Market: United Sta…One figure, no bound stated. Recorded as the total budget; whether it is a ceiling, a target or a floor is not in the input.
budget_min Minimum budget threshold no value missing Sellers may return low-minimum products that cannot absorb your spend, so the plan fragments across too many line items.
currency Budget currency no value missing AAMP rejects the brief, and AdCP rejects `budget_range` entirely — `currency` is its only required key.The amount carries '$', which names more than one currency. The engine will not pick one; accept the `currency` assumption or write the ISO 4217 code.
pricing_currencies Transactable currencies no value missing Sellers may return products priced only in currencies you cannot settle in, and mandatory signal charges may turn out to be unsatisfiable at buy time.
is_fixed_price Fixed price or auction no value missing Fixed-rate and auction products come back mixed, and the returned `pricing_options` are not pruned to the kind you intended to buy.
deal_max_cpm Maximum CPM no value missing Nothing in the discovery request stops the seller proposing inventory above your price ceiling; you find out at quote time.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
deal_min_impressions Minimum impressions per deal no value missing Deals too small to be worth trafficking get proposed and then rejected by hand.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
deal_types Preferred deal types no value missing The seller proposes whatever deal mechanics suit it — PG, PD or PA — and the buyer negotiates backwards from there.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
pacing_model Pacing model no value missing AAMP silently applies EVEN pacing, so a launch-weighted campaign delivers flat unless someone notices.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
Geography
countries Countries ["US"] derived 'United States' → countries: ['US'] (ISO 3166-1 alpha-2 name match).…: $500,000 net. Market: United States. Target demo: adults 25…
regions Regions, states or provinces no value missing Region-bound inventory (regional OOH, local TV) cannot be matched, so the seller offers national products you then have to re-cut.
metros Metros and DMAs no value missing DMA-level inventory cannot be filtered, so you get national products that will not clear a local plan.
postal_areas Postal areas no value missing Postcode-level inventory (direct mail, DOOH, local activation) is invisible to the request.
geo_proximity Proximity to locations no value missing Store-radius and drive-time buys cannot be expressed, so proximity inventory is neither found nor priced.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
required_geo_targeting Required geo-targeting capability no value missing Digital products from sellers that cannot target at your granularity stay in the result set and fail at setup.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
Inventory
channels Channels [{"adcp":"ctv","aamp":"CTV","surface":"CTV"},{"adcp":"display","aamp":"DISPLAY","surface":"digital display"},{"adcp":"olv","aamp":null,"sur… derived Channel names were matched against AdCP enums/channels.json and AAMP ChannelType. "online video" -> 'online video' is the expansion of the AdCP channel value `olv` ('Online video advertising outside CTV').… snack brand. Channels: CTV plus digital display an……and. Channels: CTV plus digital display and online video. Budge……lus digital display and online video. Budget: $500,000 net. …
channel_budget_split Budget split by channel no value missing The AAMP brief will not construct: `budget_pct` is required on every channel allocation, must be `0 < pct <= 100`, and the values must sum to 100.Channels were named but no split was stated. AAMP will not construct the brief without one; the engine leaves it missing rather than distributing the budget.
delivery_type Guaranteed or non-guaranteed no value missing Guaranteed and non-guaranteed products come back together and the buyer sorts out which is which.
preferred_delivery_types Preferred delivery types no value missing The seller cannot tell a preference from a hard constraint, so it either over-filters or ignores your leaning entirely.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
exclusivity Exclusivity no value missing Sole-sponsorship and category-exclusive products are not distinguished from ordinary inventory, so an exclusivity ask never reaches the seller as a filter.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
video_placement_types Video placement types no value missing Instream budget can be spent on accompanying-content or standalone inventory without the request ever saying otherwise.No video placement type stated. Instream budget can be spent on accompanying-content or standalone inventory without the request saying otherwise.
audio_distribution_types Audio distribution types no value missing Podcast, broadcast and music-streaming inventory are treated as one pool, so a podcast-only buy can deliver on FM simulcast.No audio distribution type stated. Podcast, broadcast and music-streaming inventory are treated as one pool.
sponsored_placement_types Sponsored placement types no value missing Retail-media requests cannot distinguish sponsored search from sponsored display, and the seller picks for you.No sponsored placement type stated. Retail-media requests cannot distinguish sponsored search from sponsored display.
social_placement_surfaces Social placement surfaces no value missing Feed, stories and short-video surfaces are indistinguishable in the request, so delivery lands wherever the seller has supply.No social placement surface stated. Feed, stories and short-video surfaces are indistinguishable in the request.
keywords Target keywords no value missing Search and retail-media products cannot be matched to your terms, so keyword availability is never assessed.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
property_list Approved property list no value missing Discovery is not restricted to your approved inventory, so products on unvetted properties come back as candidates.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
preferred_sellers Preferred sellers no value missing Buying-platform routing ignores your preferred supply partners and treats all sellers alike.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
excluded_sellers Excluded sellers no value missing Sellers you have blocked are still called and their inventory still returned.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
Creative
format_ids Ad formats no value missing Sellers return products whose creative specs you cannot fill, and the mismatch is discovered when creative is due.No creative format stated. Sellers return products whose creative specs you may not be able to fill.
standard_formats_only IAB standard formats only no value missing Bespoke and publisher-custom units stay in the result set even when you can only ship IAB standard sizes.Not stated. Bespoke and publisher-custom units stay in the result set even if you can only ship IAB standard sizes.
creative_ids Existing creative assets no value missing The plan is built without knowing which creative exists, so products get chosen for formats nobody has assets for.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
Audience
audience_primary Primary audience {"descriptors":[{"kind":"age_range","surface":"adults 25-54","ageMin":25,"ageMax":54}],"adcpSignalTargeting":null,"aampAudiencePlan":{"prim… stated …ed States. Target demo: adults 25-54. Flight: November 1 - D…Recorded as a demographic. `filters.signal_targeting` and `AudiencePlan.primary` both need a resolved reference, which a demo string is not; the descriptors travel as prose (AdCP `brief`, AAMP `AudiencePlan.rationale`) or not at all.
audience_constraints Audience constraints (narrowing) no value missing Precision constraints are dropped and the campaign reaches the primary audience unnarrowed.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
audience_extensions Audience extensions (reach) no value missing Reach-extension audiences are silently dropped and the plan under-delivers against its reach goal.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
audience_exclusions Audience exclusions (suppression) no value missing Suppression audiences (existing customers, recent converters) are not excluded, and budget is spent re-reaching people you already have.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
audience_strictness Audience degradation policy no value missing The buyer agent falls back to its default degradation policy, so a seller that cannot honour part of your plan may have it dropped without anyone being asked.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
Measurement
kpi_targets KPI targets no value missing Nobody can tell whether the campaign succeeded, and the seller optimises to whichever metric it prefers.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
min_exposures Minimum exposures for measurement no value missing Products too small to reach measurement validity stay in the result set and the study is under-powered.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
required_metrics Required reporting metrics no value missing Products that cannot report the metric your KPI is measured in are returned, and the gap shows up as `missing_metrics` on delivery reports.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
required_performance_standards Required performance standards no value missing Viewability, IVT and attention thresholds are never stated up front, so they become a post-campaign argument instead of a discovery filter.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
required_vendor_metrics Required vendor metrics no value missing Products that cannot report your measurement vendor's metrics are returned, and the vendor discovers the gap in flight.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
required_features Required protocol features no value missing Sellers that cannot support inline creative management, property-list filtering, catalog management or committed metrics are still returned, and the buy fails at execution.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
trusted_match Trusted Match capability no value missing Products without the identity or context match capability you rely on are returned as if they were interchangeable with ones that have it.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
required_axe_integrations Required agentic exchange integrations (deprecated) no value missing Nothing at 3.1.13 — the field is deprecated in favour of `trusted_match`, and populating it is a compatibility choice rather than a requirement.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
filters_ext Vendor-specific filter extensions no value missing Seller-specific criteria with no standard field have nowhere to go and end up as prose the seller may never parse.No extractor in this engine is competent for this field, so it was not looked for. A field nobody looked for and a field that was looked for and not found are different facts; this is the first kind.
Brand safety
excluded_content_categories Excluded content categories no value missing Your ads run beside content you told someone you would avoid, and the first evidence is a screenshot.Brand safety was requested but no categories were named, so nothing is emitted; AAMP `brand_safety.excluded_categories` defaults to [] and AdCP `get_products` has no brand-safety field at all.
excluded_keywords Excluded keywords no value missing Keyword-level blocks are not applied and unsuitable adjacency is caught after delivery, if at all.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
excluded_domains Excluded domains and brands no value missing Blocked domains and brands remain eligible, and the block list has to be re-applied in the DSP — if there is one in the path.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
frequency_cap Frequency cap {"max_impressions":3,"period_hours":168} derived 'per week' -> period_hours: 168 (7 days x 24 hours); max_impressions is the stated count 3… brand safety controls, frequency cap 3 per week.…AdCP `get_products` has no frequency field — `enums/frequency-cap-scope.json` applies to a media buy's packages — so a frequency requirement cannot influence which products are returned.
Governance
approval_plan_review Human approval: plan review no value missing AAMP's default applies and the pipeline halts at an approval gate the brief never discussed.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
approval_booking Human approval: booking no value missing AAMP's default applies and the agent will not book without a human, whatever the brief implied about autonomy.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
approval_creative Human approval: creative assignment no value missing AAMP's default applies and creative is assigned to placements with nobody signing it off.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.
approval_pacing_adjustment Human approval: pacing and reallocation no value missing AAMP's default applies and the agent reallocates budget between channels without asking.The policy-controls extractor is competent for this field, looked for it and found nothing in this brief.

Assumptions — none applied

Values the engine could pick and has not. Accept one and both payloads are emitted again with it in, labelled assumed. Accept nothing and nothing here reaches a seller. Scoring a brief again clears every acceptance.

'$' is the sign for the US dollar and also for the Canadian, Australian, New Zealand, Singapore, Hong Kong and Mexican dollars, among others. A bare '$' therefore does not name a currency, and the engine did not pick one: `currency` is missing and USD is offered as an assumption you can accept. Write the ISO 4217 code to state it.

Not accepted, so it is in nothing below.

What a seller will guess or drop

56 in all: 5 stop the brief constructing, 1 are read here and travel in neither payload, 50 leave a field empty for the seller to fill however it likes.

Blocks — nothing ships

  • blocks Advertiser identifier — Advertiser identifier is one of AAMP CampaignBrief's required values and no value reached the payload. The AAMP brief will not construct, so nothing downstream of the buyer agent runs.
  • blocks Campaign name — Campaign name is one of AAMP CampaignBrief's required values and no value reached the payload. The AAMP brief will not construct, and on the AdCP side the campaign has no human-readable handle in any artefact the seller sees.
  • blocks Campaign objective — Campaign objective is one of AAMP CampaignBrief's required values and no value reached the payload. The AAMP brief will not construct, and no downstream allocation logic knows whether to optimise for reach or for conversion.
  • blocks Budget currency — Budget currency is one of AAMP CampaignBrief's required values and no value reached the payload. AAMP rejects the brief, and AdCP rejects `budget_range` entirely — `currency` is its only required key.
  • blocks Budget split by channel — Budget split by channel is one of AAMP CampaignBrief's required values and no value reached the payload. The AAMP brief will not construct: `budget_pct` is required on every channel allocation, must be `0 < pct <= 100`, and the values must sum to 100.

Drops — read here, carried in neither payload

  • drops Primary audience — Primary audience is stated in this brief and reaches neither payload. Documented as one of AAMP's nine required fields; in code `target_audience` is `AudiencePlan | None = Field(default=None)`, so the model constructs without it — required by docs, optional by code. On the AdCP side the value is a SignalRef, not a taxonomy ID, and it must be buyer-selectable on the product: `included_signals` and bundled provider signals explicitly do not satisfy `signal_targeting`. AAMP validates contextual refs against IAB Content Taxonomy 3.x and rejects pre-3.x IDs. The buy runs untargeted: AdCP returns run-of-network products, and AAMP treats a null plan as "no audience targeting".
Degrades — 50 fields the seller fills for you
  • degrades Brand domain — Brand domain is not stated and not derivable from this brief. The seller cannot resolve brand identity at execution time, so category exclusivity and competitive separation cannot be applied to your buy.
  • degrades Advertiser industry — Advertiser industry is not stated and not derivable from this brief. Publishers holding category-exclusive inventory cannot tell whether your buy conflicts with a competitor already on the property.
  • degrades Agency identifier — Agency identifier is not stated and not derivable from this brief. Billing and seat attribution fall to whatever the buying platform infers.
  • degrades Internal notes — Internal notes is not stated and not derivable from this brief. Internal caveats stay in email instead of travelling with the brief.
  • degrades Minimum budget threshold — Minimum budget threshold is not stated and not derivable from this brief. Sellers may return low-minimum products that cannot absorb your spend, so the plan fragments across too many line items.
  • degrades Budget currency — The engine could set Budget currency to "USD" — '$' is the sign for the US dollar and also for the Canadian, Australian, New Zealand, Singapore, Hong Kong and Mexican dollars, among others. A bare '$' therefore does not name a currency, and the engine did not pick one: `currency` is missing and USD is offered as an assumption you can accept. Write the ISO 4217 code to state it. — and has not, because nobody accepted it. Accept the key to include it. AAMP rejects the brief, and AdCP rejects `budget_range` entirely — `currency` is its only required key.
  • degrades Transactable currencies — Transactable currencies is not stated and not derivable from this brief. Sellers may return products priced only in currencies you cannot settle in, and mandatory signal charges may turn out to be unsatisfiable at buy time.
  • degrades Fixed price or auction — Fixed price or auction is not stated and not derivable from this brief. Fixed-rate and auction products come back mixed, and the returned `pricing_options` are not pruned to the kind you intended to buy.
  • degrades Maximum CPM — Maximum CPM is not stated and not derivable from this brief. Nothing in the discovery request stops the seller proposing inventory above your price ceiling; you find out at quote time.
  • degrades Minimum impressions per deal — Minimum impressions per deal is not stated and not derivable from this brief. Deals too small to be worth trafficking get proposed and then rejected by hand.
  • degrades Preferred deal types — Preferred deal types is not stated and not derivable from this brief. The seller proposes whatever deal mechanics suit it — PG, PD or PA — and the buyer negotiates backwards from there.
  • degrades Pacing model — Pacing model is not stated and not derivable from this brief. AAMP silently applies EVEN pacing, so a launch-weighted campaign delivers flat unless someone notices.
  • degrades Regions, states or provinces — Regions, states or provinces is not stated and not derivable from this brief. Region-bound inventory (regional OOH, local TV) cannot be matched, so the seller offers national products you then have to re-cut.
  • degrades Metros and DMAs — Metros and DMAs is not stated and not derivable from this brief. DMA-level inventory cannot be filtered, so you get national products that will not clear a local plan.
  • degrades Postal areas — Postal areas is not stated and not derivable from this brief. Postcode-level inventory (direct mail, DOOH, local activation) is invisible to the request.
  • degrades Proximity to locations — Proximity to locations is not stated and not derivable from this brief. Store-radius and drive-time buys cannot be expressed, so proximity inventory is neither found nor priced.
  • degrades Required geo-targeting capability — Required geo-targeting capability is not stated and not derivable from this brief. Digital products from sellers that cannot target at your granularity stay in the result set and fail at setup.
  • degrades Ad formats — Ad formats is not stated and not derivable from this brief. Sellers return products whose creative specs you cannot fill, and the mismatch is discovered when creative is due.
  • degrades IAB standard formats only — IAB standard formats only is not stated and not derivable from this brief. Bespoke and publisher-custom units stay in the result set even when you can only ship IAB standard sizes.
  • degrades Existing creative assets — Existing creative assets is not stated and not derivable from this brief. The plan is built without knowing which creative exists, so products get chosen for formats nobody has assets for.
  • degrades Guaranteed or non-guaranteed — Guaranteed or non-guaranteed is not stated and not derivable from this brief. Guaranteed and non-guaranteed products come back together and the buyer sorts out which is which.
  • degrades Preferred delivery types — Preferred delivery types is not stated and not derivable from this brief. The seller cannot tell a preference from a hard constraint, so it either over-filters or ignores your leaning entirely.
  • degrades Exclusivity — Exclusivity is not stated and not derivable from this brief. Sole-sponsorship and category-exclusive products are not distinguished from ordinary inventory, so an exclusivity ask never reaches the seller as a filter.
  • degrades Video placement types — Video placement types is not stated and not derivable from this brief. Instream budget can be spent on accompanying-content or standalone inventory without the request ever saying otherwise.
  • degrades Audio distribution types — Audio distribution types is not stated and not derivable from this brief. Podcast, broadcast and music-streaming inventory are treated as one pool, so a podcast-only buy can deliver on FM simulcast.
  • degrades Sponsored placement types — Sponsored placement types is not stated and not derivable from this brief. Retail-media requests cannot distinguish sponsored search from sponsored display, and the seller picks for you.
  • degrades Social placement surfaces — Social placement surfaces is not stated and not derivable from this brief. Feed, stories and short-video surfaces are indistinguishable in the request, so delivery lands wherever the seller has supply.
  • degrades Target keywords — Target keywords is not stated and not derivable from this brief. Search and retail-media products cannot be matched to your terms, so keyword availability is never assessed.
  • degrades Approved property list — Approved property list is not stated and not derivable from this brief. Discovery is not restricted to your approved inventory, so products on unvetted properties come back as candidates.
  • degrades Preferred sellers — Preferred sellers is not stated and not derivable from this brief. Buying-platform routing ignores your preferred supply partners and treats all sellers alike.
  • degrades Excluded sellers — Excluded sellers is not stated and not derivable from this brief. Sellers you have blocked are still called and their inventory still returned.
  • degrades Audience constraints (narrowing) — Audience constraints (narrowing) is not stated and not derivable from this brief. Precision constraints are dropped and the campaign reaches the primary audience unnarrowed.
  • degrades Audience extensions (reach) — Audience extensions (reach) is not stated and not derivable from this brief. Reach-extension audiences are silently dropped and the plan under-delivers against its reach goal.
  • degrades Audience exclusions (suppression) — Audience exclusions (suppression) is not stated and not derivable from this brief. Suppression audiences (existing customers, recent converters) are not excluded, and budget is spent re-reaching people you already have.
  • degrades Audience degradation policy — Audience degradation policy is not stated and not derivable from this brief. The buyer agent falls back to its default degradation policy, so a seller that cannot honour part of your plan may have it dropped without anyone being asked.
  • degrades KPI targets — KPI targets is not stated and not derivable from this brief. Nobody can tell whether the campaign succeeded, and the seller optimises to whichever metric it prefers.
  • degrades Minimum exposures for measurement — Minimum exposures for measurement is not stated and not derivable from this brief. Products too small to reach measurement validity stay in the result set and the study is under-powered.
  • degrades Required reporting metrics — Required reporting metrics is not stated and not derivable from this brief. Products that cannot report the metric your KPI is measured in are returned, and the gap shows up as `missing_metrics` on delivery reports.
  • degrades Required performance standards — Required performance standards is not stated and not derivable from this brief. Viewability, IVT and attention thresholds are never stated up front, so they become a post-campaign argument instead of a discovery filter.
  • degrades Required vendor metrics — Required vendor metrics is not stated and not derivable from this brief. Products that cannot report your measurement vendor's metrics are returned, and the vendor discovers the gap in flight.
  • degrades Required protocol features — Required protocol features is not stated and not derivable from this brief. Sellers that cannot support inline creative management, property-list filtering, catalog management or committed metrics are still returned, and the buy fails at execution.
  • degrades Trusted Match capability — Trusted Match capability is not stated and not derivable from this brief. Products without the identity or context match capability you rely on are returned as if they were interchangeable with ones that have it.
  • degrades Vendor-specific filter extensions — Vendor-specific filter extensions is not stated and not derivable from this brief. Seller-specific criteria with no standard field have nowhere to go and end up as prose the seller may never parse.
  • degrades Excluded content categories — Excluded content categories is not stated and not derivable from this brief. Your ads run beside content you told someone you would avoid, and the first evidence is a screenshot.
  • degrades Excluded keywords — Excluded keywords is not stated and not derivable from this brief. Keyword-level blocks are not applied and unsuitable adjacency is caught after delivery, if at all.
  • degrades Excluded domains and brands — Excluded domains and brands is not stated and not derivable from this brief. Blocked domains and brands remain eligible, and the block list has to be re-applied in the DSP — if there is one in the path.
  • degrades Human approval: plan review — Human approval: plan review is not stated and not derivable from this brief. AAMP's default applies and the pipeline halts at an approval gate the brief never discussed.
  • degrades Human approval: booking — Human approval: booking is not stated and not derivable from this brief. AAMP's default applies and the agent will not book without a human, whatever the brief implied about autonomy.
  • degrades Human approval: creative assignment — Human approval: creative assignment is not stated and not derivable from this brief. AAMP's default applies and creative is assigned to placements with nobody signing it off.
  • degrades Human approval: pacing and reallocation — Human approval: pacing and reallocation is not stated and not derivable from this brief. AAMP's default applies and the agent reallocates budget between channels without asking.

What gets sent

AdCP get_products request

Structured filters plus the residual prose, which AdCP carries as one unvalidated string.

{
  "buying_mode": "brief",
  "brief": "Q4 holiday campaign for a CPG snack brand. Channels: CTV plus digital display and online video. Budget: $500,000 net. Market: United States. Target demo: adults 25-54. Flight: November 1 - December 31, 2026. Goal: drive incremental household penetration and retail sales lift. Requirements: premium CTV inventory, brand safety controls, frequency cap 3 per week.",
  "filters": {
    "start_date": "2026-11-01",
    "end_date": "2026-12-31",
    "countries": [
      "US"
    ],
    "channels": [
      "ctv",
      "display",
      "olv"
    ]
  }
}
34 fields left out of this payload, and what that costs
  • budget_total stated filters.budget_range requires an ISO 4217 currency and this brief states none; the engine will not assume USD.
  • budget_min missing Sellers may return low-minimum products that cannot absorb your spend, so the plan fragments across too many line items.
  • currency missing AAMP rejects the brief, and AdCP rejects `budget_range` entirely — `currency` is its only required key.
  • audience_primary stated AdCP filters.signal_targeting takes SignalRefs resolved against a signals agent. A demographic phrase is not a SignalRef, and this engine makes no network call to turn one into one.
  • audience_exclusions missing Suppression audiences (existing customers, recent converters) are not excluded, and budget is spent re-reaching people you already have.
  • brand_domain missing The seller cannot resolve brand identity at execution time, so category exclusivity and competitive separation cannot be applied to your buy.
  • brand_industries missing Publishers holding category-exclusive inventory cannot tell whether your buy conflicts with a competitor already on the property.
  • pricing_currencies missing Sellers may return products priced only in currencies you cannot settle in, and mandatory signal charges may turn out to be unsatisfiable at buy time.
  • is_fixed_price missing Fixed-rate and auction products come back mixed, and the returned `pricing_options` are not pruned to the kind you intended to buy.
  • regions missing Region-bound inventory (regional OOH, local TV) cannot be matched, so the seller offers national products you then have to re-cut.
  • metros missing DMA-level inventory cannot be filtered, so you get national products that will not clear a local plan.
  • postal_areas missing Postcode-level inventory (direct mail, DOOH, local activation) is invisible to the request.
  • geo_proximity missing Store-radius and drive-time buys cannot be expressed, so proximity inventory is neither found nor priced.
  • required_geo_targeting missing Digital products from sellers that cannot target at your granularity stay in the result set and fail at setup.
  • format_ids missing Sellers return products whose creative specs you cannot fill, and the mismatch is discovered when creative is due.
  • standard_formats_only missing Bespoke and publisher-custom units stay in the result set even when you can only ship IAB standard sizes.
  • delivery_type missing Guaranteed and non-guaranteed products come back together and the buyer sorts out which is which.
  • preferred_delivery_types missing The seller cannot tell a preference from a hard constraint, so it either over-filters or ignores your leaning entirely.
  • exclusivity missing Sole-sponsorship and category-exclusive products are not distinguished from ordinary inventory, so an exclusivity ask never reaches the seller as a filter.
  • video_placement_types missing Instream budget can be spent on accompanying-content or standalone inventory without the request ever saying otherwise.
  • audio_distribution_types missing Podcast, broadcast and music-streaming inventory are treated as one pool, so a podcast-only buy can deliver on FM simulcast.
  • sponsored_placement_types missing Retail-media requests cannot distinguish sponsored search from sponsored display, and the seller picks for you.
  • social_placement_surfaces missing Feed, stories and short-video surfaces are indistinguishable in the request, so delivery lands wherever the seller has supply.
  • keywords missing Search and retail-media products cannot be matched to your terms, so keyword availability is never assessed.
  • property_list missing Discovery is not restricted to your approved inventory, so products on unvetted properties come back as candidates.
  • min_exposures missing Products too small to reach measurement validity stay in the result set and the study is under-powered.
  • required_metrics missing Products that cannot report the metric your KPI is measured in are returned, and the gap shows up as `missing_metrics` on delivery reports.
  • required_performance_standards missing Viewability, IVT and attention thresholds are never stated up front, so they become a post-campaign argument instead of a discovery filter.
  • required_vendor_metrics missing Products that cannot report your measurement vendor's metrics are returned, and the vendor discovers the gap in flight.
  • required_features missing Sellers that cannot support inline creative management, property-list filtering, catalog management or committed metrics are still returned, and the buy fails at execution.
  • trusted_match missing Products without the identity or context match capability you rely on are returned as if they were interchangeable with ones that have it.
  • required_axe_integrations missing Nothing at 3.1.13 — the field is deprecated in favour of `trusted_match`, and populating it is a compatibility choice rather than a requirement.
  • filters_ext missing Seller-specific criteria with no standard field have nowhere to go and end up as prose the seller may never parse.
  • frequency_cap derived AdCP get_products has no field for frequency cap. AAMP takes `max_impressions` + `period_hours`, both `> 0`. `get_products` has no frequency field: AdCP has `enums/frequency-cap-scope.json`, but it applies to a media buy's packages, so a frequency requirement cannot influence which products are returned.

AAMP CampaignBrief

IAB Tech Lab buyer agent, models/campaign_brief.py — eight required fields, cross-field validators.

{
  "description": "Q4 holiday campaign for a CPG snack brand. Channels: CTV plus digital display and online video. Budget: $500,000 net. Market: United States. Target demo: adults 25-54. Flight: November 1 - December 31, 2026. Goal: drive incremental household penetration and retail sales lift. Requirements: premium CTV inventory, brand safety controls, frequency cap 3 per week.",
  "channels": [
    {
      "channel": "CTV"
    },
    {
      "channel": "DISPLAY"
    }
  ],
  "target_geo": [
    {
      "geo_type": "COUNTRY",
      "geo_value": "US"
    }
  ],
  "flight_start": "2026-11-01",
  "flight_end": "2026-12-31",
  "total_budget": 500000,
  "frequency_cap": {
    "max_impressions": 3,
    "period_hours": 168
  }
}
32 fields left out of this payload, and what that costs
  • channels derived online video has no AAMP ChannelType (the enum is CTV, DISPLAY, AUDIO, NATIVE, DOOH, LINEAR_TV), so it is absent from the AAMP brief while present in the AdCP request.
  • channel_budget_split missing ChannelAllocation requires budget_pct and the percentages must sum to 100. This brief states no split, so the allocations are emitted without it and the model will refuse to construct. The engine does not invent a split to make the model happy.
  • format_ids missing Sellers return products whose creative specs you cannot fill, and the mismatch is discovered when creative is due.
  • regions missing Region-bound inventory (regional OOH, local TV) cannot be matched, so the seller offers national products you then have to re-cut.
  • metros missing DMA-level inventory cannot be filtered, so you get national products that will not clear a local plan.
  • postal_areas missing Postcode-level inventory (direct mail, DOOH, local activation) is invisible to the request.
  • audience_primary stated AudiencePlan.primary is a required AudienceRef carrying type + identifier + taxonomy + version + source. The brief says "adults 25-54", which resolves to no IAB Audience Taxonomy 1.1 identifier. The plan is omitted rather than half-built, so nothing downstream mistakes a phrase for a segment.
  • audience_constraints missing Precision constraints are dropped and the campaign reaches the primary audience unnarrowed.
  • audience_extensions missing Reach-extension audiences are silently dropped and the plan under-delivers against its reach goal.
  • audience_exclusions missing Suppression audiences (existing customers, recent converters) are not excluded, and budget is spent re-reaching people you already have.
  • advertiser_id missing The AAMP brief will not construct, so nothing downstream of the buyer agent runs.
  • agency_id missing Billing and seat attribution fall to whatever the buying platform infers.
  • campaign_name missing The AAMP brief will not construct, and on the AdCP side the campaign has no human-readable handle in any artefact the seller sees.
  • internal_notes missing Internal caveats stay in email instead of travelling with the brief.
  • objective missing The AAMP brief will not construct, and no downstream allocation logic knows whether to optimise for reach or for conversion.
  • currency missing AAMP rejects the brief, and AdCP rejects `budget_range` entirely — `currency` is its only required key.
  • deal_max_cpm missing Nothing in the discovery request stops the seller proposing inventory above your price ceiling; you find out at quote time.
  • deal_min_impressions missing Deals too small to be worth trafficking get proposed and then rejected by hand.
  • deal_types missing The seller proposes whatever deal mechanics suit it — PG, PD or PA — and the buyer negotiates backwards from there.
  • pacing_model missing AAMP silently applies EVEN pacing, so a launch-weighted campaign delivers flat unless someone notices.
  • creative_ids missing The plan is built without knowing which creative exists, so products get chosen for formats nobody has assets for.
  • preferred_sellers missing Buying-platform routing ignores your preferred supply partners and treats all sellers alike.
  • excluded_sellers missing Sellers you have blocked are still called and their inventory still returned.
  • audience_strictness missing The buyer agent falls back to its default degradation policy, so a seller that cannot honour part of your plan may have it dropped without anyone being asked.
  • kpi_targets missing Nobody can tell whether the campaign succeeded, and the seller optimises to whichever metric it prefers.
  • excluded_content_categories missing Your ads run beside content you told someone you would avoid, and the first evidence is a screenshot.
  • excluded_keywords missing Keyword-level blocks are not applied and unsuitable adjacency is caught after delivery, if at all.
  • excluded_domains missing Blocked domains and brands remain eligible, and the block list has to be re-applied in the DSP — if there is one in the path.
  • approval_plan_review missing AAMP's default applies and the pipeline halts at an approval gate the brief never discussed.
  • approval_booking missing AAMP's default applies and the agent will not book without a human, whatever the brief implied about autonomy.
  • approval_creative missing AAMP's default applies and creative is assigned to placements with nobody signing it off.
  • approval_pacing_adjustment missing AAMP's default applies and the agent reallocates budget between channels without asking.

What it will not do

  • The transactable score covers the request-level rules this engine is capable of breaking. Full JSON Schema validation against the AdCP release does not run in your browser, so a payload that clears it here can still fail a seller's validator.

Before you send it

  1. Clear the blocks first. Those are values a required field wants and does not have, so nothing downstream runs.
  2. Read the drops. You wrote those, and neither protocol has anywhere to put them — say them to your counterparty in a channel that is not this one.
  3. Settle the assumptions with the people who have to agree. The pre-flight checklist is the list of questions to put to them.

The field map behind the two scores is published as the completeness rubric, concept by concept.

Frequently asked

Why does it refuse to fill in the channel split?
Because a split is a commitment and nothing in your text implies one. Values the engine could pick are listed under Assumptions with the rule that produced them, and they reach neither payload until you accept them.
Will a higher score get me better inventory?
Unproven. The score counts which values reach a protocol field. Three sales agents in the public AdCP registry answer an anonymous get_products, and one of them returns the same four products whatever the brief says.
Which AAMP CampaignBrief does it emit?
The one in models/campaign_brief.py, with eight required fields and cross-field validators. The IAB Tech Lab buyer-agent repository defines a second, incompatible CampaignBrief in models/flow_state.py and ships no adapter between them.