---
title: "Publisher lookup"
method: GET
path: "/api/registry/publisher"
tags: ["Authorization Lookups"]
---

# Publisher lookup

`GET /api/registry/publisher`

Given a domain, returns the inventory this entity publishes and which agents it authorizes.

**This endpoint is unauthenticated and returns the same response shape for every caller.** Compare to `/api/registry/operator`, where AAO membership tier and profile ownership unlock additional agent visibility (`members_only`, `private`). AAO membership does not change the `/publisher` response today.

**Property source precedence:** publisher-attested adagents.json properties win first. When no publisher-attested adagents properties exist for the domain, brand.json properties supplement and override lower-trust rows, followed by approved community catalogs, then crawler-discovered rows. Each property carries a `source` field (`adagents_json` / `brand_json` / `community` / `discovered`).

**Per-agent rollup:** each entry in `authorized_agents` may carry `properties_authorized` + `properties_total` + `publisher_wide`. The rollup is suppressed (fields absent) when (a) properties are entirely brand.json-hydrated — no adagents.json claim has been made — or (b) the publisher has more than 50 authorized agents (above-cap entries are returned without rollup; `rollup_truncated` is set with `{ cap, total_agents }`). Use `/api/registry/publisher/authorization?domain=X&agent=Y` for the per-agent count when the index rollup is absent.

## Query parameters

- `domain` string, required

## Response `200`

Publisher lookup result

