> ## 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.

# get_signals

> get_signals はオーディエンスシグナルとコンテキストシグナルを発見するための AdCP タスクです。自然言語またはシグナル参照で検索し、プラットフォームや CPM でフィルタリングし、アクティベーションキー付きのリアルタイムなデプロイステータスを取得します。

**タスク**: 説明に基づいてシグナルを発見し、それらがどこにデプロイされているかの詳細を返します。

**応答時間**: 約 60 秒（バックエンドシステムとの推論/RAG）

**リクエストスキーマ**: [`https://adcontextprotocol.org/schemas/v3/signals/get-signals-request.json`](https://adcontextprotocol.org/schemas/v3/signals/get-signals-request.json)
**レスポンススキーマ**: [`https://adcontextprotocol.org/schemas/v3/signals/get-signals-response.json`](https://adcontextprotocol.org/schemas/v3/signals/get-signals-response.json)

`get_signals` タスクは、シグナルメタデータとプラットフォーム横断のリアルタイムなデプロイステータスの両方を返します。これによりエージェントは可用性を把握し、アクティベーションプロセスを案内できます。

## リクエストパラメーター

| Parameter                   | Type                                                                            | Required          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| --------------------------- | ------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `discovery_mode`            | string                                                                          | No（v3.1+ では含めるべき） | `"brief"`（デフォルト）または `"wholesale"`。`"brief"`: 従来の挙動 — `signal_spec`、`signal_refs`、または非推奨の `signal_ids` が必須で、エージェントが推論/RAG を実行します。`"wholesale"`: 生のホールセールシグナルフィードの列挙 — `signal_spec`、`signal_refs`、`signal_ids` は指定してはなりません（MUST NOT）。エージェントは、存在する場合は `filters` / `account` / `destinations` / `countries` でスコープされ、ページネーションされた完全な価格付きシグナルフィードを返します。**タイミングセマンティクス:** `"wholesale"` はホールセールシグナルフィードの読み取りであり、エージェントは同期的に応答すべきで（SHOULD）、非同期/Submitted 経路を通してはなりません（MUST NOT）。部分的完了は [`incomplete[]`](#incomplete-配列) を使います。`discovery_mode` を持たない v3.1 より前のクライアントからのリクエストを受けたエージェントは `"brief"` をデフォルトにしなければなりません（MUST）。サポートの探索は [`get_adcp_capabilities`](/docs/protocol/get_adcp_capabilities)（`signals.discovery_modes`）経由。                                                                          |
| `signal_spec`               | string                                                                          | Conditional       | 望むシグナルの自然言語による説明。`discovery_mode` が `"brief"` で `signal_refs` とレガシーの `signal_ids` の両方が欠けている場合に必須。`discovery_mode` が `"wholesale"` の場合は指定してはなりません（MUST NOT）。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `signal_refs`               | SignalRef\[]                                                                    | Conditional       | 参照で特定のシグナルを検索します。`discovery_mode` が `"brief"` で `signal_spec` が欠けている場合に必須。`discovery_mode` が `"wholesale"` の場合は指定してはなりません（MUST NOT）。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `signal_ids`                | SignalID\[]                                                                     | Conditional       | **非推奨。** 代わりに `signal_refs` を使います。旧クライアント向けのレガシーな特定シグナル検索。`discovery_mode` が `"wholesale"` の場合は指定してはなりません（MUST NOT）。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `account`                   | [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No                | このリクエストのアカウント。指定された場合、シグナルエージェントは設定されていればアカウント別の料金オプションを返します。ホールセールモードではこれがレートカードのスコープになります。省略された場合、エージェントはデフォルトのレートカード価格を返すか、`pricing_options` を完全に省略します。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `destinations`              | Destination\[]                                                                  | No                | 特定のエージェント/プラットフォームで有効化可能なシグナルに絞り込みます。省略された場合、現在のエージェントで利用可能なすべてのシグナルを返します。下記 Destination Object を参照。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `countries`                 | string\[]                                                                       | No                | シグナルが使われる国（ISO 3166-1 alpha-2 コード）                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `filters`                   | Filters                                                                         | No                | 結果を絞り込むフィルター（下記 Filters Object を参照）。ホールセールモードでは、フィルターは列挙されるシグナルフィードを制約します（例: `filters.data_providers: ["acme-data"]` はそのプロバイダーのシグナルのみを返します）。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `fields`                    | string\[]                                                                       | No                | レスポンスに含める特定のシグナルフィールド。`get_products.fields` と整合します。必須の識別・有効化フィールドは、レスポンススキーマが要求する場合は常に含まれます。`taxonomy`、`data_sources`、`methodology`、`segmentation_criteria`、`criteria_url`、`onboarder`、`modeling`、`countries`、`consent_basis`、`restricted_attributes`、`policy_categories`、`art9_basis`、`data_subject_rights` などのリッチな定義メタデータのプログレッシブディスクロージャーに使います。エージェントは、厳密な検索、絞り込み、小規模なカスタムシグナル結果セット、および利用可能な場合はプライベート/ソースネイティブなシグナルについて、要求されたフィールドを尊重すべきです（SHOULD）。`fields` は投影リクエストであり、権限付与ではありません。呼び出し元が基礎となるリネージ、方法論、権利ルーティングメタデータへのアクセスを認可されていない限り、エージェントは要求された定義フィールドを編集（リダクト）してもかまいません（MAY）。別のプロバイダーのシグナルについて `consent_basis` や `art9_basis` が投影される場合、その値はプロバイダーが宣言したシグナル定義の姿勢のままです。セラーや連携エージェントが自身の処理根拠で置き換えてはなりません（MUST NOT）。広範なディスカバリーやホールセールページは、プロバイダーが公開した定義や開示 URL へのコンパクトなポインターを返してもかまいません（MAY）。 |
| `if_wholesale_feed_version` | string                                                                          | No                | 以前の `get_signals` レスポンスから得た不透明な `wholesale_feed_version` トークン。指定された場合、エージェントは呼び出し元の `cache_scope` に対する現在のホールセールシグナルフィードバージョンと比較し、何も変わっていなければ `unchanged: true`（`signals` は省略）を返してもかまいません（MAY）。[ホールセールフィードバージョニング](#ホールセールフィードバージョニング) と [キャッシュレイヤリング](#キャッシュレイヤリング) を参照。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `if_pricing_version`        | string                                                                          | No                | 以前のレスポンスから得た不透明な `pricing_version` トークン。`if_wholesale_feed_version` と共にのみ送信しなければなりません（MUST）。評価順序: `if_wholesale_feed_version` 不一致 → 完全ペイロード。`if_wholesale_feed_version` は一致するが `if_pricing_version` が不一致 → 完全ペイロード（呼び出し元が更新された `pricing_options` を確認できるように）。両方一致 → エージェントは `unchanged: true` を返してもかまいません（MAY）。価格を別途追跡しないエージェントはこれを無視します。                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `max_results`               | number                                                                          | No                | **非推奨。** 代わりに `pagination.max_results` を使います。両方が存在する場合は `pagination.max_results` が優先されます。AdCP 4.0 で削除予定。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `pagination`                | object                                                                          | No                | ページネーションエンベロープ。`pagination.max_results`（最大: 100、デフォルト: 50）がページサイズを制御し、`pagination.cursor`（前回レスポンスからの不透明トークン）がページを進めます。ホールセールでは必須（シグナルフィードは大きい場合があるため）。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `push_notification_config`  | PushNotificationConfig                                                          | No                | `brief` のセマンティックディスカバリーにおける非同期の終端完了/失敗通知用の任意の Webhook チャネル。`task_id` を持つ `submitted` レスポンスは、このフィールドの有無にかかわらず `get_task_status`（レガシー `tasks/get`）でポーリング可能です。リクエストがこのフィールドを含み、エージェントが `submitted` を返す場合、エージェントは少なくとも終端の完了/失敗通知を設定された Webhook に配信しなければなりません（MUST）。中間の進捗通知は任意（MAY）。Webhook チャネルを尊重できない場合、エージェントは黙って受け入れるのではなく、構造化エラーでリクエストを拒否しなければなりません（MUST）。`wholesale` では無視されます。このフィールドが存在するからといって、エージェントはホールセール読み取りを Submitted 経路に通してはなりません（MUST NOT）。                                                                                                                                                                                                                                                                                                                                            |

<Note>
  `discovery_mode: "wholesale"` は AdCP 3.1+ のディスカバリー形状です。呼び出し元が
  3.1+ のシグナルサーフェスやホールセールサポートを前提にできない場合、クライアントは
  ホールセールリクエストを発行する前に、まず [`get_adcp_capabilities`](/docs/protocol/get_adcp_capabilities)
  を呼び出し、`signals.discovery_modes` に `"wholesale"` が含まれることを確認すべきです。
  フィールドが無いか `"brief"` のみを列挙している場合は、エージェントを brief 専用として扱い、
  `signal_spec`、`signal_refs`、または非推奨の `signal_ids` を使います。
</Note>

### 非同期ディスカバリー

`discovery_mode: "brief"` は、セマンティックディスカバリーが遅いプロバイダークエリや、初期レスポンス前に完了できないレビューに依存する場合、`submitted` を返してもかまいません（MAY）。`task_id` を用いた `get_task_status`（レガシー `tasks/get`）のポーリングは常に有効です。`push_notification_config` が存在し、エージェントが `submitted` を返す場合、エージェントは少なくとも終端の完了/失敗通知をその Webhook にも送信します。中間の進捗通知は任意です。`discovery_mode: "wholesale"` は同期的なフィード読み取りのままで、部分的完了は `submitted` ではなく `incomplete[]` で報告します。

### Destination オブジェクト

各デプロイ先は `type` フィールドでプラットフォームベースかエージェントベースかを区別します。

| Parameter   | Type         | Required      | Description                                                          |
| ----------- | ------------ | ------------- | -------------------------------------------------------------------- |
| `type`      | string       | Yes           | 識別子。DSP なら "platform"、営業エージェントなら "agent"                             |
| `platform`  | string       | Conditional\* | プラットフォーム ID（例: 'the-trade-desk', 'amazon-dsp'）。type="platform" の場合必須 |
| `agent_url` | string (URI) | Conditional\* | 営業エージェントを識別する URL。type="agent" の場合必須                                 |
| `account`   | string       | No            | プラットフォーム/エージェント上のアカウント ID                                            |

\*`platform` は type="platform" の場合必須、`agent_url` は type="agent" の場合必須。

**デスティネーションフィルタリング**: シグナルは、要求されたデスティネーションの*いずれか*で利用可能であれば返されます（OR セマンティクス）。シグナルが利用できないデスティネーションは、そのシグナルのレスポンス `deployments` 配列から省略されます。一部のデスティネーションがシグナルをサポートしない場合、`PARTIAL_COVERAGE` 警告が含まれることがあります。

**アクティベーションキー**: 認証済みの呼び出し元がリクエスト中のいずれかのデスティネーションにアクセス権を持つ場合、シグナルエージェントはそれらのデプロイメント（`is_live: true` のとき）についてレスポンスに `activation_key` フィールドを含めます。

**権限モデル**: シグナルエージェントは、呼び出し元の認証・認可に基づいてキーの付与を決定します。例:

* 営業エージェントは自分の `agent_url` に一致するデプロイメントのキーを受け取ります
* 複数 DSP プラットフォームへの認証情報を持つバイヤーは、それらすべてのデプロイメントのキーを受け取ります
* アクセス可否は、リクエスト中のフラグではなく、シグナルエージェントの権限システムで決定されます

### Filters オブジェクト

| Parameter                 | Type      | Required | Description                                                                                      |
| ------------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------ |
| `catalog_types`           | string\[] | No       | カタログタイプでフィルタリング（"marketplace"、"custom"、"owned"）                                                  |
| `data_providers`          | string\[] | No       | 特定のデータプロバイダーでフィルタリング                                                                             |
| `max_cpm`                 | number    | No       | 最大 CPM 価格フィルター。すべての CPM ベースの料金オプションがこの値を超えるシグナルを除外します。CPM ベースの料金オプションを持たないシグナルはこのフィルターの影響を受けません。 |
| `min_coverage_percentage` | number    | No       | 最小カバレッジ要件                                                                                        |

<Note>
  `catalog_types`、非推奨の `catalog_signals` 機能フラグ、非推奨の
  `signal_id.source: "catalog"` 値はレガシーなワイヤ用語です。新しい文章では、これらを
  adagents.json の `signals[]` におけるプロバイダー公開のシグナル定義として読み替えてください。
  既存の 3.x エージェントは互換性のためこれらを受け付け／送出し続けてもかまいませんが、
  新しい呼び出し元は `signal_ref` を使うべきで（SHOULD）、Signals プロトコルを使う前に
  `signals.features.catalog_signals` を必須としてはなりません（MUST NOT）。
</Note>

## レスポンス構造

すべての AdCP レスポンスは次を含みます。

* **message**: 操作結果の人間可読な要約
* **context\_id**: フォローアップリクエスト用のセッション継続識別子
* **data**: タスク固有のペイロード（下記 Response Data 参照）

レスポンス構造はプロトコル間で同一で、トランスポートラッパーのみ異なります。

* **MCP**: 完全なレスポンスを平坦な JSON として返却
* **A2A**: アーティファクトとして返却（text パートに message、data パートにデータ）

## Response Data

```json theme={null}
{
  "signals": [
    {
      "signal_ref": {
        "scope": "data_provider",
        "data_provider_domain": "string",
        "signal_id": "string"
      },
      "signal_agent_segment_id": "string",
      "name": "string",
      "description": "string",
      "signal_type": "string",
      "data_provider": "string",
      "coverage_percentage": "number (optional, deprecated)",
      "coverage_forecast": {
        "method": "estimate",
        "forecast_range_unit": "availability",
        "scope": {
          "kind": "inventory",
          "label": "network price-priority inventory"
        },
        "bucket_semantics": "exclusive",
        "bucket_completeness": "partial",
        "points": [
          {
            "label": "not present",
            "dimensions": [
              {
                "kind": "signal",
                "signal_ref": {
                  "scope": "data_provider",
                  "data_provider_domain": "weather-data.example",
                  "signal_id": "weather"
                },
                "signal_value": null,
                "presence": "absent"
              }
            ],
            "metrics": {
              "impressions": { "mid": 280000 },
              "coverage_rate": { "mid": 0.28 }
            }
          },
          {
            "label": "hot",
            "dimensions": [
              {
                "kind": "signal",
                "signal_ref": {
                  "scope": "data_provider",
                  "data_provider_domain": "weather-data.example",
                  "signal_id": "weather"
                },
                "signal_value": "hot",
                "presence": "present"
              }
            ],
            "metrics": {
              "impressions": { "mid": 180000 },
              "coverage_rate": { "mid": 0.18 }
            }
          }
        ]
      },
      "deployments": [
        {
          "type": "agent",
          "agent_url": "string",
          "account": "string",
          "is_live": "boolean",
          "activation_key": {
            "type": "segment_id",
            "segment_id": "string"
          },
          "estimated_activation_duration_minutes": "number"
        }
      ],
      "pricing_options": [
        {
          "pricing_option_id": "string",
          "model": "cpm | percent_of_media | flat_fee | per_unit | custom",
          "...": "..."
        }
      ]
    }
  ]
}
```

<Note>
  `get_signals` はディスカバリーと可用性のサーフェスであり、正規のシグナル定義から
  すべてのフィールドをインライン化することを要求するものではありません。広範な検索結果や
  ホールセールフィードのページでは、シグナルエージェントは各リスティングをコンパクトに保ち、
  安定した参照と、大きな定義リソース向けのキャッシュ可能な開示ポインターを使うべきです（SHOULD）。
  バイヤーは `signal_ref` からプロバイダー公開の定義を参照解決できます。プロバイダーの
  `/.well-known/adagents.json` を取得し（存在する場合は `authoritative_location` に従う）、
  一致する `signals[].id` を選択します。取得した `adagents.json` ドキュメントは、解決された
  authoritative URL に加え、`catalog_etag`、HTTP `ETag` / `Last-Modified`、または上限付き TTL で
  キャッシュし、そのキャッシュされたドキュメント内で `signal_ref.signal_id` を解決します。
  `taxonomy.etag` は、独自の鮮度バリデーターを持つタクソノミードキュメントについてのみ使います。
  これらは既存のプロバイダーファイルおよびタクソノミーのバリデーターを再利用します。`get_signals`
  は別個のシグナル定義バリデーターを定義せず、クライアントはシグナル定義キャッシュを
  バリデーターのみでキー付けしてはなりません。
</Note>

### 定義フィールドのインクルージョン

同じ呼び出しでよりリッチなレビューコンテキストが必要なバイヤーは `fields` を設定できます。これは
別個の検索タスクを導入するのではなく、`get_products.fields` と同じレスポンス投影パターンを使います。

必須の識別・有効化フィールドは、レスポンススキーマが要求する場合は常に含まれます。追加の値は、
`taxonomy`、`data_sources`、`methodology`、`segmentation_criteria`、`criteria_url`、
`refresh_cadence`、`lookback_window`、`onboarder`、`modeling`、`audience_expansion`、
`device_expansion`、`countries`、`consent_basis`、`restricted_attributes`、`policy_categories`、
`art9_basis`、`data_subject_rights` などの、任意のリスティングフィールドやリッチな定義メタデータを
インラインで要求します。

別のプロバイダーのシグナルについて `consent_basis` や `art9_basis` が投影される場合、その値は
プロバイダーが宣言したシグナル定義の姿勢のままです。セラーや連携エージェントが、プロバイダー宣言の
根拠を自身の処理根拠で置き換えてはなりません（MUST NOT）。

エージェントは、フィールドが利用可能なとき、厳密な検索、絞り込み、小規模なカスタムシグナル結果
セットについて、要求されたフィールドを尊重すべきです（SHOULD）。広範なディスカバリーやホールセール
ページでは、要求されたフィールドをインライン化するとページが大きくなりすぎる場合、エージェントは
プロバイダー公開の定義、タクソノミードキュメント、基準ページ、開示 URL へのポインターを含む
コンパクトなリスティングを返してもかまいません（MAY）。これにより、静的シグナルは `adagents.json`
を通じてキャッシュ可能なまま、カスタムや brief 固有のシグナルは有用な場合により深いインライン
コンテキストを返せます。

### フィールド説明

* **signals**: 一致するシグナルの配列
  * **signal\_ref**: 正規のシグナル参照。adagents.json の `signals[]` を通じて解決されるシグナルには `scope: "data_provider"` を、adagents.json の `signals[]` に公開されていないソースネイティブなシグナルには `scope: "signal_source"` を、プロダクトコンテキストのレスポンスでのみ `scope: "product"` を使います。新しいレスポンスはこのフィールドを含めるべきです（SHOULD）。
  * **signal\_id**: 非推奨のレガシー SignalId オブジェクト。新しいクライアントは `signal_ref` を読むべきです。移行期間中、古いレスポンスは `signal_id` のみを含むことがあります。
  * **signal\_agent\_segment\_id**: このシグナルソースが発行する不透明なシグナルハンドル。`activate_signal` にはそのまま使い、グローバルに移植可能なシグナル ID として扱わないでください。パッケージレベルの `signal_targeting_groups` では、`signal_ref` が購入時のアイデンティティであり、このハンドルは選択したプロダクトオプションが別個の実行ハンドルとして公開する場合にのみエコーされます。
  * **name**: 人間可読なシグナル名
  * **description**: 詳細なシグナル説明
  * **signal\_type**: シグナルのタイプ。次のいずれか:
    * `marketplace` — 再販されるサードパーティセグメント（プロバイダーの `adagents.json` でプロバイダー認可を検証可能）
    * `owned` — シグナルソースが直接所有するデータから導出されるファーストパーティセグメント
    * `custom` — モデル、コンポジット、バイヤー入力からオンデマンドで構築されるソースネイティブなセグメント（既存の上流プロバイダーに帰属しない）
  * **data\_provider**: 該当する場合の人間可読なソース名。`scope: "data_provider"` のシグナルではこれがデータプロバイダーです。`scope: "signal_source"` のシグナルではシグナルソースや独自の出所を示すことがあります。
  * **coverage\_percentage**: 任意の非推奨レガシースカラー。オーディエンスカバレッジのパーセンテージ。`coverage_forecast` を消費しないクライアントのフォールバックとしてのみ使います。**coverage\_forecast** が存在する場合、シグナルレベルのディスカバリーでは `coverage_forecast` が正規であり、このスカラーはフォールバック専用です。`coverage_forecast` が同じ分母で absent バケットを含む場合、`coverage_percentage` は `100 * (1 - absent coverage_rate.mid)` に整合すべきです。
  * **coverage\_forecast**: シグナルの、任意のフォーキャスト形状の可用性ガイダンス。`scope` が分母を宣言し、`bucket_semantics` が返される値バケットが `exclusive` か `overlapping` かを宣言し、`bucket_completeness` が返されるバケットが完全な分母分割か部分的ヒストグラムかを宣言します。各ポイントは、正規の `signal_ref` を持つ `kind: "signal"` ディメンション、任意の存在値には `presence: "present"`、特定の値バケットには `presence: "present"` に加えて `signal_value`、非存在バケットには `presence: "absent"` に加えて `signal_value: null` を使えます。`metrics.coverage_rate` は宣言されたスコープの 0.0〜1.0 の割合です。
  * **deployments**: デスティネーションデプロイメントの配列
    * **agent\_url**: デスティネーションエージェントを識別する URL
    * **account**: 該当する場合のアカウント ID
    * **is\_live**: このデプロイメントでシグナルが現在アクティブかどうか
    * **activation\_key**: ターゲティングに使うキー（下記 Activation Key 参照）。**`is_live=true` かつ認証済みの呼び出し元がこのデプロイメントにアクセスできる場合にのみ含まれます。**
    * **estimated\_activation\_duration\_minutes**: ライブでない場合の有効化所要時間
  * **pricing\_options**: 増分価格を持つシグナルの料金オプションの配列。選択した `pricing_option_id` を `report_usage` またはパッケージレベルの `signal_targeting_groups` に渡して課金検証に使います。価格が呼び出し元に利用できない、デスティネーションプロダクトにバンドルされている、または増分コストがない場合は省略されます。
    * **pricing\_option\_id**: この料金オプションの一意識別子
    * **model**: 課金モデル — `cpm`、`percent_of_media`、`flat_fee`、`per_unit`、または `custom`
    * `model: "cpm"` — `cpm`（数値、インプレッション 1000 回あたりのコスト）、`currency`（ISO 4217）
    * `model: "percent_of_media"` — `percent`（0〜100）、`currency`（ISO 4217）、`max_cpm`（任意の CPM 上限: 実効課金 = `min(percent × media_spend_per_mille, max_cpm)`）
    * `model: "flat_fee"` — `amount`（固定料金）、`currency`（ISO 4217）、`period`（`monthly`、`quarterly`、`annual`、または `campaign`）
    * `model: "per_unit"` — `unit`（何をカウントするか）、`unit_price`（1 単位あたりのコスト）、`currency`（ISO 4217）
    * `model: "custom"` — `description`（人間可読）、`metadata`（構造化パラメーター）、`currency`（任意）。パフォーマンスキッカー、段階的ボリューム、ハイブリッド式、または標準モデルで表現できない任意の構成のためのエスケープハッチ。バイヤーはコミットメント前にカスタム価格をオペレーターレビューに通すべきです（SHOULD）。

課金モデルに合った料金オプションを選択します。直接のシグナル有効化では、その `pricing_option_id` を `report_usage` に渡して課金検証に使います。メディアプロダクトで選択されるセラー提供シグナルでは、パッケージレベルの `targeting_overlay.signal_targeting_groups.groups[].signals[].pricing_option_id` に渡します。シグナルが複数のモデル（例: CPM とフラットフィー）を提供する場合、予想される配信ボリュームとキャンペーン構造に基づいて選びます。

### レスポンスメタデータ

| Field                    | Type               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `wholesale_feed_version` | string             | このレスポンスの構成に使われたホールセールシグナルフィード状態のバージョンを表す不透明トークン。不透明として扱います — フォーマットなし、順序なし、検査なし。条件付きフェッチを実装するエージェントはすべてのレスポンスで返します。[ホールセールフィードバージョニング](#ホールセールフィードバージョニング) を参照。                                                                                                                                                                                                                                                                                |
| `pricing_version`        | string             | 任意のより細粒度のトークン。`wholesale_feed_version` が構造/メタデータについてのみ変わるのに対し、価格が動くと変わります。これらを分離しないエージェントは `pricing_version` を省略してもかまいません（MAY）。                                                                                                                                                                                                                                                                                                                |
| `cache_scope`            | string             | `"public"` または `"account"`。**すべてのレスポンスで必須**（スキーマで強制 — 2 層キャッシュの安全性はこれに依存します）。リクエストに `account` がなかった場合は `"public"` でなければなりません（MUST）。リクエストに `account` があった場合、エージェントは `"public"`（アカウント価格がレートカードと同じ — 呼び出し元が重複排除）または `"account"`（アカウント固有のオーバーライド）のいずれかを宣言します。[キャッシュレイヤリング](#キャッシュレイヤリング) を参照。                                                                                                                                                      |
| `unchanged`              | boolean            | リクエストが呼び出し元の `cache_scope` に対するエージェントの現在のバージョンに一致する `if_wholesale_feed_version`（および／または `if_pricing_version`）を運んだ場合にのみ、存在して `true` になります。その場合 `signals[]` は省略しなければならず（MUST）、`wholesale_feed_version`、`cache_scope`、（使用時は）`pricing_version` は依然としてエコーしなければなりません（MUST）。エージェントは `unchanged: false` を送出してはなりません（MUST NOT）— フィールドの不在が「レスポンスがシグナルを運ぶ」というシグナルです（状態ごとに 1 つの形状）。`unchanged: true` を受け取った呼び出し元は、ローカルのホールセールシグナルミラーを変更してはなりません（MUST NOT）。 |
| `incomplete`             | IncompleteEntry\[] | 呼び出し元の `time_budget` 内、または内部制限のために完了できなかったものを宣言します。[incomplete 配列](#incomplete-配列) を参照。                                                                                                                                                                                                                                                                                                                                                        |
| `pagination`             | PaginationResponse | `has_more`、`cursor`、任意の `total_count`。ホールセールモードでは必須。                                                                                                                                                                                                                                                                                                                                                                                           |

### Activation Key オブジェクト

アクティベーションキーは、デスティネーションターゲットでのシグナルの使い方を表します。セグメント ID かキー/バリューのいずれかです。

**セグメント ID 形式:**

```json theme={null}
{
  "type": "segment_id",
  "segment_id": "ttd_segment_12345"
}
```

**キー/バリュー形式:**

```json theme={null}
{
  "type": "key_value",
  "key": "audience_segment",
  "value": "luxury_auto_intenders"
}
```

## プロトコル別の例

AdCP のペイロードはプロトコル間で同一で、リクエスト/レスポンスのラッパーのみ異なります。

### MCP リクエスト - 営業エージェントがシグナルを問い合わせる

営業エージェントがシグナルを問い合わせます。認証済みの呼び出し元が wonderstruck.salesagents.com であるため、シグナルエージェントはレスポンスにアクティベーションキーを含めます。

```json theme={null}
{
  "tool": "get_signals",
  "arguments": {
    "signal_spec": "High-income households interested in luxury goods",
    "destinations": [
      {
        "type": "agent",
        "agent_url": "https://wonderstruck.salesagents.com"
      }
    ],
    "countries": ["US"],
    "filters": {
      "max_cpm": 5.0,
      "catalog_types": ["marketplace"]
    },
    "pagination": {
      "max_results": 5
    }
  }
}
```

### MCP レスポンス - Activation Key 付き

認証済みの呼び出し元がデプロイメントターゲットに一致するため、レスポンスにアクティベーションキーが含まれます。

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "message": "Found 1 luxury segment matching your criteria. Already activated for your sales agent.",
  "context_id": "ctx-signals-123",
  "cache_scope": "public",
  "wholesale_feed_version": "sig_v2026-05-18T08:00:00Z-public-rev12",
  "signals": [
    {
      "signal_ref": {
        "scope": "data_provider",
        "data_provider_domain": "pinnacle-data.example",
        "signal_id": "luxury_auto_intenders"
      },
      "signal_agent_segment_id": "luxury_auto_intenders",
      "name": "Luxury Automotive Intenders",
      "description": "High-income individuals researching luxury vehicles",
      "signal_type": "marketplace",
      "data_provider": "Pinnacle Data",
      "coverage_forecast": {
        "method": "estimate",
        "forecast_range_unit": "availability",
        "scope": {
          "kind": "inventory",
          "label": "eligible destination inventory"
        },
        "bucket_semantics": "exclusive",
        "bucket_completeness": "partial",
        "points": [
          {
            "label": "present",
            "dimensions": [
              {
                "kind": "signal",
                "signal_ref": {
                  "scope": "data_provider",
                  "data_provider_domain": "pinnacle-data.example",
                  "signal_id": "luxury_auto_intenders"
                },
                "presence": "present"
              }
            ],
            "metrics": {
              "coverage_rate": { "mid": 0.12 }
            }
          }
        ]
      },
      "deployments": [
        {
          "type": "agent",
          "agent_url": "https://wonderstruck.salesagents.com",
          "is_live": true,
          "activation_key": {
            "type": "key_value",
            "key": "audience_segment",
            "value": "luxury_auto_intenders_v2"
          }
        }
      ],
      "pricing_options": [
        {
          "pricing_option_id": "po_cpm_usd",
          "model": "cpm",
          "cpm": 3.50,
          "currency": "USD"
        }
      ]
    }
  ]
}
```

### MCP レスポンス - 複数の料金オプション

一部のシグナルは複数の課金モデルを提供します。バイヤーは 1 つを選択し、直接のシグナル利用では `report_usage` に、シグナルがメディアバイで選択される場合はパッケージレベルの `signal_targeting_groups` に、その `pricing_option_id` を渡します。

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "message": "Found 1 segment matching your criteria. Three pricing options are available: CPM at $3.50, 15% of media spend, or $5,000/month flat fee.",
  "context_id": "ctx-signals-456",
  "cache_scope": "public",
  "wholesale_feed_version": "sig_v2026-05-18T08:00:00Z-public-rev12",
  "signals": [
    {
      "signal_ref": {
        "scope": "data_provider",
        "data_provider_domain": "acmedata.com",
        "signal_id": "eco_conscious_shoppers"
      },
      "signal_agent_segment_id": "eco_conscious_shoppers",
      "name": "Eco-Conscious Shoppers",
      "description": "Users with demonstrated interest in sustainable and eco-friendly products",
      "signal_type": "marketplace",
      "data_provider": "Acme Data",
      "coverage_percentage": 18,
      "deployments": [
        {
          "type": "agent",
          "agent_url": "https://wonderstruck.salesagents.com",
          "is_live": true,
          "activation_key": {
            "type": "segment_id",
            "segment_id": "eco_seg_789"
          }
        }
      ],
      "pricing_options": [
        {
          "pricing_option_id": "po_eco_cpm",
          "model": "cpm",
          "cpm": 3.50,
          "currency": "USD"
        },
        {
          "pricing_option_id": "po_eco_pom",
          "model": "percent_of_media",
          "percent": 15,
          "max_cpm": 1.50,
          "currency": "USD"
        },
        {
          "pricing_option_id": "po_eco_flat",
          "model": "flat_fee",
          "amount": 5000,
          "period": "monthly",
          "currency": "USD"
        }
      ]
    }
  ]
}
```

### MCP リクエスト - バイヤーが複数 DSP を確認

バイヤーが複数の DSP プラットフォームで可用性を確認します。

```json theme={null}
{
  "tool": "get_signals",
  "arguments": {
    "signal_spec": "High-income households interested in luxury goods",
    "destinations": [
      {
        "type": "platform",
        "platform": "the-trade-desk",
        "account": "agency-123"
      },
      {
        "type": "platform",
        "platform": "amazon-dsp"
      }
    ],
    "countries": ["US"],
    "filters": {
      "max_cpm": 5.0,
      "catalog_types": ["marketplace"]
    },
    "pagination": {
      "max_results": 5
    }
  }
}
```

### MCP レスポンス - マルチプラットフォームアクセスを持つバイヤー

The Trade Desk と Amazon DSP の両方の認証情報を持つバイヤーは、両プラットフォームのキーを受け取ります。

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "message": "Found 1 luxury segment matching your criteria. Already activated on The Trade Desk, pending activation on Amazon DSP.",
  "context_id": "ctx-signals-123",
  "cache_scope": "public",
  "wholesale_feed_version": "sig_v2026-05-18T08:00:00Z-public-rev12",
  "signals": [
    {
      "signal_ref": {
        "scope": "data_provider",
        "data_provider_domain": "experian.com",
        "signal_id": "luxury_auto_intenders"
      },
      "signal_agent_segment_id": "luxury_auto_intenders",
      "name": "Luxury Automotive Intenders",
      "description": "High-income individuals researching luxury vehicles",
      "signal_type": "marketplace",
      "data_provider": "Experian",
      "coverage_percentage": 12,
      "deployments": [
        {
          "type": "platform",
          "platform": "the-trade-desk",
          "account": "agency-123",
          "is_live": true,
          "activation_key": {
            "type": "segment_id",
            "segment_id": "ttd_agency123_exp_lux_auto"
          }
        },
        {
          "type": "platform",
          "platform": "amazon-dsp",
          "is_live": false,
          "estimated_activation_duration_minutes": 60
        }
      ],
      "pricing_options": [
        {
          "pricing_option_id": "po_cpm_usd",
          "model": "cpm",
          "cpm": 3.50,
          "currency": "USD"
        }
      ]
    }
  ]
}
```

### A2A リクエスト

#### 自然言語での呼び出し

```javascript theme={null}
await a2a.send({
  message: {
    parts: [{
      kind: "text",
      text: "Find me signals for high-income households interested in luxury goods that can be deployed on The Trade Desk and Amazon DSP in the US, with a maximum CPM of $5.00."
    }]
  }
});
```

#### 明示的なスキル呼び出し

```javascript theme={null}
await a2a.send({
  message: {
    parts: [{
      kind: "data",
      data: {
        skill: "get_signals",
        parameters: {
          signal_spec: "High-income households interested in luxury goods",
          destinations: [
            {
              type: "agent",
              agent_url: "https://thetradedesk.com",
              account: "agency-123"
            },
            {
              type: "agent",
              agent_url: "https://advertising.amazon.com/dsp"
            }
          ],
          countries: ["US"],
          filters: {
            max_cpm: 5.0,
            catalog_types: ["marketplace"]
          },
          pagination: {
            max_results: 5
          }
        }
      }
    }]
  }
});
```

### A2A レスポンス

A2A は同じデータ構造でアーティファクトとして結果を返します。

```json theme={null}
{
  "artifacts": [{
      "artifactId": "artifact-signal-discovery-def456",
      "name": "signal_discovery_result",
      "parts": [
        {
          "kind": "text",
          "text": "Found 1 luxury segment matching your criteria. Available on The Trade Desk, pending activation on Amazon DSP."
        },
        {
          "kind": "data",
          "data": {
            "context_id": "ctx-signals-123",
            "signals": [
              {
                "signal_ref": {
                  "scope": "data_provider",
                  "data_provider_domain": "experian.com",
                  "signal_id": "luxury_auto_intenders"
                },
                "signal_agent_segment_id": "luxury_auto_intenders",
                "name": "Luxury Automotive Intenders",
                "description": "High-income individuals researching luxury vehicles",
                "signal_type": "marketplace",
                "data_provider": "Experian",
                "coverage_percentage": 12,
                "deployments": [
                  {
                    "type": "agent",
                    "agent_url": "https://thetradedesk.com",
                    "account": "agency-123",
                    "is_live": true
                  },
                  {
                    "type": "agent",
                    "agent_url": "https://advertising.amazon.com/dsp",
                    "is_live": false,
                    "estimated_activation_duration_minutes": 60
                  }
                ],
                "pricing_options": [
                  {
                    "pricing_option_id": "po_cpm_usd",
                    "model": "cpm",
                    "cpm": 3.50,
                    "currency": "USD"
                  }
                ]
              }
            ]
          }
        }
      ]
    }]
}
```

### プロトコルトランスポート

* **MCP**: 引数を伴う直接のツール呼び出し。完全なレスポンスを平坦な JSON として返却
* **A2A**: 入力を伴うスキル呼び出し。message とデータを分離した構造化アーティファクトを返却
* **データの一貫性**: 両プロトコルとも同一の AdCP データ構造とバージョン情報を含みます

## シナリオ

### すべてのプラットフォームを探索

プラットフォーム横断で利用可能なすべてのデプロイメントを発見します。

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-request.json",
  "signal_spec": "Contextual segments for luxury automotive content",
  "destinations": [
    { "type": "platform", "platform": "index-exchange", "account": "agency-123-ix" },
    { "type": "platform", "platform": "openx" },
    { "type": "platform", "platform": "pubmatic", "account": "brand-456-pm" }
  ],
  "countries": ["US"],
  "filters": {
    "data_providers": ["Peer39"],
    "catalog_types": ["marketplace"]
  }
}
```

### レスポンス

**Message**: "Found luxury automotive contextual segment from Peer39 with 15% coverage. Live on Index Exchange and OpenX, pending activation on Pubmatic."

**ペイロード**:

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "cache_scope": "public",
  "wholesale_feed_version": "sig_v2026-05-18T08:00:00Z-public-rev12",
  "signals": [{
    "signal_ref": {
      "scope": "data_provider",
      "data_provider_domain": "peer39.com",
      "signal_id": "peer39_luxury_auto"
    },
    "signal_agent_segment_id": "peer39_luxury_auto",
    "name": "Luxury Automotive Context",
    "description": "Pages with luxury automotive content and high viewability",
    "signal_type": "marketplace",
    "data_provider": "Peer39",
    "coverage_percentage": 15,
    "deployments": [
      {
        "type": "platform",
        "platform": "index-exchange",
        "account": "agency-123-ix",
        "is_live": true,
        "activation_key": {
          "type": "segment_id",
          "segment_id": "ix_agency123_peer39_lux_auto"
        }
      },
      {
        "type": "platform",
        "platform": "index-exchange",
        "is_live": true,
        "activation_key": {
          "type": "segment_id",
          "segment_id": "ix_peer39_luxury_auto_gen"
        }
      },
      {
        "type": "platform",
        "platform": "openx",
        "is_live": true,
        "activation_key": {
          "type": "segment_id",
          "segment_id": "ox_peer39_lux_auto_456"
        }
      },
      {
        "type": "platform",
        "platform": "pubmatic",
        "account": "brand-456-pm",
        "is_live": false,
        "estimated_activation_duration_minutes": 60
      }
    ],
    "pricing_options": [
      {
        "pricing_option_id": "po_cpm_usd",
        "model": "cpm",
        "cpm": 2.50,
        "currency": "USD"
      }
    ]
  }]
}
```

### レスポンスフィールド

* **context\_id** (string): セッション永続化用のコンテキスト識別子
* **signals** (array): 一致するシグナルの配列
  * **signal\_agent\_segment\_id** (string): このシグナルソースが発行する不透明なシグナルハンドル。`activate_signal` にはそのまま使い、グローバルに移植可能なシグナル ID として扱わないでください。メディアバイのシグナルグループでは、`signal_ref` が購入時のアイデンティティであり、このハンドルは選択したプロダクトオプションが別個の実行ハンドルとして公開する場合にのみエコーされます。
  * **name** (string): 人間可読なシグナル名
  * **description** (string): 詳細なシグナル説明
  * **signal\_type** (string): `marketplace`（再販サードパーティ）、`owned`（シグナルソースのファーストパーティデータ）、または `custom`（オンデマンド構築のソースネイティブセグメント）
  * **data\_provider** (string, optional): 該当する場合の人間可読なソース/プロバイダー名
  * **coverage\_percentage** (number, optional, deprecated): レガシースカラーの推定リーチパーセンテージ。`coverage_forecast` が無いかクライアントがサポートしない場合のフォールバックとしてのみ使います。
  * **coverage\_forecast** (object, optional): 明示的な分母と可用性ポイントを持つフォーキャスト形状のカバレッジ内訳。「任意の存在値」の集約バケットには `presence: "present"` と `signal_value` の省略を使い、行が特定の値のためのものである場合にのみ `signal_value` を追加します。返されるバケットが重複しない場合は `bucket_semantics: "exclusive"` を、複数値シグナルにより返されるレートの合計が 1.0 を超えうる場合は `"overlapping"` を使います。返されるバケットが宣言された分母をカバーする場合にのみ `bucket_completeness: "complete"` を使い、そうでなければ `"partial"` を使います。バイヤーは省略されたシェアを、未開示・その他・非サポートのバケットとして扱わなければなりません。

`coverage_forecast` をシグナルファーストのディスカバリーの正規フィールドとして使います:「このシグナルまたはその値はどれだけのインベントリを持つか?」。`kind: "signal"` ディメンションを持つプロダクトまたはプロポーザルのフォーキャストは、プロダクト固有のプランニングの正規サーフェスとして使います:「このシグナルはこのプロダクトのベースライン可用性をどう制約するか?」。バケット固有のフィルタリングは現状クライアント側であり、`min_coverage_percentage` のようなリクエストフィルターは依然としてレガシースカラーを使います。

* **deployments** (array): プラットフォーム固有のデプロイメント情報
  * **platform** (string): ターゲットプラットフォーム名
  * **account** (string, nullable): アカウント固有の場合の特定アカウント
  * **is\_live** (boolean): シグナルが現在アクティブかどうか
  * **activation\_key** (object): ターゲティングに使うキー。`is_live=true` かつ呼び出し元がアクセスできる場合にのみ含まれます。上記 Activation Key オブジェクトを参照。
  * **estimated\_activation\_duration\_minutes** (number, optional): ライブでない場合の有効化所要時間
* **pricing\_options** (array): 増分価格を持つシグナルの利用可能な料金オプションの配列。1 つを選択し、その `pricing_option_id` を `report_usage` またはパッケージレベルの `signal_targeting_groups` に渡します。
  * **pricing\_option\_id** (string): この料金オプションの一意識別子
  * **model** (string): 課金モデル — `cpm`、`percent_of_media`、`flat_fee`、`per_unit`、または `custom`

## エラーコード

### ディスカバリーエラー

* `REFERENCE_NOT_FOUND`: 参照された `signal_agent_segment_id` が存在しないか、
  プライベートなシグナルエージェントがこのアカウントから見えません。リソースが存在するが
  未認可であっても、真に存在しなくても、同じコードが返されます — セラーは両者を区別しては
  なりません（MUST NOT。どの型付きパラメーターの解決に失敗したかは `error.field` を参照）。
  error-handling.mdx の uniform-response の MUST を参照。
* `AGENT_ACCESS_DENIED`: 認証済みエージェントの認証情報がこのシグナルエージェントへのアクセスを認可しませんでした

### ディスカバリー警告

* `PRICING_UNAVAILABLE`: 1 つ以上のプラットフォームで価格データが一時的に利用不可
* `PARTIAL_COVERAGE`: 一部の要求されたプラットフォームがこのシグナルタイプをサポートしません
* `STALE_DATA`: プロバイダーのリフレッシュ遅延により一部のシグナルメタデータが古い可能性があります

## 利用上の注意

1. **認証ベースのキー**: アクティベーションキーは、認証済みの呼び出し元がいずれかのデプロイメントターゲットに一致する場合にのみ返されます
2. **権限セキュリティ**: シグナルエージェントは、リクエストフラグではなく呼び出し元の識別に基づいてキーの付与を決定します
3. **デプロイメントステータス**: `is_live` を確認して有効化が必要かを判断します
4. **複数デプロイメント**: 複数のデプロイメントターゲットを問い合わせてプラットフォーム横断の可用性を確認します
5. **有効化が必要な場合**: `is_live` が false の場合は `activate_signal` タスクを使います
6. **message フィールド**: 最も関連性の高い発見の簡潔な要約を提供します

## メディアプロダクト上のセラー提供シグナル

ターゲティングシグナルを所有または適用する認可を持つ営業エージェントは、`get_products` を通じて購入時のプロダクト適格性を公開します。バイヤーがパッケージ選択前にディスカバリーや有効化を必要とする場合、`get_signals` を通じてより広範なクロスプロダクトのシグナルフィードを公開することもできます。

* `get_products` は、プロダクトがパッケージレベルのシグナルターゲティングを持つかを宣言します。`products[].included_signals` は、プロダクトにすでにバンドルまたは計画された選択不可のシグナルを記述します。インラインの `products[].signal_targeting_options` は、プロダクト固有のメニュー、価格、有効化ハンドル、デフォルト、グルーピングヒント、または brief/refine で選択されたサブセットを運べます。ホールセールプロダクトはインラインオプションを省略し、`get_signals` を選択可能なシグナルフィードとして使えます。
* `get_signals` は任意で、`signal_ref`、`signal_agent_segment_id`、値メタデータ、および任意のデフォルトまたはアカウントスコープの `pricing_options` を含むクロスプロダクトのシグナルメタデータを返します。
* `create_media_buy` は、`packages[].targeting_overlay.signal_targeting_groups` でパッケージのシグナルを選択し、選択したシグナルの `pricing_option_id`、`signal_ref`、および必要な場合は別個のセラー実行ハンドルを運びます。

これにより、プロダクトが大きなホールセールシグナルフィードを複製することを強いずに、バイヤーにプロダクトファーストの購入時適格性パスを与えます。存在する場合は選択したプロダクトのインライン `signal_targeting_options` を、`signal_targeting_rules` を使ってそのパッケージで何が適用可能かを判断します。プロダクトがインラインオプションを省略するがシグナルターゲティングを許可する場合、候補ディスカバリーと有効化メタデータには `get_signals` を使い、次に `get_products.filters.signal_targeting` またはプロダクト固有の `get_products` クエリを使って、`create_media_buy` を呼ぶ前に、意図したプロダクトについて候補セットが選択可能で共同構成可能であることを確認します。両サーフェスが価格を含む場合、そのプロダクトについてはプロダクトスコープの `signal_targeting_options[].pricing_options` の価格が正規です。両サーフェスで公開されるプロダクトローカルなシグナルについては、プロダクトオプションの `signal_ref.signal_id` が、同じシグナルについてセラーの `get_signals.signals[].signal_ref.signal_id` と一致しなければなりません（MUST）。`included_signals` は説明のためだけのもので、シグナルを選択可能にはしません。

メディアバイのプロダクトターゲティングでは、プロダクトオプションとパッケージグループは同じ `signal_ref` アイデンティティを使います。プロダクトローカルなシグナルオプションには `scope: "product"`、公開された adagents.json の `signals[]` で定義されるシグナルには `data_provider_domain` を伴う `scope: "data_provider"`、adagents.json の `signals[]` に公開されないソースネイティブなカスタムシグナルには `scope: "signal_source"` を使います。プロバイダー公開のシグナルが選択される場合、バイヤーは、シグナル ID またはタグについてプロバイダーの `adagents.json` の `authorized_agents` ルールを確認することで、セラーの認可を検証できます。古い Signals プロトコルの `signal_id.source` 形状は非推奨で、後方互換性のためにのみ保持されます。

## ホールセールシグナルフィード

コンシューマー（ストアフロント、連携マーケットプレイス、レジストリ）がシグナルエージェントの完全な価格付きシグナルフィードをミラーする必要がある場合、`discovery_mode: "wholesale"` を設定し、`signal_spec` / `signal_refs` / 非推奨の `signal_ids` を省略します。呼び出し元が 3.1+ のシグナルサーフェスやホールセールサポートを前提にできない場合、まず `get_adcp_capabilities.signals.discovery_modes` に `"wholesale"` があるか確認します。ホールセール列挙は [`get_products` の `buying_mode: "wholesale"`](/docs/media-buy/task-reference/get_products) と対称です。同期的、ページネーションあり、確定価格で、部分的完了は `incomplete[]` で宣言されます。

### リクエスト

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-request.json",
  "discovery_mode": "wholesale",
  "account": { "account_id": "acct_123" },
  "filters": {
    "catalog_types": ["marketplace", "owned"],
    "data_providers": ["acme-data", "nova-insights"]
  },
  "pagination": { "max_results": 50 }
}
```

### レスポンス

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "message": "Returning 50 of 312 signals in wholesale mode.",
  "context_id": "ctx-wholesale-001",
  "cache_scope": "public",
  "wholesale_feed_version": "v2026-05-18T08:00:00Z-acme-rev412",
  "signals": [
    {
      "signal_ref": { "scope": "data_provider", "data_provider_domain": "acme-data.com", "signal_id": "luxury_auto_intenders" },
      "signal_agent_segment_id": "sigagent_seg_4421",
      "name": "Luxury Auto Intenders",
      "description": "Households researching premium vehicles in the last 30 days.",
      "signal_type": "marketplace",
      "data_provider": "Acme Data",
      "coverage_percentage": 18.4,
      "deployments": [
        { "type": "platform", "platform": "the-trade-desk", "is_live": true,
          "activation_key": { "type": "segment_id", "segment_id": "ttd_seg_99821" } }
      ],
      "pricing_options": [
        { "pricing_option_id": "po_cpm_1", "model": "cpm", "cpm": 2.50, "currency": "USD" }
      ]
    }
  ],
  "pagination": { "has_more": true, "cursor": "eyJvIjo1MH0=", "total_count": 312 }
}
```

### 認可と来歴

マーケットプレイスシグナル（`signal_type: "marketplace"`）は、上流のデータプロバイダーに帰属し続けます。ホールセール列挙は来歴を潰しません。

* 各マーケットプレイスシグナルは `data_provider` を運びます。
* コンシューマーは、プロバイダーの `adagents.json` を通じてプロバイダー認可を検証すべきです（SHOULD）— そのシグナルクラスについて、シグナルエージェントの URL がプロバイダーの認可リストに現れなければなりません。
* ストアフロントやレジストリは、ホールセール列挙に加えて `adagents.json` の相互参照を使い、データパブリッシャーのシグナルビューを実体化してもかまいません（MAY）: 既知の各データプロバイダーについて、認可されたシグナルエージェント経由で利用可能なシグナルの集合を価格付きで。

### 価格

エージェントが宣言すべき確定したスタンドアロンシグナル価格を持つ場合、認証済みの呼び出し元について `pricing_options[]` を投入しなければなりません（MUST）。`account` が省略された場合、エージェントはデフォルトのレートカード価格を返すか、`pricing_options[]` を省略します（その場合、呼び出し元は構成前に `account` で再クエリするか、`get_products` のプロダクトスコープ価格を使わなければなりません（MUST））。未認証の呼び出し元は価格なしでシグナルメタデータを受け取ってもかまいません（MAY）。メディアプロダクトにバンドルされている、または増分コストを持たないシグナルは `pricing_options[]` を省略してもかまいません（MAY）。

### 機能宣言

シグナルエージェントは [`get_adcp_capabilities`](/docs/protocol/get_adcp_capabilities) でホールセールサポートを宣言します。

```json theme={null}
{
  "signals": {
    "discovery_modes": ["brief", "wholesale"]
  }
}
```

`"wholesale"` を宣言しないエージェントは、ホールセール呼び出しに対して `INVALID_REQUEST` を返してもかまいません（MAY）。ホールセールディスカバリーは AdCP 3.1+ であるため、呼び出し元が 3.1+ のシグナルサーフェスやホールセールサポートを前提にできない場合、機能宣言が正規のサポートシグナルとなります。呼び出し元はホールセールリクエストを発行する前に探索すべきです（SHOULD）。

## ホールセールフィードバージョニング

ホールセール列挙があっても、エージェントのシグナルフィードをミラーするコンシューマーは、変更を検出するためだけに毎回のポーリングですべてのページネーションされたページを再取得することになります。これを避けるため、`get_signals` はすべてのレスポンスで返される不透明な `wholesale_feed_version` トークンをサポートします。後続の呼び出しで `if_wholesale_feed_version` を通じて渡すと、エージェントは `unchanged: true` でショートサーキットしてもかまいません（MAY）— シグナルペイロードなし、ページごとの差分なし。

これは `get_signals` が返すセラー側のホールセールシグナルフィードです。`sync_catalogs` フィードではありません。`sync_catalogs` はセラーアカウント上のバイヤー提供のキャンペーン入力フィードを管理します。

### 変更なしレスポンス

**リクエスト:**

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-request.json",
  "discovery_mode": "wholesale",
  "if_wholesale_feed_version": "v2026-05-18T08:00:00Z-acme-rev412"
}
```

**レスポンス（ホールセールシグナルフィード変更なし）:**

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "message": "Wholesale signals feed unchanged since v2026-05-18T08:00:00Z-acme-rev412.",
  "context_id": "ctx-abc-789",
  "unchanged": true,
  "wholesale_feed_version": "v2026-05-18T08:00:00Z-acme-rev412",
  "pricing_version": "v2026-05-18T08:00:00Z-acme-rev412",
  "cache_scope": "public"
}
```

`unchanged: true` のとき、`signals[]` は省略しなければならず（MUST）、コンシューマーはローカルのホールセールシグナルミラーを変更してはなりません（MUST NOT）。

### ホールセールシグナルフィード変更 — 完全ペイロード返却（省略版）

```json test=false theme={null}
{
  "message": "Returning 312 signals (wholesale feed version advanced).",
  "context_id": "ctx-abc-790",
  "wholesale_feed_version": "v2026-05-18T10:15:00Z-acme-rev415",
  "pricing_version": "v2026-05-18T10:15:00Z-acme-rev415",
  "cache_scope": "public",
  "signals": [
    {
      "signal_ref": { "scope": "data_provider", "data_provider_domain": "acme-data.com", "signal_id": "luxury_auto_intenders" },
      "signal_agent_segment_id": "sigagent_seg_4421",
      "name": "Luxury Auto Intenders",
      "description": "Households researching premium vehicles in the last 30 days.",
      "signal_type": "marketplace",
      "data_provider": "Acme Data",
      "coverage_percentage": 18.4,
      "deployments": [
        { "type": "platform", "platform": "the-trade-desk", "is_live": true,
          "activation_key": { "type": "segment_id", "segment_id": "ttd_seg_99821" } }
      ],
      "pricing_options": [
        { "pricing_option_id": "po_cpm_1", "model": "cpm", "cpm": 2.50, "currency": "USD" }
      ]
    }
  ],
  "pagination": { "has_more": true, "cursor": "eyJvIjo1MH0=", "total_count": 312 }
}
```

### ルール

* トークンは**不透明**です。フォーマットなし、順序なし、検査なし。
* 返される `wholesale_feed_version` は `cache_scope` を通じてスコープキー付けされます。呼び出し元は、使用した `(account, filters, discovery_mode, destinations, countries)` タプルと共に `(cache_scope, wholesale_feed_version)` のペアをキャッシュします。2 層モデルについては [キャッシュレイヤリング](#キャッシュレイヤリング) を参照。
* `pricing_version` は任意のより細粒度のトークンです。存在する場合、価格が動くと変わりますが、`wholesale_feed_version` は構造/メタデータが動いたときのみ変わります。セグメントメタデータを変えないレートカードスイープで一般的です。
* **`if_pricing_version` には `if_wholesale_feed_version` が必要です。** 価格は独自の構造的ベースラインを持ちません。`if_wholesale_feed_version` なしで `if_pricing_version` を送るのはスキーマレベルのエラーです。エージェントの評価は 2 段階です: ホールセールフィード不一致は完全ペイロードを返します。ホールセールフィード一致で価格不一致も完全ペイロードを返します（呼び出し元が更新された `pricing_options` を確認できるように）。両方一致 → `unchanged: true`。
* **`filters` の正規化。** エージェントは、`wholesale_feed_version` キースペースへのハッシュ化前に `filters` オブジェクトを正規化されたものとして扱わなければなりません（MUST）: キーを辞書順にソート、省略されデフォルトの値は同一に扱う、フィルターが集合セマンティクスを持つ場合は配列値をソート（例: `catalog_types`、`data_providers`）。同等だが形状の異なるフィルターオブジェクトを渡す呼び出し元は、同じ `wholesale_feed_version` を受け取らなければなりません（MUST）。キー順やデフォルト省略の違いによる暗黙のミラー陳腐化バグを防ぎます。**前方互換のデフォルト:** 3.x マイナーバージョンで追加される新しいフィルターフィールドは集合か列かのセマンティクスを宣言しなければなりません（MUST）。明示的な宣言がない場合、ルールは**集合セマンティクス**にデフォルトします。
* **ページネーションとの相互作用。** `wholesale_feed_versioning.supported: true` を宣言するエージェントは、（最初だけでなく）すべてのページネーションされたページで `wholesale_feed_version` を返さなければなりません（MUST）。バージョニングを宣言しないエージェントも同様にすべきです（SHOULD）。ページ間でホールセールフィードが変異した場合、新しいバージョンが次のページで現れ、呼び出し元は `cursor: null` からページネーションを再開しなければなりません（MUST）— すでに受け取った部分ページは陳腐化したバージョンを記述しています。
* **`unchanged: true` と進行中のページネーション。** ページネーション途中の呼び出し元は、それまでのページが描かれたバージョンに一致する `if_wholesale_feed_version` を送ってもかまいません（MAY）。エージェントが `unchanged: true` を確認した場合、レスポンスは `signals[]` とページネーションエンベロープを完全に省略し、呼び出し元はそのバージョン下での進行中のウォークを放棄します。エージェントは、アクティブなページネーション内の個々のページをスキップするために条件付きフェッチのショートサーキットを使ってはなりません（MAY NOT）— `unchanged` はフィード対キャッシュバージョンであり、ページ単位ではありません。
* `if_wholesale_feed_version` を無視する v3.1 より前のエージェントは、単に完全ペイロードを返します — 意味的には正しく、非効率なだけです。

条件付きフェッチを超えたプッシュ型の変更追跡については `specs/wholesale-feed-webhooks.md` を参照。ホールセールフィード Webhook は、変更されたシグナルペイロード、価格ペイロード、削除トゥームストーン、または一括変更サマリーを運びます。`get_signals` は修復と再照合の読み取りのままです。

## キャッシュレイヤリング

シグナルエージェントは 2 つの概念的なレイヤーを公開します: **パブリックレイヤー**（レートカード/構造ビュー）と **アカウント別オーバーレイ**（プレミアムバイヤー向けのアカウント固有価格）。条件付きフェッチパスは `cache_scope` を通じてレイヤーを認識します。

**2 層キャッシュ。**

| Layer           | Cache key                                                               | What's stored                                                                         |
| --------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Public          | `(agent, discovery_mode, filters, destinations, countries)`             | `wholesale_feed_version_public`、アカウント参照なしで見たホールセールシグナルフィードペイロード                       |
| Account overlay | `(agent, discovery_mode, filters, destinations, countries, account_id)` | `wholesale_feed_version_account`、`cache_scope: "account"` が返されたときのホールセールシグナルフィードペイロード |

**挙動。**

* `account` なしのリクエストは常に `cache_scope: "public"` を返します。呼び出し元はパブリックキーの下にキャッシュします。
* `account` ありのリクエストは `cache_scope: "public"` または `"account"` を返します（エージェントは宣言しなければなりません（MUST）。デフォルトなし）。
  * `"public"`: このアカウントはレートカードで価格付けされます。呼び出し元は重複排除してもかまいません（MAY）— バージョンとペイロードは未認証ビューと同じです。
  * `"account"`: このレスポンスはアカウント固有のオーバーライドを運びます。呼び出し元はアカウントオーバーレイキーの下にキャッシュします。
* エージェントはアカウントを `"account"` から `"public"` にダウングレードしてもかまいません（MAY）— 呼び出し元はこれを「このアカウントはもうオーバーライドを持たない」と解釈し、オーバーレイを破棄すべきです（SHOULD）。

**`if_wholesale_feed_version` での条件付きフェッチ。** トークンを、それが返されたスコープと組にして送ります。エージェントはそのスコープの現在のバージョンと比較します。呼び出し元のトークンが `"account"` スコープに属するが、エージェントが `cache_scope: "public"` で応答した場合、それがダウングレードシグナルです。

**Webhook 無効化。** ホールセールフィード Webhook イベントは、`*.priced` と `*.updated` のペイロードで `applies_to.scope` を宣言します。エージェントは、どのサブスクライバーがシグナル Webhook を受け取るかを決める際、`get_signals discovery_mode: "wholesale"` が使うのと同じアカウント/呼び出し元認可述語を適用しなければなりません（MUST）。

* `applies_to: { scope: "public" }` → パブリックレイヤーのキャッシュを無効化。そのパブリックバージョンを参照するすべてのアカウントオーバーレイも陳腐化します。
* `applies_to: { scope: "account", account_ids: [...] }` → 指定されたアカウントのオーバーレイのみを無効化。
* `account_ids` なしの `applies_to: { scope: "account" }` → セラーは影響を受ける集合を秘匿します。サブスクライバー別のスコープフィルターが、プリンシパルが影響を受ける集合にあるサブスクライバーにのみイベントをルーティングします。

完全な Webhook 側の仕様については `specs/wholesale-feed-webhooks.md` の §"Cache layering and event scoping" を参照。

## incomplete 配列

エージェントが呼び出し元の `time_budget` 内（または内部制限のため）にすべての作業を完了できない場合、レスポンスは `incomplete` — 欠けているものを宣言する配列 — を含みます。呼び出し元は `estimated_wait` を使って、より大きな予算で再試行すべきかを判断できます。

| Field            | Type     | Required | Description                                                                                                              |
| ---------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
| `scope`          | string   | Yes      | `"signals"`: 一致するすべてのシグナルが返されなかった。`"pricing"`: シグナルは返されたが価格が欠けているか未確認。`"wholesale_feed"`: ホールセールモードで、完全なフィード列挙を完了できなかった。 |
| `description`    | string   | Yes      | 何が欠けていてなぜかの人間可読な説明。                                                                                                      |
| `estimated_wait` | Duration | No       | このスコープを解決するのに追加でどれだけの時間が必要か。                                                                                             |

## 反復的絞り込み

`get_signals` は別個のモードフラグなしで反復的絞り込みをサポートします。`signal_spec` と `signal_refs` の組み合わせが操作を決定します。

| Fields provided                                                  | Behavior                                                                  |
| ---------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `signal_spec` のみ                                                 | ディスカバリー — 説明に一致するシグナルを探す                                                  |
| `signal_refs` のみ                                                 | 厳密検索 — 参照で特定のシグナルを返す                                                      |
| `signal_refs` + `signal_spec`                                    | 絞り込み — 既知のシグナルから開始し、spec に従って調整                                           |
| `discovery_mode: "wholesale"`（`signal_spec` も `signal_refs` もなし） | ホールセール — エージェントの完全な価格付きシグナルフィードを列挙。[ホールセールシグナルフィード](#ホールセールシグナルフィード) を参照。 |

以前の結果を絞り込むには、保持したいシグナルの `signal_ref` 値を渡し戻し、変更内容を記述する更新された `signal_spec` を提供します。

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-request.json",
  "signal_spec": "Same audience but with broader coverage, ideally above 20%",
  "signal_refs": [
    {
      "scope": "data_provider",
      "data_provider_domain": "experian.com",
      "signal_id": "luxury_auto_intenders"
    }
  ],
  "destinations": [
    {
      "type": "agent",
      "agent_url": "https://wonderstruck.salesagents.com"
    }
  ],
  "countries": ["US"]
}
```

シグナルエージェントは、提供された ID を出発点として、spec を調整ガイダンスとして使い、元の選択と要求された変更の両方を反映したシグナル（例: 同じプロバイダーのより広範なセグメント、またはより高いカバレッジを持つ代替プロバイダーの比較可能なセグメント）を返します。

### レスポンス - 複数シグナル

```json theme={null}
{
  "message": "I found 3 signals matching your luxury goods criteria. The best option is 'Affluent Shoppers' with 22% coverage, already live across all requested platforms. 'High Income Households' offers broader reach (35%) but requires activation on OpenX. All signals are priced between $2-4 CPM.",
  "context_id": "ctx-signals-abc123",
  "signals": [
    {
      "signal_ref": {
        "scope": "data_provider",
        "data_provider_domain": "acme-data.com",
        "signal_id": "affluent_shoppers"
      },
      "signal_agent_segment_id": "acme_affluent_shoppers",
      "name": "Affluent Shoppers",
      "description": "Users with demonstrated luxury purchase behavior",
      "signal_type": "marketplace",
      "data_provider": "Acme Data",
      "coverage_percentage": 22,
      "deployments": [
        {
          "type": "platform",
          "platform": "index-exchange",
          "account": "agency-123-ix",
          "is_live": true,
          "activation_key": {
            "type": "segment_id",
            "segment_id": "ix_agency123_acme_aff_shop"
          }
        },
        {
          "type": "platform",
          "platform": "openx",
          "account": "agency-123-ox",
          "is_live": true,
          "activation_key": {
            "type": "segment_id",
            "segment_id": "ox_agency123_affluent_789"
          }
        }
      ],
      "pricing_options": [
        {
          "pricing_option_id": "po_cpm_usd",
          "model": "cpm",
          "cpm": 3.50,
          "currency": "USD"
        }
      ]
    }
    // ... more signals
  ]
}
```

### レスポンス - 警告付き部分成功

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "message": "Found 2 luxury signals, but encountered some platform limitations. The 'Premium Auto Shoppers' signal has limited reach due to data restrictions, and pricing data is unavailable for one platform. Review the warnings below for optimization suggestions.",
  "context_id": "ctx-signals-abc123",
  "cache_scope": "public",
  "wholesale_feed_version": "sig_v2026-05-18T08:00:00Z-public-rev12",
  "signals": [
    {
      "signal_ref": {
        "scope": "data_provider",
        "data_provider_domain": "experian.com",
        "signal_id": "premium_auto_shoppers"
      },
      "signal_agent_segment_id": "premium_auto_shoppers",
      "name": "Premium Auto Shoppers",
      "description": "High-value automotive purchase intenders",
      "signal_type": "marketplace",
      "data_provider": "Experian",
      "coverage_percentage": 8,
      "deployments": [
        {
          "type": "platform",
          "platform": "the-trade-desk",
          "is_live": true,
          "activation_key": {
            "type": "segment_id",
            "segment_id": "ttd_exp_auto_premium"
          }
        }
      ],
      "pricing_options": [
        {
          "pricing_option_id": "po_cpm_usd",
          "model": "cpm",
          "cpm": 4.50,
          "currency": "USD"
        }
      ]
    }
  ],
  "errors": [
    {
      "code": "PRICING_UNAVAILABLE",
      "message": "Pricing data temporarily unavailable for The Trade Desk platform",
      "field": "signals[0].pricing_options",
      "suggestion": "Retry in 15-30 minutes when platform pricing feed updates",
      "details": {
        "affected_platform": "the-trade-desk",
        "last_updated": "2025-01-15T12:00:00Z",
        "retry_after": 1800
      }
    },
    {
      "code": "PRICING_UNAVAILABLE", 
      "message": "Pricing data temporarily unavailable for Amazon DSP",
      "field": "filters.platforms",
      "suggestion": "Pricing will be available during activation, or try again later",
      "details": {
        "affected_platform": "amazon-dsp",
        "retry_after": 1800
      }
    }
  ]
}
```

### レスポンス - 該当なし

```json theme={null}
{
  "$schema": "/schemas/signals/get-signals-response.json",
  "status": "completed",
  "message": "I couldn't find any signals matching 'underwater basket weavers' in the requested platforms. This appears to be a very niche audience. Consider broadening your criteria to 'craft enthusiasts' or 'hobby communities' for better results. Alternatively, we could create a custom signal for this specific audience.",
  "context_id": "ctx-signals-abc123",
  "cache_scope": "public",
  "wholesale_feed_version": "sig_v2026-05-18T08:00:00Z-public-rev12",
  "signals": []
}
```

## 実装ガイド

### シグナルメッセージ生成

`message` フィールドは実行可能なインサイトを提供すべきです。

```python theme={null}
def generate_signals_message(signals, request):
    if not signals:
        return generate_no_signals_message(request.signal_spec)

    best_signal = find_best_signal(signals)

    if len(signals) == 1:
        signal = signals[0]
        deployment_status = get_deployment_summary(signal, request.destinations)
        pricing = signal.pricing_options[0] if signal.pricing_options else None
        if pricing:
            p = pricing.pricing
            if p.model == "cpm":
                price_commentary = f"Priced at ${p.cpm:.2f} CPM {p.currency}."
            elif p.model == "percent_of_media":
                cap = f", capped at ${p.max_cpm:.2f} CPM" if getattr(p, "max_cpm", None) else ""
                price_commentary = f"Priced at {p.percent}% of media spend{cap}."
            elif p.model == "flat_fee":
                price_commentary = f"Flat fee of {p.amount} {p.currency} per {p.period}."
            else:
                price_commentary = ""
        else:
            price_commentary = ""
        coverage_commentary = f" with {signal.coverage_percentage}% coverage" if getattr(signal, "coverage_percentage", None) is not None else ""
        return f"I found a perfect match: '{signal.name}' from {signal.data_provider}{coverage_commentary}. {deployment_status} {price_commentary}"
    else:
        return f"I found {len(signals)} signals matching your {extract_key_criteria(request.signal_spec)} criteria. {describe_best_option(best_signal)} {get_pricing_range(signals)}."

def get_deployment_summary(signal, requested_deployments):
    live = [d for d in signal.deployments if d.is_live]
    pending = [d for d in signal.deployments if not d.is_live]

    if not pending:
        return "Already live on all requested deployments, ready to use immediately."
    elif live:
        activation_time = max((d.estimated_activation_duration_minutes or 0) for d in pending)
        return f"Live on {len(live)} deployment(s). Activation on {len(pending)} more would take about {activation_time} minutes."
    else:
        return "Requires activation on all deployments, which typically takes 1-2 hours."
```
