Problem
get_properties_by_agent(adagents, agent_url) returns [] in two semantically very different cases, and callers can't tell them apart:
- Valid file, agent not authorized. The file conforms to the JSON Schema and lists other agents, just not this one (or restricts this agent to properties it isn't matched to).
- Schema-invalid file. Entries are missing
authorization_type plus a required selector. Per the published schema (https://adcontextprotocol.org/schemas/v1/adagents.json), every entry in authorized_agents.items must satisfy one of:
oneOf:
- { required: [url, authorized_for, authorization_type, property_ids] }
- { required: [url, authorized_for, authorization_type, property_tags] }
- { required: [url, authorized_for, authorization_type, properties] }
- { required: [url, authorized_for, authorization_type, publisher_properties] }
- { required: [url, authorized_for, authorization_type, signal_ids] }
- { required: [url, authorized_for, authorization_type, signal_tags] }
Bare entries like {url, authorized_for} match no variant. The SDK currently treats them as "authorizes nothing" — correct by the spec, but the caller has no way to know whether the file is structurally broken or just doesn't list us yet.
Real-world impact
Multiple publishers in production are shipping bare-entry adagents.json. Example (wonderstruck.org):
{
"$schema": "https://adcontextprotocol.org/schemas/v1/adagents.json",
"authorized_agents": [
{"url": "https://wonderstruck.sales-agent.scope3.com", "authorized_for": "Authorized for display banners"},
{"url": "https://interchange.io", "authorized_for": "Authorized for display banners"}
],
"properties": [
{"property_id": "main_site", "property_type": "website", "name": "Main site",
"identifiers": [{"type": "domain", "value": "wonderstruck.org"}], "tags": ["sites"]}
]
}
get_properties_by_agent(data, "https://wonderstruck.sales-agent.scope3.com") returns []. Our publisher-partners UI shows "Pending 0/0," which reads as "publisher hasn't authorized us yet" — but actually the file is invalid. We end up chasing publishers without knowing what to tell them. The online validator at agenticadvertising.org reports these files as valid: true (filed separately against adcontextprotocol/adcp), reinforcing the confusion.
Proposed API
A sibling validator that introspects without changing existing behavior:
from adcp.adagents import validate_adagents
result = validate_adagents(adagents_data)
# AdagentsValidationResult(
# schema_valid: bool,
# errors: list[AdagentsEntryError], # per-entry problems
# authorized_agents_count: int,
# properties_count: int,
# )
AdagentsEntryError would carry:
- entry index and
url
- error kind:
missing_authorization_type, missing_selector_for_type, unknown_authorization_type, selector_present_for_wrong_type, etc.
- human-readable message
Then callers can do:
result = validate_adagents(data)
if not result.schema_valid:
show_publisher_error(result.errors)
elif not get_properties_by_agent(data, agent_url):
show_publisher_error("File is valid but doesn't list your agent")
else:
show_authorized(...)
Alternative considered
Adding a second return value or raising on get_properties_by_agent — both break the API. Sibling validator avoids that.
Cross-SDK note
The TS SDK (adcp-client) doesn't implement per-agent resolution at all today (filed separately). Once it does, the same validator helper should land there for consistency.
Willing to PR
Happy to put up a PR if the API shape is agreed.
Problem
get_properties_by_agent(adagents, agent_url)returns[]in two semantically very different cases, and callers can't tell them apart:authorization_typeplus a required selector. Per the published schema (https://adcontextprotocol.org/schemas/v1/adagents.json), every entry inauthorized_agents.itemsmust satisfy one of:{url, authorized_for}match no variant. The SDK currently treats them as "authorizes nothing" — correct by the spec, but the caller has no way to know whether the file is structurally broken or just doesn't list us yet.Real-world impact
Multiple publishers in production are shipping bare-entry adagents.json. Example (wonderstruck.org):
{ "$schema": "https://adcontextprotocol.org/schemas/v1/adagents.json", "authorized_agents": [ {"url": "https://wonderstruck.sales-agent.scope3.com", "authorized_for": "Authorized for display banners"}, {"url": "https://interchange.io", "authorized_for": "Authorized for display banners"} ], "properties": [ {"property_id": "main_site", "property_type": "website", "name": "Main site", "identifiers": [{"type": "domain", "value": "wonderstruck.org"}], "tags": ["sites"]} ] }get_properties_by_agent(data, "https://wonderstruck.sales-agent.scope3.com")returns[]. Our publisher-partners UI shows "Pending 0/0," which reads as "publisher hasn't authorized us yet" — but actually the file is invalid. We end up chasing publishers without knowing what to tell them. The online validator at agenticadvertising.org reports these files asvalid: true(filed separately against adcontextprotocol/adcp), reinforcing the confusion.Proposed API
A sibling validator that introspects without changing existing behavior:
AdagentsEntryErrorwould carry:urlmissing_authorization_type,missing_selector_for_type,unknown_authorization_type,selector_present_for_wrong_type, etc.Then callers can do:
Alternative considered
Adding a second return value or raising on
get_properties_by_agent— both break the API. Sibling validator avoids that.Cross-SDK note
The TS SDK (
adcp-client) doesn't implement per-agent resolution at all today (filed separately). Once it does, the same validator helper should land there for consistency.Willing to PR
Happy to put up a PR if the API shape is agreed.