> ## Documentation Index
> Fetch the complete documentation index at: https://adcp-docs-ja.pier1.co.jp/llms.txt
> Use this file to discover all available pages before exploring further.

# Registry API

> AdCP エコシステムにおけるブランド解決、プロパティルックアップ、エージェント探索、認可のためのパブリック REST API。

AgenticAdvertising.org レジストリは、AdCP エコシステムにおけるブランドとプロパティの解決、エージェントの発見、認可の検証のためのパブリック REST API を提供します。

## ベース URL

```
https://agenticadvertising.org
```

ほとんどのエンドポイントは**パブリックで認証不要**です。[認証済みエンドポイント](#authenticated-endpoints)には Bearer トークンが必要です。

完全な [OpenAPI 3.1 仕様](https://agenticadvertising.org/openapi/registry.yaml) がコード生成とツール用に利用可能です。`/.well-known/openapi.yaml` でも発見できます。

## クイックスタート

ブランドドメインを正準アイデンティティに解決します。

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://agenticadvertising.org/api/brands/resolve?domain=acmecorp.com"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://agenticadvertising.org/api/brands/resolve?domain=acmecorp.com"
  );
  const brand = await res.json();
  console.log(brand.brand_name, brand.canonical_domain);
  ```

  ```python Python theme={null}
  import requests

  brand = requests.get(
      "https://agenticadvertising.org/api/brands/resolve",
      params={"domain": "acmecorp.com"}
  ).json()
  print(brand["brand_name"], brand["canonical_domain"])
  ```
</CodeGroup>

```json Response theme={null}
{
  "canonical_id": "acmecorp.com",
  "canonical_domain": "acmecorp.com",
  "brand_name": "Acme Corp",
  "keller_type": "master",
  "house_domain": "acmecorp.com",
  "source": "brand_json"
}
```

<h2 id="rate-limits">
  レート制限
</h2>

| Endpoint                                                        | Limit                          |
| --------------------------------------------------------------- | ------------------------------ |
| 一括解決（`/api/brands/resolve/bulk`、`/api/properties/resolve/bulk`） | IP あたり 20 リクエスト/分              |
| 保存エンドポイント（`/api/brands/save`、`/api/properties/save`）            | ユーザーあたり 60 リクエスト/時             |
| クロールリクエスト（`/api/registry/crawl-request`）                        | ドメインあたり 5 分、ユーザーあたり 30 リクエスト/時 |
| その他すべてのエンドポイント                                                  | 制限なし                           |

レート制限されたエンドポイントは、制限を超えると `429 Too Many Requests` を返します。

## エンドポイントグループ

<CardGroup cols={2}>
  <Card title="Brand Resolution" icon="fingerprint" href="/docs/registry/index#brand-resolution">
    ドメインを正準ブランドアイデンティティに解決し、brand.json ファイルを取得し、ブランドレジストリを参照。
  </Card>

  <Card title="Property Resolution" icon="building" href="/docs/registry/index#property-resolution">
    パブリッシャードメインをプロパティ情報に解決し、adagents.json を検証し、プロパティを参照。
  </Card>

  <Card title="Agent Discovery" icon="robot" href="/docs/registry/index#agent-discovery">
    インベントリプロファイルでエージェントをリスト、検索、フィルタリング。パブリッシャーを参照し、レジストリ統計を表示。
  </Card>

  <Card title="Change Feed" icon="clock-rotate-left" href="/docs/registry/index#change-feed">
    ローカル同期のためにレジストリ変更のカーソルベースフィードをポーリング。
  </Card>

  <Card title="Lookups & Authorization" icon="shield-check" href="/docs/registry/index#lookups--authorization">
    ドメインでエージェントをルックアップし、プロダクト認可を検証し、プロパティ認可をリアルタイムで確認。
  </Card>
</CardGroup>

## エンティティ別ルックアップ

3 つのエンドポイントが、レジストリに誰がいるかについての異なる質問に答えます。それらは API リファレンスの 2 つのタググループにまたがるため、エンドポイント固有のパラメーターに入る前に、この表を使って正しいルックアップサーフェスを選んでください。

| Endpoint                               | Auth surface                                                                                                   | What it returns                                                                                      |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `GET /api/registry/agents`             | パブリックカタログ。認証済みの AgenticAdvertising.org API 階層メンバーは `members_only` エージェントも見られます。                                | AgenticAdvertising.org が証明したメンバー登録エージェントカタログ。ヘルス、機能、プロパティ、コンプライアンス、測定メトリクス、検証状態の任意のフィルターとエンリッチメント付き。 |
| `GET /api/registry/operator?domain=X`  | Auth 対応: 匿名の呼び出し元は `public` を、AgenticAdvertising.org API 階層メンバーは `members_only` も、プロファイル所有者は `private` も見られます。 | クエリされたエンティティが運営するエージェントと、それらのエージェントを信頼するパブリッシャー。                                                     |
| `GET /api/registry/publisher?domain=X` | パブリックで未認証。AgenticAdvertising.org メンバーシップはレスポンス形状を変えません。                                                        | クエリされたエンティティが公開するインベントリ（`properties[]`）と、それが認可するエージェント（`adagents.json` からの `authorized_agents[]`）。   |

**`GET /api/registry/agents`** — パブリックなエージェント母集団を参照またはフィルタリングしたいときに使います。エージェントがこのカタログに入る方法については [エージェントの登録](/docs/registry/registering-an-agent) を参照。リファレンス: Agent Discovery の [List agents エンドポイント](#agent-discovery)。

**`GET /api/registry/operator?domain=X`** — 1 つのエンティティを手にしていて、そのエージェントフットプリントを知りたいときに使います。

**`GET /api/registry/publisher?domain=X`** — 1 つのパブリッシャーを手にしていて、そのインベントリと委任を知りたいときに使います。

<h3 id="brand-resolution">
  ブランド解決
</h3>

これらのエンドポイントはドメインをブランドアイデンティティに解決します。レスポンスの `source` フィールドがデータの出所を示します。

| Source       | Meaning                                  |
| ------------ | ---------------------------------------- |
| `brand_json` | ドメインの `/.well-known/brand.json` ファイルから解決 |
| `enriched`   | Brandfetch API 経由でエンリッチ                  |
| `community`  | コミュニティメンバーが提出                            |

すべてのソースが同じ解決レスポンス構造を生成します。完全なブランドアイデンティティデータ（logos、colors、tone）を得るには、`/api/brands/enrich` を使うか、レジストリでブランドをルックアップします。

| Method | Path                       | Description                 |
| ------ | -------------------------- | --------------------------- |
| GET    | `/api/brands/resolve`      | ドメインを正準ブランドに解決              |
| POST   | `/api/brands/resolve/bulk` | 最大 100 ドメインを一度に解決           |
| GET    | `/api/brands/brand-json`   | ドメインの生の brand.json を取得      |
| GET    | `/api/brands/registry`     | すべてのブランドをリスト（検索、ページネーション）   |
| GET    | `/api/brands/enrich`       | Brandfetch 経由でブランドデータをエンリッチ |
| GET    | `/api/brands/history`      | ブランドの編集履歴                   |
| POST   | `/api/brands/save`         | コミュニティブランドを保存または更新（認証必須）    |

<h3 id="property-resolution">
  プロパティ解決
</h3>

| Method | Path                           | Description                |
| ------ | ------------------------------ | -------------------------- |
| GET    | `/api/properties/resolve`      | ドメインをプロパティ情報に解決            |
| POST   | `/api/properties/resolve/bulk` | 最大 100 ドメインを一度に解決          |
| GET    | `/api/properties/registry`     | すべてのプロパティをリスト（検索、ページネーション） |
| GET    | `/api/properties/validate`     | ドメインの adagents.json を検証    |
| GET    | `/api/properties/history`      | プロパティの編集履歴                 |
| POST   | `/api/properties/save`         | ホストされたプロパティを保存または更新（認証必須）  |

<h3 id="agent-discovery">
  エージェント探索
</h3>

| Method | Path                          | Description                                      |        |             |            |          |       |        |            |
| ------ | ----------------------------- | ------------------------------------------------ | ------ | ----------- | ---------- | -------- | ----- | ------ | ---------- |
| GET    | `/api/registry/agents`        | すべてのメンバー登録エージェントをリスト — タイプでフィルタリング（\`?type=brand | rights | measurement | governance | creative | sales | buying | signals\`） |
| GET    | `/api/registry/agents/search` | インベントリプロファイルでエージェントを検索（認証必須）                     |        |             |            |          |       |        |            |
| GET    | `/api/registry/publishers`    | すべてのパブリッシャーをリスト                                  |        |             |            |          |       |        |            |
| GET    | `/api/registry/stats`         | レジストリ統計                                          |        |             |            |          |       |        |            |
| POST   | `/api/registry/crawl-request` | パブリッシャードメインの再クロールをリクエスト（認証必須）                    |        |             |            |          |       |        |            |

#### 測定ベンダー探索

測定ベンダー（Adelaide スタイルの attention、Scope3 スタイルの emissions、Nielsen DAR、IAS/DV カスタム品質など）を特に発見するには、エージェントリストを `type=measurement` でフィルタリングします。

```bash theme={null}
curl "https://agenticadvertising.org/api/registry/agents?type=measurement"
```

これは、AAO メンバーによってレジストリに登録されたすべての測定エージェントを返します。

**メトリクスごとのカタログ探索。** 各測定エージェントは、その完全なメトリクスごとのカタログを [`get_adcp_capabilities.measurement.metrics[]`](/docs/protocol/get_adcp_capabilities#measurement) — 正準の、ベンダー管理の真実の源泉 — に公開します。AAO は各測定エージェントの `get_adcp_capabilities` を TTL でクロールし結果を保存します。`?capabilities=true` を渡すと、カタログが `creative_capabilities` と `signals_capabilities` の隣でレスポンスに折り込まれます。

**フィルターパラメーター**（存在するときすべて `type=measurement` を意味します。明示的な非測定タイプは 400 を返します）:

| Param                       | Match                                               | Notes                                                                                         |
| --------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `metric_id=attention_units` | `metrics[].metric_id` の完全一致                         | 繰り返し可能。パラメーター内の複数の値は OR。                                                                      |
| `accreditation=MRC`         | `metrics[].accreditations[].accrediting_body` の完全一致 | 繰り返し可能。ベンダー主張 — レスポンスの `verified_by_aao` は常に `false`。レンダラーはこれらを AAO の裏書きではなくベンダーの主張としてマークすべき。 |
| `q=attention`               | `metric_id` の大文字小文字を区別しない部分文字列                      | v1 スコープ: metric\_id のみ。最大 64 文字。SQL ワイルドカード（`%`、`_`）は拒否。説明/標準のファジー検索はフォローアップ。                 |

```bash theme={null}
# アテンション測定を提供するすべてのベンダー
curl "https://agenticadvertising.org/api/registry/agents?metric_id=attention_units&capabilities=true"

# MRC 認定のビューアビリティベンダー
curl "https://agenticadvertising.org/api/registry/agents?type=measurement&accreditation=MRC&q=viewab&capabilities=true"
```

**直接呼び出し対インデックス — どちらをいつ使うか。** バイヤーはベンダーのメトリクスカタログへの 2 つのパスを持ちます。

| Use case                                    | Path                             | Why                                                                              |
| ------------------------------------------- | -------------------------------- | -------------------------------------------------------------------------------- |
| ディスカバリー/プランニング（「どのベンダーが attention を提供するか？」） | AAO インデックス（`?metric_id=...`）     | 事前集計済み、キャッシュ済み、高速。1 回の呼び出しでクロスベンダー。AAO TTL ウィンドウ（通常 24 時間）まで古い可能性。               |
| 決済/監査（「Adelaide は現在メトリクス X をサポートするか？」）      | `get_adcp_capabilities` への直接呼び出し | ライブ、正準、古さなし。バイヤーはすでに配信/照合時に測定エージェントを呼び出している。1 回の追加呼び出しは安価で、監査証跡からインデックスの古さを除去する。 |
| `get_products` 時のフィルタリング                    | AAO インデックス                       | バイヤーは高速パスのクエリにおり、セラーのプロダクトカタログはすでにどのベンダーが有効かを知る必要がある。                            |

<h3 id="change-feed">
  Change Feed
</h3>

| Method | Path                        | Description                                           |
| ------ | --------------------------- | ----------------------------------------------------- |
| GET    | `/api/registry/feed`        | カーソルベースのレジストリ変更フィードをポーリング（認証必須）                       |
| GET    | `/api/registry/feed/stream` | カーソルベースのレジストリフィードページを Server-Sent Events でストリーム（認証必須） |

<h3 id="lookups--authorization">
  ルックアップと認可
</h3>

| Method | Path                                            | Description         |
| ------ | ----------------------------------------------- | ------------------- |
| GET    | `/api/registry/lookup/domain/{domain}`          | ドメインに認可されたエージェントを検索 |
| GET    | `/api/registry/lookup/property`                 | プロパティ識別子でエージェントを検索  |
| GET    | `/api/registry/lookup/agent/{agentUrl}/domains` | エージェントのすべてのドメインを取得  |
| POST   | `/api/registry/validate/product-authorization`  | エージェントのプロダクト認可を検証   |
| POST   | `/api/registry/expand/product-identifiers`      | プロパティセレクターを識別子に展開   |
| GET    | `/api/registry/validate/property-authorization` | リアルタイム認可チェック        |

認可検証は両側をチェックします: パブリッシャーの `adagents.json`（主張された `delegation_type` でこのエージェントを認可するか？）とオペレーターの `brand.json`（一致する `relationship` でこのプロパティを宣言するか？）。

### バリデーションツール

| Method | Path                     | Description             |
| ------ | ------------------------ | ----------------------- |
| POST   | `/api/adagents/validate` | ドメインの adagents.json を検証 |
| POST   | `/api/adagents/create`   | adagents.json コンテンツを生成  |

### 検索

| Method | Path                        | Description             |
| ------ | --------------------------- | ----------------------- |
| GET    | `/api/search`               | ブランド、パブリッシャー、プロパティを横断検索 |
| GET    | `/api/manifest-refs/lookup` | ドメインのマニフェスト参照を検索        |

### エージェントプロービング

| Method | Path                             | Description              |
| ------ | -------------------------------- | ------------------------ |
| GET    | `/api/public/discover-agent`     | エージェント URL の機能をプローブ      |
| GET    | `/api/public/agent-formats`      | エージェントからクリエイティブフォーマットを取得 |
| GET    | `/api/public/agent-products`     | セールスエージェントからプロダクトを取得     |
| GET    | `/api/public/validate-publisher` | パブリッシャードメインを検証           |

## アクティビティ履歴

`GET /api/brands/history?domain={domain}` と `GET /api/properties/history?domain={domain}` は、レジストリエントリの編集履歴を新しい順で返します。これらはパブリックエンドポイントです — 認証不要。

```json Response theme={null}
{
  "domain": "acmecorp.com",
  "total": 3,
  "revisions": [
    {
      "revision_number": 3,
      "editor_name": "Pinnacle Media",
      "edit_summary": "Updated logo URL",
      "source": "community",
      "is_rollback": false,
      "created_at": "2026-03-01T12:34:56Z"
    },
    {
      "revision_number": 2,
      "editor_name": "system",
      "edit_summary": "API: enriched via Brandfetch",
      "source": "enriched",
      "is_rollback": false,
      "created_at": "2026-02-15T08:00:00Z"
    }
  ]
}
```

`editor_name: "system"` のエントリは自動エンリッチメントによって書き込まれました。`is_rollback` が `true` のとき、`rolled_back_to` に復元されたリビジョン番号が含まれます。ページネーションは `limit`（最大 100）と `offset` クエリパラメーターを使います。

## 不正防止とアンチホモグラフ制御

`/api/brands/save`、`/api/properties/save`、および `adagents` 検証エンドポイントは、認証済みメンバー組織からドメイン文字列を受け入れるため、ホストされたレジストリは保存時に多層の不正防止制御の下限を適用します。これらは 3.x 時代の AgenticAdvertising.org レジストリの運用挙動であり — 新しいワイヤサーフェスではありません — タイポスクワット、混同可能なそっくりさん、通りすがりのブランドハイジャックが、単一の認証済み呼び出し元によってインデックスに書き込まれないように存在します。

* **ドメイン正規化（IDNA 2008 + 混同可能検出）。** 保存エンドポイントは、永続化前に国際化ドメイン名を ASCII に正規化するために IDNA 2008 を適用すべきで（SHOULD）、次に 2 つのコーパス — (1) インデックス内のすでに登録されたエントリ、(2) レジストリオペレーターが維持する厳選された高価値ブランドの拒否リスト — に対して Unicode 混同可能検出（例: ICU `uspoof` または同等物）を実行すべきです（SHOULD）。拒否リストは、有名ブランドが自身で登録される前に、それらのタイポスクワットを捕捉します（例: `g00gle.com` の提出は、Google がまだインデックス行を主張していなくても拒否リストのエントリと衝突します）。曖昧な提出 — 混合スクリプトラベル、ホモグラフ衝突、許可されない Unicode クラス — は、黙ってコミットするのではなく、拒否または人間のレビューのためにフラグを立てるべきです（SHOULD）。
* **コミット前の所有権証明。** 保存エンドポイントは、**新しい**ブランドまたはプロパティエントリがインデックスにコミットされる前にドメイン管理の証拠を要求しなければなりません（MUST）— これがこの制御を動機付ける脅威です。侵害されたメンバー API キーを持つ攻撃者は、そうでなければ衝突する以前のエントリを持たない新鮮な混同可能バリアントを自由に一括登録できるからです。同じ認証済み組織による既存のコミュニティソースエントリへの**リビジョン**については、再証明はローリングベースで要求されるべきですが（SHOULD。例: 以前の証明が 90 日より古くなったら）、そのウィンドウ内ではスキップしてもかまいません（MAY）。受け入れられる証明は、サーバー発行の nonce に一致する `_adcp-owner.{domain}` の DNS TXT レコード、またはドメイン上の `/.well-known/adcp-ownership.txt` にホストされた HTTP チャレンジのいずれかです。nonce は単一使用で、`(organization, domain)` ペアにスコープされ、発行から **15 分**以内に期限切れになければなりません（MUST）。検証は成功時に nonce を消費し、失敗時に無効化しなければなりません（MUST）。期限切れ後のリークまたは未使用の nonce は死んでいます。既存の**権威ある**エントリ（すなわち `brand.json` / `adagents.json` に裏付けられたもの）へのリビジョンは、[Save brand](#save-brand) と [Save property](#save-property) の 409 Conflict セマンティクスに従い続けます。所有権証明はコミュニティソースの保存パスをカバーします。
* **保存に対する組織ごとのレート制限。** [レート制限](#rate-limits)に文書化された IP ごとのレート制限に加えて、保存エンドポイントは、単一の侵害された API キーが混同可能バリアントを一括登録できないよう、組織ごとの制限を適用すべきです（SHOULD）。ホストされた実装はバースト許容の上限を使います（目安: 組織あたり数十保存/時、組織あたり数百/日）。組織ごとのバケットを超える呼び出し元は `429 Too Many Requests` を受け取ります。

これらの制御はホストされた AgenticAdvertising.org レジストリによって強制されます。[Change Feed](#change-feed) を消費するセルフホストミラーは、ホストされたレジストリの保存時チェックに依存し、それらを再実行しません — これはフィードのアドバイザリアイデンティティの姿勢（`specs/registry-change-feed.md` §Advisory identity material を参照）と一貫しています: フィードは変更検出であり信頼アンカーではなく、パブリッシャー自身の `adagents.json` ピンが権威あるアイデンティティソースのままです（[`adagents.json` §`signing_keys`](/docs/governance/property/adagents#signing_keys) を参照）。代替レジストリ実装を運営するオペレーターは、コミュニティソースの書き込みを受け入れる前に同等の保存時制御を適用すべきです（SHOULD）。

## 認証

パブリックエンドポイント（解決、探索、検索）は認証不要です。書き込みエンドポイントは、**組織 API キー**（サーバー間）または OAuth 2.1 経由で取得した**ユーザー JWT**（インタラクティブ/エージェントクライアント）のいずれかを受け入れます。両方とも `Authorization: Bearer ...` ヘッダーで送信されます。

### Option A: 組織 API キー

長寿命、組織スコープ。ユーザーが存在しないサーバー間統合に最適。

1. [agenticadvertising.org/dashboard/api-keys](https://agenticadvertising.org/dashboard/api-keys) でサインイン
2. **Create key** をクリックし、生成されたキーをコピー

`Authorization` ヘッダーでキーを渡します。

```
Authorization: Bearer sk_...
```

### Option B: OAuth 2.1 経由のユーザー SSO

短寿命、ユーザースコープ。人間が AAO にサインインするエージェントクライアント（MCP、AI アシスタント、カスタムアプリ）に最適。単一のトークンが `/mcp` と REST API の両方に対して機能します。

ディスカバリーは [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) と [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) に従います。

* 認可サーバーメタデータ: `GET /.well-known/oauth-authorization-server`
* 保護リソースメタデータ（REST API）: `GET /.well-known/oauth-protected-resource/api`
* 保護リソースメタデータ（MCP）: `GET /.well-known/oauth-protected-resource/mcp`

フローは PKCE 付き認可コードです。動的クライアント登録（[RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591)）が `/register` で利用可能です。ユーザーは AuthKit 経由で認証します。トークンは WorkOS 署名の JWT です。

```
Authorization: Bearer <jwt>
```

有効なユーザー JWT はアイデンティティを証明し、エンタイトルメントは証明しません。組織メンバーシップまたは管理者ロールでゲートされたエンドポイント（ほとんどの書き込みエンドポイント）は、認証済みユーザーが必要な立場を欠く場合、依然として `403` を返します。

<h3 id="authenticated-endpoints">
  認証済みエンドポイント
</h3>

これらのエンドポイントには有効な API キーが必要です。

<h4 id="save-brand">
  Save brand
</h4>

`POST /api/brands/save`

レジストリでコミュニティブランドを保存または更新します。既存のブランドについては、リビジョン追跡された編集を作成します。`brand.json` 経由で管理される権威あるブランドは編集できません — それらは `409 Conflict` を返します。

**リクエストボディ:**

```json theme={null}
{
  "domain": "acmecorp.com",
  "brand_name": "Acme Corp",
  "brand_manifest": {
    "name": "Acme Corp",
    "description": "A fictional company",
    "logos": [{ "url": "https://acmecorp.com/logo.svg", "tags": ["icon"] }],
    "colors": [{ "hex": "#FF5733", "type": "accent" }]
  }
}
```

`domain` と `brand_name` は必須です。`brand_manifest`（ブランドアイデンティティデータ）は任意です。ブランドの `source` はサーバーによって `"community"` に設定されます。ドメインは正規化されます（プロトコル除去、小文字化）。

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://agenticadvertising.org/api/brands/save" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"domain":"acmecorp.com","brand_name":"Acme Corp"}'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://agenticadvertising.org/api/brands/save",
    {
      method: "POST",
      headers: {
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        domain: "acmecorp.com",
        brand_name: "Acme Corp",
      }),
    }
  );
  const result = await res.json();
  ```

  ```python Python theme={null}
  import requests

  result = requests.post(
      "https://agenticadvertising.org/api/brands/save",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={"domain": "acmecorp.com", "brand_name": "Acme Corp"},
  ).json()
  ```
</CodeGroup>

```json Response (create) theme={null}
{
  "success": true,
  "message": "Brand \"Acme Corp\" saved to registry",
  "domain": "acmecorp.com",
  "id": "br_abc123"
}
```

```json Response (update) theme={null}
{
  "success": true,
  "message": "Brand \"Acme Corp\" updated in registry (revision 2)",
  "domain": "acmecorp.com",
  "id": "br_abc123",
  "revision_number": 2
}
```

<h4 id="save-property">
  Save property
</h4>

`POST /api/properties/save`

レジストリでホストされたプロパティを保存または更新します。既存のプロパティについては、リビジョン追跡された編集を作成します。`adagents.json` 経由で管理される権威あるプロパティは編集できません — それらは `409 Conflict` を返します。

これはアイデンティティのみの書き込みサーフェスです: 保存されるドキュメントは常に `authorized_agents: []` を運びます。セールス認可はパブリッシャー自身のオリジン `adagents.json` にのみ存在します — コミュニティレジストリはそれを作成も運搬もできません — したがってリクエストボディで送られる任意の `authorized_agents` は無視されます。

**リクエストボディ:**

```json theme={null}
{
  "publisher_domain": "examplepub.com",
  "properties": [
    { "type": "website", "name": "Example Publisher" }
  ],
  "contact": {
    "name": "Ad Ops",
    "email": "adops@examplepub.com"
  }
}
```

`publisher_domain` は必須です。`properties`（それぞれ `type` と `name` を要求）と `contact` は任意です。ドメインは正規化されます（プロトコル除去、小文字化）。

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://agenticadvertising.org/api/properties/save" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "publisher_domain": "examplepub.com",
      "properties": [{"type": "website", "name": "Example Publisher"}]
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://agenticadvertising.org/api/properties/save",
    {
      method: "POST",
      headers: {
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        publisher_domain: "examplepub.com",
        properties: [{ type: "website", name: "Example Publisher" }],
      }),
    }
  );
  const result = await res.json();
  ```

  ```python Python theme={null}
  import requests

  result = requests.post(
      "https://agenticadvertising.org/api/properties/save",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={
          "publisher_domain": "examplepub.com",
          "properties": [{"type": "website", "name": "Example Publisher"}],
      },
  ).json()
  ```
</CodeGroup>

```json Response (create) theme={null}
{
  "success": true,
  "message": "Hosted property created for examplepub.com",
  "id": "prop_xyz789"
}
```

```json Response (update) theme={null}
{
  "success": true,
  "message": "Property 'examplepub.com' updated (revision 2)",
  "id": "prop_xyz789",
  "revision_number": 2
}
```

#### Change feed

`GET /api/registry/feed`

レジストリ変更のカーソルベースフィードをポーリングします。これを使って、完全なデータセットを再取得せずにレジストリのローカルコピーを同期に保ちます。イベントは UUID v7 の `event_id` で順序付けられ、単調なカーソル進行を提供します。フィードはイベントを 90 日間保持します — 期限切れのカーソルは `410 Gone` を返します。各レスポンスには、コンシューマーが要求したタイプフィルターのフィードラグを測定できるよう `freshness` メタデータが含まれます。

**スキーマ:** [`core/registry-feed-response.json`](https://adcontextprotocol.org/schemas/v3/core/registry-feed-response.json) が [`core/registry-event.json`](https://adcontextprotocol.org/schemas/v3/core/registry-event.json) アイテムをラップします。

**クエリパラメーター:**

| Parameter | Type   | Default | Description                                        |
| --------- | ------ | ------- | -------------------------------------------------- |
| `cursor`  | UUID   | —       | このイベント ID の後から再開。最も早く利用可能なイベントには省略。                |
| `types`   | string | —       | カンマ区切りのイベントタイプフィルター。グロブパターンをサポート（例: `property.*`）。 |
| `limit`   | number | 100     | ページあたりの最大イベント数（1〜10,000）。                          |

**イベントタイプ:**

| Type                            | Description                                                                                      |
| ------------------------------- | ------------------------------------------------------------------------------------------------ |
| `property.created`              | 新しいプロパティがレジストリに追加された                                                                             |
| `property.updated`              | プロパティメタデータが変更された                                                                                 |
| `property.merged`               | 2 つのプロパティレコードがマージされた                                                                             |
| `property.stale`                | プロパティが再クロール検証に失敗した                                                                               |
| `property.reactivated`          | 古いプロパティが再クロールに合格した                                                                               |
| `collection.created`            | 新しいパブリッシャーコレクションがレジストリに追加された                                                                     |
| `collection.updated`            | コレクションメタデータまたは配信識別子が変更された                                                                        |
| `collection.merged`             | 2 つのコレクションレコードがマージされた                                                                            |
| `collection.removed`            | コレクションがパブリッシャーの権威あるカタログでもはや見えない                                                                  |
| `agent.discovered`              | 新しい `agent_url` がパブリッシャーの `adagents.json` に現れた（認可グラフ。エージェントが `/api/registry/agents` にあることを意味しない） |
| `agent.removed`                 | エージェントがレジストリから削除された                                                                              |
| `agent.profile_updated`         | エージェントのインベントリプロファイルが変更された                                                                        |
| `agent.compliance_changed`      | エージェントのコンプライアンスまたは検証状態が変更された                                                                     |
| `agent.verification_earned`     | エージェントが AAO Verified バッジを獲得した                                                                    |
| `agent.verification_lost`       | エージェントが AAO Verified バッジを失った                                                                     |
| `publisher.adagents_discovered` | パブリッシャーの adagents.json が発見されレジストリに投影された                                                          |
| `publisher.adagents_changed`    | パブリッシャーの adagents.json が更新された                                                                    |
| `authorization.granted`         | エージェントがプロパティに認可された                                                                               |
| `authorization.revoked`         | 認可が削除された                                                                                         |
| `authorization.modified`        | 認可は見えるままだが、外部から見えるメタデータが変更された                                                                    |

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://agenticadvertising.org/api/registry/feed?types=property.*&limit=50" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://agenticadvertising.org/api/registry/feed?types=property.*&limit=50",
    { headers: { Authorization: "Bearer YOUR_API_KEY" } }
  );
  const feed = await res.json();
  // Store feed.cursor for next poll
  ```

  ```python Python theme={null}
  import requests

  feed = requests.get(
      "https://agenticadvertising.org/api/registry/feed",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      params={"types": "property.*", "limit": 50},
  ).json()
  # Store feed["cursor"] for next poll
  ```
