Skip to main content

AAO Directory API

The AAO directory at agenticadvertising.org indexes publisher adagents.json files across the open web. This API surfaces the inverse map every sales-agent operator needs at sync time:
“What publishers have authorized my agent?”
Without this endpoint, operators have to either maintain the publisher domain list manually and call fetch_agent_authorizations against it, or crawl the open web themselves. Both are infeasible at managed-network scale (cafemedia alone delegates ~6,800 publisher domains under a single manager file). This endpoint is discovery, not authorization. The publisher’s own adagents.json remains the trust root. The directory tells you which publishers to verify directly via the SDK’s per-domain primitives (verify_agent_authorization, fetch_agent_authorizations).

Endpoint

{agent_url} MUST be percent-encoded. The directory canonicalizes the lookup key (lowercase host, default port stripped, trailing slash on path component normalized) using the same convention the SDK applies in verify_agent_authorization.

Query parameters

Worked example: filtering by multiple status values

Equivalent in TypeScript:
Equivalent in Python (requests):
The OpenAPI fragment for the status parameter:
Repeated-key was chosen because (a) it is what URLSearchParams.append() and OpenAPI’s default explode: true produce, (b) it composes cleanly with future values that might contain a comma, and (c) it leaves no parser ambiguity at the directory.

Worked example: requesting ?include=properties for full set-diff

The default response carries properties_authorized as a count only. Count-equality is not set-equality: a publisher rotating three properties leaves the count unchanged but the set entirely different, which a count-based divergence detector cannot see. ?include=properties adds a property_ids: list[string] field per PublisherEntry — the canonical IDs the agent’s selectors resolve to under that publisher — so consumers can run full set-diff against a federated fetch_agent_authorizations result and detect rotation, not just delta-in-magnitude. The flag is opt-in to keep the default page payload small. Inline IDs add roughly the per-publisher property count × ~16 bytes per ID; on a managed-network parent file (~6,800 publishers × avg 1 property each ≈ 7 KB of additional IDs), the overhead is small but non-zero. Pagination semantics are unchanged.

Response

With ?include=properties, each PublisherEntry additionally carries property_ids:

Field reference

Envelope

PublisherEntry

discovery_method values

The directory verifies the managerdomain safety rule before returning a row with discovery_method: ads_txt_managerdomain — this is the directory’s main value-add over a per-operator ads.txt crawl.

status values

unbound, pending, unreachable, and no_properties are intentionally not part of v1. The directory only indexes publishers whose adagents.json was successfully fetched and references the agent. If a publisher disappears, the directory drops it from results rather than returning a tombstone (consumers track membership via set-diff against prior pages).

HTTP semantics

The endpoint sets Cache-Control and ETag. Conditional GET (If-None-Match) is the wire-level cache mechanism; directory_indexed_at in the body is the freshness anchor for consumer logic.

Authentication

V1 is unauthenticated. Publisher adagents.json files are public; the inverse map is public. If rate-limiting graduates from IP-based to identity-based, the path is a separate RFC layering RFC 9421 request signing keyed off the agent’s published JWKS — the agent proves it controls agent_url by signing the request. Out of scope for this RFC.

Pagination

Cursors are opaque. Treat them as substitutable strings and pass them back verbatim. The directory MAY change cursor format without notice; consumers MUST NOT parse cursor contents. A cursor remains valid for at least one directory refresh cycle. Past that, the directory MAY return 400 with cursor_expired or 200 with re-traversal from the start — both are conforming. Consumers SHOULD record the wall-clock time of the prior request and refuse to use cursors older than 24 hours.

Relationship to other primitives

The AAO directory complements the existing SDK primitives: The first two answer questions where the operator already knows the publisher set. The directory endpoint answers the operator’s actual sync-time question: “what’s my publisher set?” The recommended workflow:
  1. Call GET /v1/agents/{agent_url}/publishers to discover the publisher set.
  2. For each publisher_domain in the response, the operator MAY call verify_agent_authorization against the publisher’s own adagents.json to re-confirm against the trust root. The directory’s last_verified_at reduces but does not eliminate the need for per-domain verification on critical paths.
  3. Use the response’s properties_authorized / properties_total for operator-facing scope summaries, and the signing_keys_pinned flag to surface which agents must publish a JWKS matching the publisher’s pin.
  4. Operators running a divergence detector (catching cases where the directory and the publisher’s live adagents.json disagree) SHOULD request ?include=properties and compare the directory’s property_ids[] against a federated fetch as a set, not as a count. A publisher rotating N properties produces equal counts on both sides; only set-comparison catches it.

Relationship to publisher_properties inline resolution

On managed-network-shape parent files (per adcp#4825 inline resolution rule), the directory computes properties_total from the parent file’s inline properties[] filtered by publisher_domain. Strict federation at this scale would require N HTTP fetches per directory refresh per publisher — the same scale problem operators have, moved one layer up. The directory uses the inline resolution rule the spec endorses.

Out of scope (v1)

  • Authentication. Public endpoint, anonymous rate limiting. Identity-bound limits arrive in a separate RFC if needed.
  • Cross-directory federation. Single directory. The endpoint shape is defined such that multiple AAO-compatible directories could implement it; discovery of which directory to query is configuration today.
  • Push notification of new authorizations. Poll-based v1.
  • Full property objects inline. ?include=properties returns the resolved property_ids[] only — not the property objects themselves. Consumers with the IDs can fetch detail via existing per-domain primitives.

See also