Empirical evidence
Pulled https://cafemedia.com/.well-known/adagents.json (2.6 MB, `last_updated: 2026-05-14`, contact: Raptive). It is the largest known AAO-conformant file in production and represents the canonical "managed network" delegation pattern (~6,800 publisher properties under one operator). Structure:
{
\"\$schema\": \"https://adcontextprotocol.org/schemas/v3/adagents.json\",
\"authorized_agents\": [
{
\"url\": \"https://interchange.io\",
\"authorization_type\": \"publisher_properties\",
\"authorized_for\": \"Official sales agent for Raptive US display inventory\",
\"publisher_properties\": [{
\"selection_type\": \"by_tag\",
\"property_tags\": [\"raptive_managed\"],
\"publisher_domains\": [\"recipeswithessentialoils.com\", \"cravethegood.com\", ... 6800 total]
}]
}
],
\"properties\": [
{
\"property_id\": \"5bd748df...\",
\"property_type\": \"website\",
\"identifiers\": [{\"type\": \"domain\", \"value\": \"recipeswithessentialoils.com\"}],
\"publisher_domain\": \"recipeswithessentialoils.com\",
\"tags\": [\"raptive_managed\"]
},
... 6843 total inline properties
],
\"tags\": {\"raptive_managed\": {\"name\": \"Raptive Managed\", ...}}
}
The gap
Per the spec at /schemas/3.1.0-beta.1/core/publisher-property-selector.json:
"the same `property_tags` predicate is resolved against each listed publisher's adagents.json"
This is the federated resolution model: to enumerate cafemedia's authorized inventory, a resolver must fetch each of the 6,800 child publishers' adagents.json files, follow their delegation chains, and find properties matching the selector. Operationally infeasible at managed-network scale — 6,800 HTTP fetches per agent-authorization check.
Cafemedia's pragmatic answer: inline the properties in the parent file with a publisher_domain field on each property record. The selector + publisher_domains list + property_tags list unambiguously identifies which inline properties belong to which child. But the spec doesn't currently endorse this resolution path.
Result today
The Python SDK at adcp/adagents.py:953-957 handles publisher_properties by returning the raw selector dicts:
if authorization_type == \"publisher_properties\":
publisher_props = agent.get(\"publisher_properties\", [])
if not isinstance(publisher_props, list):
return []
return [p for p in publisher_props if isinstance(p, dict)]
So get_properties_by_agent(cafemedia_data, \"https://interchange.io\") returns 1 dict (the selector), not the 6,843 actual properties. Downstream consumers (the Prebid Sales Agent's _count_total_properties at src/services/aao_lookup_service.py:249) get nonsense counts ("1 / 1 authorized" instead of "6843 / 6843").
Proposal — pick one
Option A (recommended): Extend the spec to recognize the inline-with-publisher_domain resolution path. When a parent file (a) contains a publisher_properties selector AND (b) has top-level properties[] entries with publisher_domain fields matching the selector's publisher_domains, the resolver MAY satisfy the selector from the parent file's inline properties — no per-child fetch required. Keeps federated resolution as a fallback for files that don't inline.
Option B: Spec stays as-is (strictly federated). Then cafemedia and every future managed network needs to either (i) restructure each of 6,800 child domains to publish their own adagents.json, or (ii) the SDK adds a pragmatic "check parent file first" extension that's nonconformant per spec. This is the worse outcome — pushes complexity onto every operator.
Option C: Spec defines an explicit "managed network" authorization_type that says "properties are inlined in this file with publisher_domain field" — distinct from cross-publisher federation. Cleanest but breaks cafemedia's current file shape and requires migration.
Why this is urgent
Cafemedia is the production reference. Their file has been static-ish since at least 2026-05. Every downstream consumer either:
- Reports broken property counts (current SDK behavior)
- Hits 6,800 HTTP fetches to enumerate the network (strict spec compliance)
- Forks the SDK with a private "parent file inline lookup" extension
The Prebid Sales Agent (prebid/salesagent#511) hit this trying to onboard Raptive.
Companion tickets
References
_resolve_agent_properties SDK gap: adcp/adagents.py:909-959
- Selector schema:
https://adcontextprotocol.org/schemas/3.1.0-beta.1/core/publisher-property-selector.json
- Live cafemedia file:
https://cafemedia.com/.well-known/adagents.json (HTTP 200, 2.6 MB)
Empirical evidence
Pulled
https://cafemedia.com/.well-known/adagents.json(2.6 MB, `last_updated: 2026-05-14`, contact: Raptive). It is the largest known AAO-conformant file in production and represents the canonical "managed network" delegation pattern (~6,800 publisher properties under one operator). Structure:{ \"\$schema\": \"https://adcontextprotocol.org/schemas/v3/adagents.json\", \"authorized_agents\": [ { \"url\": \"https://interchange.io\", \"authorization_type\": \"publisher_properties\", \"authorized_for\": \"Official sales agent for Raptive US display inventory\", \"publisher_properties\": [{ \"selection_type\": \"by_tag\", \"property_tags\": [\"raptive_managed\"], \"publisher_domains\": [\"recipeswithessentialoils.com\", \"cravethegood.com\", ... 6800 total] }] } ], \"properties\": [ { \"property_id\": \"5bd748df...\", \"property_type\": \"website\", \"identifiers\": [{\"type\": \"domain\", \"value\": \"recipeswithessentialoils.com\"}], \"publisher_domain\": \"recipeswithessentialoils.com\", \"tags\": [\"raptive_managed\"] }, ... 6843 total inline properties ], \"tags\": {\"raptive_managed\": {\"name\": \"Raptive Managed\", ...}} }The gap
Per the spec at
/schemas/3.1.0-beta.1/core/publisher-property-selector.json:This is the federated resolution model: to enumerate cafemedia's authorized inventory, a resolver must fetch each of the 6,800 child publishers' adagents.json files, follow their delegation chains, and find properties matching the selector. Operationally infeasible at managed-network scale — 6,800 HTTP fetches per agent-authorization check.
Cafemedia's pragmatic answer: inline the properties in the parent file with a
publisher_domainfield on each property record. The selector + publisher_domains list + property_tags list unambiguously identifies which inline properties belong to which child. But the spec doesn't currently endorse this resolution path.Result today
The Python SDK at
adcp/adagents.py:953-957handlespublisher_propertiesby returning the raw selector dicts:So
get_properties_by_agent(cafemedia_data, \"https://interchange.io\")returns 1 dict (the selector), not the 6,843 actual properties. Downstream consumers (the Prebid Sales Agent's_count_total_propertiesatsrc/services/aao_lookup_service.py:249) get nonsense counts ("1 / 1 authorized" instead of "6843 / 6843").Proposal — pick one
Option A (recommended): Extend the spec to recognize the inline-with-
publisher_domainresolution path. When a parent file (a) contains apublisher_propertiesselector AND (b) has top-levelproperties[]entries withpublisher_domainfields matching the selector'spublisher_domains, the resolver MAY satisfy the selector from the parent file's inline properties — no per-child fetch required. Keeps federated resolution as a fallback for files that don't inline.Option B: Spec stays as-is (strictly federated). Then cafemedia and every future managed network needs to either (i) restructure each of 6,800 child domains to publish their own adagents.json, or (ii) the SDK adds a pragmatic "check parent file first" extension that's nonconformant per spec. This is the worse outcome — pushes complexity onto every operator.
Option C: Spec defines an explicit "managed network" authorization_type that says "properties are inlined in this file with
publisher_domainfield" — distinct from cross-publisher federation. Cleanest but breaks cafemedia's current file shape and requires migration.Why this is urgent
Cafemedia is the production reference. Their file has been static-ish since at least 2026-05. Every downstream consumer either:
The Prebid Sales Agent (prebid/salesagent#511) hit this trying to onboard Raptive.
Companion tickets
References
_resolve_agent_propertiesSDK gap:adcp/adagents.py:909-959https://adcontextprotocol.org/schemas/3.1.0-beta.1/core/publisher-property-selector.jsonhttps://cafemedia.com/.well-known/adagents.json(HTTP 200, 2.6 MB)