</CodeGroup>

```json Response theme={null}
{
  "events": [
    {
      "event_id": "019539a0-1234-7000-8000-000000000001",
      "event_type": "property.created",
      "entity_type": "property",
      "entity_id": "019539a0-b1c2-7000-8000-000000000002",
      "payload": {
        "property_rid": "019539a0-b1c2-7000-8000-000000000002",
        "classification": "property",
        "source": "contributed",
        "identifiers": [
          { "type": "domain", "value": "streamer.example.com" }
        ]
      },
      "actor": "crawler",
      "created_at": "2026-03-31T10:00:00.000Z"
    }
  ],
  "cursor": "019539a0-1234-7000-8000-000000000001",
  "has_more": true,
  "freshness": {
    "generated_at": "2026-03-31T10:00:15.000Z",
    "latest_event_created_at": "2026-03-31T10:00:00.000Z",
    "lag_seconds": 15,
    "retention_days": 90
  }
}
```

`has_more` が `true` のとき、返された `cursor` 値を次のリクエストで渡してポーリングを続けます。`false` のとき、現在のフィードの終わりに達しています — 後で同じカーソルで再度ポーリングして新しいイベントを取得します。

`latest_event_created_at` は、現在フィードに見える最新の一致イベントです。`lag_seconds` は `generated_at` に対して計算されます。自身のミラー鮮度目標に応じてアラートを設定します。

