Aller au contenu principal
A2A series · 4 / 4

Speak the AdCP standard with an agent:
validate & preview a media buy

AdCP (Ad Context Protocol) is the media-buy standard. OrbiAds exposes it natively: a buy-side agent sends a create_media_buy request, the OrbiAds agent validates then previews it as a GAM deal — fully read-only.

OA
OrbiAds Engineering
Published June 30, 2026 · 9 min read

Final episode. So far, our agents read Google Ad Manager. Here we speak the media-buy standard: AdCP (Ad Context Protocol). A buy-side agent sends a create_media_buy request; the OrbiAds agent validates then previews it as a GAM deal, writing nothing.

AdCP is native in OrbiAds (don't hand-roll anything)

The reflex to avoid: building a "homemade JSON brief". OrbiAds already exposes a complete AdCP surface. The tools live under parent tools (parent → action pattern):

CapabilityCallType
Sell-side discoveryproducts → get_products_adcpread
Validate a create_media_buydeals(action='adcp_validate')read
Translate to DealSpec (no execute)deals(action='adcp_preview')read
Execute end-to-enddeals(action='adcp_create')write

The AdCP request (create_media_buy)

Here's what a media-buy request from a buy-side agent looks like:

sample_adcp_request.json
{
  "idempotency_key": "demo-mediabuy-0001-acme-q3",
  "account": { "account_id": "demo-buyer-seat-001", "sandbox": true },
  "brand": { "domain": "acme.com", "industries": ["retail"] },
  "start_time": "2026-09-01T00:00:00Z",
  "end_time": "2026-09-30T23:59:59Z",
  "packages": [
    {
      "package_id": "pkg-homepage-fr-1",
      "budget": 5000.0,
      "impressions": 1000000,
      "targeting_overlay": { "geo_countries": ["FR"], "language": ["fr"] }
    }
  ],
  "ext": {
    "orbiads_deal_type": "pg_guaranteed",
    "orbiads_buyer_account_id": "demo-authorized-buyer-seat"
  }
}

The A2A case: a read-only gateway

The adcp_gateway agent receives the request (from a buy-side agent or the user), then: (1) check_credentials + network check, (2) deals(adcp_validate), (3) if valid, deals(adcp_preview), (4) a human-readable summary. It never calls adcp_create.

AdCP agent: validate then read-only preview
Native AdCP: the agent validates the request (deals(adcp_validate)) then previews it as a GAM deal (deals(adcp_preview)) — read-only, nothing written. The actionable error ADCP_ADVERTISER_UNRESOLVED shows the GAM translation at work.

Three frictions to know

  • Filtering by name, not by action. tool_filter can't isolate an action: exposing deals also exposes writes. Guardrails = the prompt (allow only validate/preview) + OrbiAds' confirmation_token.
  • Real advertiser lookup. adcp_preview resolves the brand in GAM. No match → ADCP_ADVERTISER_UNRESOLVED: provide ext.orbiads_advertiser_company_id.
  • Model choice. A large nested AdCP JSON can make some lightweight models "code" the call; a stronger model makes it reliable. It's the approach we validate, the model stays a parameter.

Series wrap-up

In four episodes: we connected an agent to GAM (OAuth), deployed it and made it discoverable over A2A, composed a multi-agent business case, and spoke the AdCP standard. The through-line: everything rests on a clean connection and guardrails (read-only, network check, confirmation_token). The rest is composition.

The full code, ready to clone

All 4 agents, the step-by-step tutorial and the examples — on GitHub, MIT licensed.

FAQ

Frequently asked questions

What is AdCP (Ad Context Protocol)?

AdCP is an open standard describing, in JSON, a media-buy request (create_media_buy) that a buy-side agent sends to a seller. OrbiAds supports it natively and translates it into Google Ad Manager deals — no need to invent a homemade brief format.

Which AdCP tools does OrbiAds expose?

Under the deals parent tool: adcp_validate (validates the payload against the v3 schema, read-only), adcp_preview (translates the request into a DealSpec without executing, read-only), adcp_create (executes end-to-end, write). On the sell side, products → get_products_adcp does product discovery in AdCP format.

How do you guarantee a read-only AdCP agent?

ADK's tool_filter filters by tool name, not by action — exposing deals also exposes adcp_create (write). We rely on (a) the agent instruction allowing only adcp_validate/adcp_preview, and (b) the OrbiAds guardrail: adcp_create refuses to run without a confirmation_token returned by a prior preview. For strict read-only you'd need a dedicated server scope.

Why does preview return ADCP_ADVERTISER_UNRESOLVED?

Because adcp_preview performs a real advertiser lookup in GAM. If the brand (brand.domain) matches no advertiser, it returns this actionable error: provide ext.orbiads_advertiser_company_id (the GAM Company ID). This is expected behavior, not a bug.