- PublisherLookupResult
  - `domain` string, required
  - `member` object, nullable, required
    - `slug` string
    - `display_name` string
    - `membership_tier` string — Raw AAO membership tier enum (e.g. `individual_professional`, `company_leader`). Present only when the profile owner has set their member card to public (`is_public=true`) AND the org has a resolvable tier. Absent for private profiles and for orgs without an active tier-bearing subscription.
    - `membership_tier_label` string — Human-readable label for `membership_tier` (e.g. `Professional`, `Partner`, `Leader`). Matches the AAO pricing page. Use this for UI display; the raw enum is for programmatic gating. Presence rules match `membership_tier`.
    - `is_founding_member` boolean — True when the profile owner carries the Founding Member badge (joined before the founding-cohort cutoff). Surfaced when the profile owner has set their member card to public (`is_public=true`). Absent for private profiles. Founding Member is orthogonal to tier — founding orgs typically display both (e.g. Scope3 shows `Partner` + `Founding Member`).
  - `adagents_valid` boolean, nullable, required
  - `discovery_method` 'direct' | 'authoritative_location' | 'ads_txt_managerdomain' | 'adagents_authoritative' | 'community_catalog' | 'null', nullable — How the publisher's adagents.json was discovered on the most recent successful crawl or registry write. `direct`: publisher's own /.well-known/ served the document. `authoritative_location`: publisher's stub redirected to a canonical URL. `ads_txt_managerdomain`: manifest was discovered via ads.txt MANAGERDOMAIN delegation. `adagents_authoritative`: manager file named this publisher through publisher_properties fan-out. `community_catalog`: moderator-approved community catalog. Null until first crawl after migration 470.
  - `manager_domain` string, nullable — The manager domain whose adagents.json was used to authorize this publisher's agents. Non-null only when `discovery_method` is `ads_txt_managerdomain`. Matches the MANAGERDOMAIN value from the publisher's ads.txt.
  - `hosting` object, required
    - `mode` 'self' | 'self_invalid' | 'aao_hosted' | 'self_redirected' | 'none', required — Where this publisher's adagents.json lives. `self` = publisher hosts a valid file at their own /.well-known. `self_invalid` = publisher's /.well-known returns a file that fails validation (fixable misconfiguration, not absence). `aao_hosted` = the publisher hosts a stub at their own /.well-known whose `authoritative_location` points at AAO's canonical document. `self_redirected` = the publisher's stub `authoritative_location` resolves to a third-party HTTPS origin (a CDN, partner CMS, or sibling host) — verifiers should audit the TLS chain at `resolved_url`, not at the publisher's own origin. `none` = no adagents.json configured yet.
    - `hosted_url` string — Canonical AAO-hosted adagents.json URL. Present iff `mode === 'aao_hosted'`. Publishers reference this URL from their own /.well-known stub via the `authoritative_location` field (see https://docs.adcontextprotocol.org/docs/governance/property/adagents).
    - `expected_url` string, required — Where adagents.json *should* live for this domain — the publisher's own /.well-known path. Always populated, regardless of `mode`.
    - `resolved_url` string, nullable — Where the canonical adagents.json document actually lives after following the publisher's `authoritative_location` stub or any HTTP-layer redirects. Populated when `mode === 'self_redirected'` (the third-party HTTPS origin verifiers should audit) and when `mode === 'aao_hosted'` AND the publisher has actively set up the redirect (`authoritative_location` in the manifest body or a network-layer redirect to AAO's hosted URL). NULL when there's no resolved-URL evidence to report.
    - `last_validated` string, nullable — ISO timestamp of the last successful validation crawl. Lets verifiers sanity-check freshness. NULL when never crawled.
    - `last_http_status` integer, nullable — HTTP status code returned by AAO's most recent fetch attempt of the publisher's `/.well-known/adagents.json`. Verifier-grade chrome — lets a buy-side scraper confirm they see the same response AAO does. NULL until the first crawl records or for transient errors that never produced an HTTP response.
    - `last_bytes` integer, nullable — Response body byte length from the most recent fetch (post-decompression). When `authoritative_location` was followed, measures the canonical document body, not the stub. NULL until the first crawl records.
    - `origin_verified_at` string, nullable — ISO timestamp of the last successful origin verification — AAO fetched the publisher's own /.well-known/adagents.json and confirmed `authoritative_location` points at our hosted URL. When set, the publisher's authorization rows have been promoted to `source='adagents_json'` (origin-attested). NULL when never verified or last attempt failed. Only populated when `mode === 'aao_hosted'`.
    - `origin_last_checked_at` string, nullable — ISO timestamp of the last verification attempt regardless of result. Lets a caller render "checked X minutes ago, not yet verified" vs "never checked." Only populated when `mode === 'aao_hosted'`.
  - `files` object — Plain-English summary of what AAO has found at the publisher's origin. The publisher page leads with this — `you have a valid adagents.json` is the primary signal, not `mode === self`. Optional in the schema for backwards compatibility; the handler always populates it.
    - `adagents_json` object, required
      - `status` 'valid' | 'community' | 'invalid' | 'unknown' | 'checking', required — What we know about the publisher's adagents.json right now. `valid` = crawler fetched a parsing-and-shape-valid file from the publisher origin. `community` = moderators approved a community adagents.json catalog for this domain. `invalid` = crawler fetched a file that failed validation. `unknown` = never crawled or last result is stale. `checking` = an auto-crawl was kicked off by this request; the page should poll for fresh data shortly.
      - `expected_url` string, required — Where adagents.json should live on the publisher's own origin.
      - `registry_url` string — Registry-served adagents.json URL when the document is community or AgenticAdvertising.org hosted rather than served by the publisher origin.
    - `brand_json` object, required
      - `status` 'present' | 'unknown' | 'checking', required — What we know about the publisher's brand.json. `present` = a brand record with manifest data exists. `unknown` = no record yet. `checking` = an auto-crawl was kicked off.
      - `name` string
  - `properties` object[], required
    - `id` string
    - `type` string
    - `name` string
    - `identifiers` PropertyIdentifier[]
      - `type` string, required
      - `value` string, required
    - `tags` string[] — Arbitrary string tags on this property. The `relationship:` prefix tag (e.g. `relationship:owned`) is deprecated in favour of the `delegation_type` field and will be removed in a future release.
    - `source` 'adagents_json' | 'community' | 'discovered' | 'brand_json' — Where this property came from. `adagents_json` comes from the publisher's own adagents.json, `community` from an approved community adagents.json catalog, `discovered` from crawler or third-party signals, and `brand_json` from the publisher's brand.json when no federated-index data exists yet.
    - `delegation_type` 'direct' | 'delegated' | 'ad_network' — Delegation relationship declared in brand.json. Populated only when `source` is `brand_json` — for `adagents_json` and `discovered` sources the authoritative value is on the matching `authorized_agents` entry. Mirrors adagents.json `delegation_type` for bilateral verification: `direct` = publisher treats this as a direct buying path, even if a third party operates the software; `delegated` = a rep firm or manager is authorized to sell on the publisher's behalf (operator-declared, unilateral until corroborated by the publisher's adagents.json); `ad_network` = sold as part of a network/exchange package. `owned` properties have no `delegation_type` — ownership is implicit and has no adagents.json counterpart.
  - `brand` object — Display-oriented brand identity summary from brand.json. The full raw document remains available from the publisher's /.well-known/brand.json or hosted registry URL.
    - `name` string — Display name from brand.json or the registered brand row.
    - `description` string — Short brand or house description when present in brand.json.
    - `logo_url` string — First usable logo URL from brand.json.
    - `colors` string[] — Representative hex colors from brand.json, capped for display.
    - `industries` string[] — Industry labels from brand.json when present.
  - `formats` object[] — Display-oriented summary of top-level adagents.json `formats[]`, normalized for publisher pages and agent discovery clients. Each entry preserves `format_kind`, `format_option_id`, and canonical params.
    - `format_option_id` string — Stable format option identifier from adagents.json `formats[]`.
    - `display_name` string, required — Human-readable format label for catalog and publisher UI display.
    - `format_kind` string, required — Canonical format discriminator, such as `image`, `video_hosted`, `native_in_feed`, or `custom`.
    - `params` object — Canonical format params from the publisher's adagents.json declaration.
    - `applies_to_property_ids` string[] — Property IDs this format applies to; absent means all properties.
    - `applies_to_property_tags` string[] — Property tags this format applies to; absent means all properties.
    - `seller_preference` string — Seller preference hint from the format declaration, when present.
    - `experimental` boolean — Whether this seller's format declaration is marked experimental.
  - `authorized_agents` object[], required
    - `url` string, required
    - `authorized_for` string
    - `source` 'adagents_json' | 'aao_hosted' | 'agent_claim', required — How strongly this authorization is attested. `adagents_json`: the publisher's origin actually serves a valid adagents.json (origin-verified). `aao_hosted`: AAO is hosting the canonical document on the publisher's behalf — represents publisher intent but origin has NOT been verified to redirect to AAO. `agent_claim`: the agent claimed it; publisher has not confirmed.
    - `properties_authorized` integer — Count of this publisher's properties the agent is authorized to sell. Absent when `rollup_truncated` is set (call `/api/registry/publisher/authorization` for the per-agent count) or when properties are entirely brand.json-hydrated (no adagents.json claim has actually been made about them).
    - `properties_total` integer — Total number of properties this publisher exposes through the registry. Same value across all agents in the response. Absent when `properties_authorized` is absent.
    - `publisher_wide` boolean — True when the agent has only a publisher-wide authorization row and `properties_authorized` was synthesized as `properties_total`. False when the agent has property-level authorization rows. Absent when the rollup is absent.
  - `rollup_truncated` object — Set when the publisher has more authorized agents than the per-agent rollup cap. Above the cap, agents beyond `cap` are returned without `properties_authorized` / `properties_total` / `publisher_wide`; call `/api/registry/publisher/authorization?domain=X&agent=Y` for the per-agent count. Lets a caller decide whether to fan out individual calls or stop reading.
    - `cap` integer, required — Maximum number of agents for which the rollup is computed in a single response.
    - `total_agents` integer, required — Total authorized-agent count for this publisher (the full population the cap was applied to).
  - `auto_crawl_triggered` boolean — Set to `true` when this request triggered a background crawl of the publisher's origin (we hadn't crawled before). The client should refetch in ~3-5s to pick up fresh data. Debounced per-domain so a tight refresh loop won't keep firing crawls.

## Other responses

- `400` — Missing domain

---

[API](https://skmtc.net/adcontextprotocol/apis/agenticadvertising-org-registry-api.md) · [All operations](https://skmtc.net/adcontextprotocol/apis/agenticadvertising-org-registry-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/adcontextprotocol/agenticadvertising-org-registry-api/revisions/9ea7fedf54c0/schema)