`GET /api/registry/feed/stream` は、同じフィードページを Server-Sent Events で提供します。切断後は最後に永続化したカーソルで再接続します。ストリームは上記と同じ JSON 形状で `event: feed` を、追いついている間 `event: heartbeat` を発します。カーソルは同じ論理 `types` サブスクリプションに結び付けられます。カーソルを再利用しながらフィルターを変更すると、以前フィルターされたイベントをスキップする可能性があります。ストリームは再開カーソルを SSE `id` ではなく JSON `data.cursor` で運ぶため、ブラウザ `EventSource` クライアントは `?cursor=...` で再接続しなければなりません。

カーソルが期限切れ（90 日より古いか見つからない）の場合、レスポンスは `410 Gone` です。

```json 410 Gone theme={null}
{
  "error": "cursor_expired",
  "message": "Cursor is older than 90-day retention window. Re-bootstrap from /registry/agents/search, /catalog, and /catalog/collections/sync."
}
```

#### Agent search

`GET /api/registry/agents/search`

インベントリプロファイル — チャネル、市場、コンテンツカテゴリ、プロパティタイプなど — でエージェントを検索します。フィルターは次元間で AND、次元内で OR を使います。結果は、フィルターマッチの幅、インベントリの深さ、TMP サポートに基づく関連性スコアでランク付けされます。

**クエリパラメーター:**

| Parameter        | Type    | Default | Description                                 |
| ---------------- | ------- | ------- | ------------------------------------------- |
| `channels`       | CSV     | —       | チャネルでフィルタリング（例: `ctv,olv,display`）          |
| `property_types` | CSV     | —       | プロパティタイプでフィルタリング（例: `ctv_app,website`）      |
| `markets`        | CSV     | —       | 市場/国コードでフィルタリング（例: `US,GB`）                 |
| `categories`     | CSV     | —       | IAB コンテンツカテゴリでフィルタリング（例: `IAB-7,IAB-7-1`）   |
| `tags`           | CSV     | —       | タグでフィルタリング（例: `premium,brand_safe`）         |
| `delivery_types` | CSV     | —       | 配信タイプでフィルタリング（例: `guaranteed,programmatic`） |
| `has_tmp`        | boolean | —       | TMP サポートを要求（`true` または `false`）             |
| `min_properties` | number  | —       | インベントリ内の最小プロパティ数                            |
| `cursor`         | string  | —       | 前のレスポンスからのページネーションカーソル                      |
| `limit`          | number  | 50      | ページあたりの最大結果数（1〜200）                         |

各 CSV パラメーターは最大 100 値を受け入れます。

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://agenticadvertising.org/api/registry/agents/search?channels=ctv,olv&markets=US&has_tmp=true" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://agenticadvertising.org/api/registry/agents/search?channels=ctv,olv&markets=US&has_tmp=true",
    { headers: { Authorization: "Bearer YOUR_API_KEY" } }
  );
  const agents = await res.json();
  ```

  ```python Python theme={null}
  import requests

  agents = requests.get(
      "https://agenticadvertising.org/api/registry/agents/search",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      params={"channels": "ctv,olv", "markets": "US", "has_tmp": "true"},
  ).json()
  ```
</CodeGroup>

```json Response theme={null}
{
  "results": [
    {
      "agent_url": "https://ads.streamhaus.example.com",
      "channels": ["ctv", "olv"],
      "property_types": ["ctv_app", "website"],
      "markets": ["US", "GB", "CA"],
      "categories": ["IAB-7", "IAB-7-1"],
      "tags": ["premium"],
      "delivery_types": ["guaranteed"],
      "format_ids": [],
      "property_count": 42,
      "publisher_count": 3,
      "has_tmp": true,
      "category_taxonomy": null,
      "relevance_score": 0.92,
      "matched_filters": ["channels", "markets"],
      "updated_at": "2026-03-31T10:00:00.000Z"
    }
  ],
  "cursor": "MC45Mjpodh...",
  "has_more": false
}
```

`matched_filters` 配列は、どのフィルター次元が一致したかを示し、結果が返された理由を理解するのに役立ちます。`relevance_score` は、フィルターマッチの幅、0.1 で重み付けされた `ln(property_count + 1)`、TMP サポートの 0.05 のブーストを組み合わせます。

#### Crawl request

`POST /api/registry/crawl-request`

パブリッシャードメインの即時再クロールをリクエストします。`adagents.json` ファイルを更新した後にこれを使うと、次のスケジュールされたクロールを待たずにレジストリが変更を取得します。クロールは非同期で実行されます — エンドポイントは直ちに `202 Accepted` を返します。

ドメインあたり 5 分ごとに 1 リクエスト、ユーザーあたり 1 時間に 30 リクエストにレート制限されます。

**リクエストボディ:**

```json theme={null}
{
  "domain": "examplepub.com"
}
```

`domain` は必須です。ドメインは正規化されます（小文字化、トリム）。エンドポイントはドメイン形式を検証し、DNS ルックアップを実行してプライベート/予約済み IP アドレスを拒否します。

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://agenticadvertising.org/api/registry/crawl-request" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"domain":"examplepub.com"}'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://agenticadvertising.org/api/registry/crawl-request",
    {
      method: "POST",
      headers: {
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ domain: "examplepub.com" }),
    }
  );
  const result = await res.json(); // 202
  ```

  ```python Python theme={null}
  import requests

  result = requests.post(
      "https://agenticadvertising.org/api/registry/crawl-request",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={"domain": "examplepub.com"},
  ).json()
  ```
</CodeGroup>

```json 202 Accepted theme={null}
{
  "message": "Crawl request accepted",
  "domain": "examplepub.com"
}
```

```json 429 Too Many Requests theme={null}
{
  "error": "Rate limit exceeded for this domain",
  "retry_after": 245
}
```

`retry_after` は再試行前に待つ秒数です。

#### Submit brand (legacy)

`POST /api/brands/discovered/community`

レビュー用にブランドを提出します。このエンドポイントは `/api/brands/save` より前からあります — 新しい統合には save エンドポイントを推奨します。

### エラーレスポンス

| Status | Description                                                   |
| ------ | ------------------------------------------------------------- |
| 400    | 必須フィールドの欠如または無効なドメイン                                          |
| 401    | API キーの欠如または無効                                                |
| 409    | 権威あるブランド/プロパティを編集できない（`brand.json` または `adagents.json` 経由で管理） |
| 410    | カーソル期限切れ（Change Feed — 90 日保持ウィンドウより古い）                       |
| 429    | レート制限超過                                                       |

## プロトコル対 REST API

AdCP プロトコルは、エージェント間通信のための MCP と A2A のタスク（例: `get_products`、`create_media_buy`）を定義します。レジストリ REST API は別物です — AgenticAdvertising.org レジストリでエンティティをルックアップするための HTTP エンドポイントを提供します。

**REST API を使う**のはディスカバリーと認可のためです。

* プロトコル呼び出しを行う前にブランドまたはプロパティドメインを解決する
* どのエージェントが存在し、何に認可されているかを発見する
* アドサービング中にリアルタイムで認可を検証する
* レジストリを参照または検索する統合を構築する

**MCP/A2A タスクを使う**のはトランザクショナルな操作のためです。

* セールスエージェントからプロダクトを取得（`get_products`）
* メディアバイの作成（`create_media_buy`）
* クリエイティブの構築（`build_creative`）
* シグナルの取得（`get_signals`）

典型的な統合は両方を使います: レジストリ API 経由でパブリッシャードメインを解決し、次に認可されたエージェントの MCP エンドポイントを呼び出してトランザクションします。
