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

# create_media_buy

> create_media_buy タスク — AdCP で発見したプロダクトから広告キャンペーンを作成します。パッケージ、予算、フライト期間、ガバナンスルール、承認ワークフローを処理。

選択したパッケージからメディアバイを作成するか、プロポーザルを実行します。必要に応じたバリデーションや承認、キャンペーン作成を処理します。

2 つのモードをサポート:

* **Manual Mode**: `packages` 配列で明示的にラインアイテムを指定
* **Proposal Mode**: `proposal_id` と `total_budget` を指定し、`get_products` のプロポーザルを実行

**Response Time**: 即時〜日単位（`completed`、120 秒未満の `working`、数時間〜数日の `submitted`）

**Request Schema**: [`/schemas/v3/media-buy/create-media-buy-request.json`](https://adcontextprotocol.org/schemas/v3/media-buy/create-media-buy-request.json)
**Response Schema**: [`/schemas/v3/media-buy/create-media-buy-response.json`](https://adcontextprotocol.org/schemas/v3/media-buy/create-media-buy-response.json)

## クイックスタート

2 つのパッケージでシンプルなメディアバイを作成:

<CodeGroup>
  ```javascript JavaScript test=false theme={null}
  import { testAgent } from '@adcp/sdk/testing';
  import { CreateMediaBuyResponseSchema } from '@adcp/sdk';

  // Calculate dates dynamically - start tomorrow, end in 90 days
  const tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  tomorrow.setHours(0, 0, 0, 0);
  const endDate = new Date(tomorrow);
  endDate.setDate(endDate.getDate() + 90);

  const result = await testAgent.createMediaBuy({
    brand: {
      domain: 'acmecorp.com'
    },
    packages: [
      {
        product_id: 'prod_d979b543',
        pricing_option_id: 'cpm_usd_auction',
        format_ids: [
          {
            agent_url: 'https://creative.adcontextprotocol.org',
            id: 'display_300x250_image'
          }
        ],
        budget: 2500,
        bid_price: 5.00
      },
      {
        product_id: 'prod_e8fd6012',
        pricing_option_id: 'cpm_usd_auction',
        format_ids: [
          {
            agent_url: 'https://creative.adcontextprotocol.org',
            id: 'display_300x250_html'
          }
        ],
        budget: 2500,
        bid_price: 4.50
      }
    ],
    start_time: tomorrow.toISOString(),
    end_time: endDate.toISOString()
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  // Validate response against schema
  const validated = CreateMediaBuyResponseSchema.parse(result.data);

  // Check for errors (discriminated union response)
  if ('errors' in validated && validated.errors) {
    throw new Error(`Failed to create media buy: ${JSON.stringify(validated.errors)}`);
  }

  if ('media_buy_id' in validated) {
    console.log(`Created media buy ${validated.media_buy_id}`);
    console.log(`Upload creatives by: ${validated.creative_deadline}`);
    console.log(`Packages created: ${validated.packages.length}`);
  }
  ```

  ```python Python test=false theme={null}
  import asyncio
  import time
  from datetime import datetime, timedelta, timezone
  from adcp.testing import test_agent

  async def create_campaign():
      # Calculate dates dynamically - start tomorrow, end in 90 days
      tomorrow = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1)
      end_date = tomorrow + timedelta(days=90)

      result = await test_agent.simple.create_media_buy(
          brand={
              'domain': 'acmecorp.com'
          },
          packages=[
              {
                  'product_id': 'prod_d979b543',
                  'pricing_option_id': 'cpm_usd_auction',
                  'format_ids': [
                      {
                          'agent_url': 'https://creative.adcontextprotocol.org',
                          'id': 'display_300x250_image'
                      }
                  ],
                  'budget': 2500,
                  'bid_price': 5.00
              },
              {
                  'product_id': 'prod_e8fd6012',
                  'pricing_option_id': 'cpm_usd_auction',
                  'format_ids': [
                      {
                          'agent_url': 'https://creative.adcontextprotocol.org',
                          'id': 'display_300x250_html'
                      }
                  ],
                  'budget': 2500,
                  'bid_price': 4.50
              }
          ],
          start_time=tomorrow.isoformat().replace('+00:00', 'Z'),
          end_time=end_date.isoformat().replace('+00:00', 'Z')
      )

      # Check for errors (discriminated union response)
      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Failed to create media buy: {result.errors}")

      print(f"Created media buy {result.media_buy_id}")
      print(f"Upload creatives by: {result.creative_deadline}")
      print(f"Packages created: {len(result.packages)}")

  asyncio.run(create_campaign())
  ```

  ```bash CLI test=false theme={null}
  npx @adcp/sdk@latest \
    https://test-agent.adcontextprotocol.org/sales/mcp \
    create_media_buy \
    '{"brand":{"domain":"acmecorp.com"},"packages":[{"product_id":"prod_d979b543","pricing_option_id":"cpm_usd_auction","format_ids":[{"agent_url":"https://creative.adcontextprotocol.org","id":"display_300x250_image"}],"budget":30000,"bid_price":5.00},{"product_id":"prod_e8fd6012","pricing_option_id":"cpm_usd_auction","format_ids":[{"agent_url":"https://creative.adcontextprotocol.org","id":"display_300x250_html"}],"budget":20000,"bid_price":4.50}],"start_time":"2025-06-01T00:00:00Z","end_time":"2025-08-31T23:59:59Z"}' \
    --auth $ADCP_AUTH_TOKEN
  ```
</CodeGroup>

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

| Parameter           | Type                                                                                                  | Required | Description                                                                                                                                                                                                             |
| ------------------- | ----------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `account`           | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references)                      | Yes      | アカウント参照。`{ "account_id": "..." }` または、セラーが暗黙的な解決をサポートする場合は `{ "brand": {...}, "operator": "..." }` を渡します。請求とポリシー評価に必要。                                                                                                  |
| `proposal_id`       | string                                                                                                | No\*     | 実行する `get_products` のコミット済みプロポーザル ID。packages の代替。ドラフトのプロポーザルはまず finalize する必要があり、セラーはドラフトプロポーザルの実行を `PROPOSAL_NOT_COMMITTED` で拒否します。                                                                                   |
| `total_budget`      | TotalBudget                                                                                           | No\*     | プロポーザル実行時の総予算。配分割合はパブリッシャーが適用                                                                                                                                                                                           |
| `packages`          | Package\[]                                                                                            | No\*     | パッケージ構成の配列（下記）。proposal\_id を使わない場合は必須                                                                                                                                                                                  |
| `brand`             | BrandRef                                                                                              | Yes      | ブランド参照 — 実行時に完全なアイデンティティに解決されます。[brand.json](/docs/brand-protocol/brand-json) 参照                                                                                                                                        |
| `start_time`        | string                                                                                                | Yes      | `"asap"` または ISO 8601 日時。新規メディアバイでは、具体的な日時は過去であってはなりません。                                                                                                                                                                |
| `end_time`          | string                                                                                                | Yes      | ISO 8601 日時（指定がなければ UTC）                                                                                                                                                                                                |
| `paused`            | boolean                                                                                               | No       | 配信を保留した状態でメディアバイを作成します。true で、かつメディアバイが本来アクティブになる場合、`media_buy_status` は `paused` になります。セットアップのブロッカーが依然として優先されます: クリエイティブ欠如は `pending_creatives`、将来のフライトは `pending_start` を返し、それらのブロッカーが解消された後に保留が `paused` として可視化されます。 |
| `invoice_recipient` | [BusinessEntity](/docs/building/by-layer/L2/accounts-and-agents#billing-entity-and-invoice-recipient) | No       | この購入についてアカウントのデフォルト請求エンティティを上書きします。セラーは受取人が認可されていることを検証しなければならず（MUST）、ガバナンスエージェントが設定されている場合は `check_governance` に含めなければなりません。                                                                                           |
| `po_number`         | string                                                                                                | No       | 発注番号                                                                                                                                                                                                                    |
| `idempotency_key`   | string                                                                                                | No       | 安全なリトライのための一意キー。同じキーとアカウントのリクエストがすでに処理済みの場合、セラーは既存のメディアバイを返します。（セラー、リクエスト）ペアごとに一意でなければなりません。最低 16 文字。                                                                                                                   |
| `context`           | object                                                                                                | No       | レスポンスにそのまま返される不透明な相関データ。内部トラッキング、トレース ID、その他の呼び出し元固有の識別子に使用。                                                                                                                                                            |
| `reporting_webhook` | ReportingWebhook                                                                                      | No       | レポーティングの自動配信設定                                                                                                                                                                                                          |

\* Either `packages` OR (`proposal_id` + `total_budget`) must be provided.

プロポーザルを実行する場合、返されたプロポーザルの `proposal_status` によって `create_media_buy` が有効かどうかが決まります。`committed` のプロポーザルは `expires_at` 前に実行でき、`draft` のプロポーザルは事前に `action: "finalize"` を指定した `get_products` の refine 呼び出しが必要です。Finalize は確定条件へのセラーのコミットであり、バイヤーの受諾ではありません。この `create_media_buy` 呼び出しが受諾/実行のステップです。

### TotalBudget オブジェクト

| Parameter  | Type   | Required | Description    |
| ---------- | ------ | -------- | -------------- |
| `amount`   | number | Yes      | 総予算額           |
| `currency` | string | Yes      | ISO 4217 通貨コード |

### Package オブジェクト

| Parameter               | Type                                                                                                                  | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `product_id`            | string                                                                                                                | Yes      | `get_products` で取得した product\_id。セラーは、この要求パッケージを表すすべてのレスポンスパッケージオブジェクトでこの値をエコーしなければなりません（MUST）。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `pricing_option_id`     | string                                                                                                                | Yes      | プロダクトの `pricing_options` 配列にある価格オプション ID                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `format_ids`            | FormatID\[]                                                                                                           | No       | レガシーの名前付きフォーマットセレクター。使用するフォーマット ID——プロダクトでサポートされている必要あり。省略された場合（かつ 3.1 以降のフォーマットオプションセレクターや直接の正準セレクターも存在しない場合）、プロダクトがサポートするすべてのフォーマットがデフォルトになります。異種のセラー集団を対象とするフォーマットオプション対応のバイヤー SDK は、レガシーフォーマットのみのセラーが all-formats にフォールバックせず明示的なフォーマットセットを受け取れるよう、`format_option_refs` と並べてこれを二重出力すべきです（SHOULD）。                                                                                                                                                                                                                                                                                  |
| `format_option_refs`    | FormatOptionRef\[]                                                                                                    | No       | 3.1 以降のフォーマットオプションセレクター。パッケージの対象プロダクトの `format_options[]` 内エントリへの構造化参照: パブリッシャーカタログ由来のオプションには `{scope: "publisher", publisher_domain, format_option_id}`、プロダクトローカルのオプションには `{scope: "product", format_option_id}`（[canonical formats](/docs/creative/canonical-formats) 参照）。存在する場合、`format_option_refs` は `format_ids` と直接の `format_kind`/`params` の両方に優先します。エントリが `format_options[]` のエントリと一致しない、プロダクトがレガシーフォーマットのみ、またはプロダクトの `format_options[]` エントリが選択可能な `format_option_id` 値を公開しない場合、セラーは `UNSUPPORTED_FEATURE`（フィールドパス `packages[i].format_option_refs[j]`）で拒否しなければなりません（MUST）。 |
| `format_kind`           | CanonicalFormatKind                                                                                                   | No       | 3.1 以降の直接正準セレクター。バイヤーが `format_option_refs[]` や `format_ids[]` ではなく正準種別で作成する場合に、このパッケージが対象とする正準的なフォーマット形状を指定します。プロダクト宣言が寸法、尺、サイズ、コーデック、その他の正準パラメータを要求する場合は `params` と組み合わせます。`format_ids[]` も存在し `format_option_refs[]` が無い場合、セラーは `format_ids[]` を検証します。`format_kind` は同じ正規化された形状の情報提供のエコーにすぎません。                                                                                                                                                                                                                                                                                    |
| `params`                | object                                                                                                                | No       | `format_kind` の直接正準セレクターのためのパラメータ。選択した正準のパラメータ語彙に従います。`format_kind` が必要で、`params` 単独はスキーマ不正です。`{format_kind: "image"}` のような広いセレクターは、`format_options[]` が `params.width` と `params.height` を固定するプロダクトを満たしません。セラーは仕様不足の直接セレクターを `UNSUPPORTED_FEATURE` または同等のフォーマットセレクターエラーで拒否します。                                                                                                                                                                                                                                                                                                       |
| `budget`                | number                                                                                                                | Yes      | 価格オプションの通貨での予算                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `impressions`           | number                                                                                                                | No       | このパッケージのインプレッション目標                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `paused`                | boolean                                                                                                               | No       | 一時停止状態で作成する場合（デフォルト: `false`）                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `pacing`                | string                                                                                                                | No       | `"even"`（デフォルト）、`"asap"`、`"front_loaded"`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `bid_price`             | number                                                                                                                | No       | オークション価格の場合の入札額。選択した価格オプションに `max_bid: true` がない限り、指定した金額がそのまま入札/価格として扱われる。`max_bid: true` の場合はバイヤーの最大支払い意思額（上限）として扱われる。                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `optimization_goals`    | [OptimizationGoal\[\]](/docs/media-buy/conversion-tracking/#optimization-goals)                                       | No       | このパッケージの最適化ターゲット。各ゴールは `kind: "event"`（`event_sources` 配列を持つコンバージョンイベント。オプションで `cost_per`、`per_ad_spend`、`maximize_value` ターゲットを指定可）または `kind: "metric"`（オプションで `cost_per` または `threshold_rate` ターゲットを持つセラー独自のメトリクス）。イベントゴールにはプロダクトの `conversion_tracking.supported_targets` が必要。メトリクスゴールには `metric_optimization.supported_metrics` が必要。                                                                                                                                                                                                                                              |
| `targeting_overlay`     | TargetingOverlay                                                                                                      | No       | 追加ターゲティング条件（[Targeting](/docs/media-buy/advanced-topics/targeting) 参照）                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `start_time`            | string                                                                                                                | No       | このパッケージのフライト開始日時（ISO 8601）。省略するとメディアバイの `start_time` を継承。メディアバイの日付範囲内である必要があります。`"asap"` はサポートしません。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `end_time`              | string                                                                                                                | No       | このパッケージのフライト終了日時（ISO 8601）。省略するとメディアバイの `end_time` を継承。メディアバイの日付範囲内である必要があります。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `creative_assignments`  | CreativeAssignment\[]                                                                                                 | No       | 既存ライブラリのクリエイティブを重み/プレースメント指定付きで割り当て                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `creatives`             | CreativeAsset\[]                                                                                                      | No       | 新規クリエイティブアセットをインラインでアップロードして割り当て。`media_buy.features.inline_creative_management: true` が必要。セラーが `creative.has_creative_library: true` も宣言する場合、`creative_id` はライブラリに既存であってはなりません。                                                                                                                                                                                                                                                                                                                                                                                                      |
| `context`               | object                                                                                                                | No       | パッケージレスポンス、Webhook、読み取り面にそのまま返される不透明な相関データ。セラーが割り当てた `package_id` を内部ラインアイテム、キャンペーン構造、トラッキング状態にマッピングするために使用。混在したセラー集団を対象とするバイヤーは、`product_id` をエコーしないレガシーセラーのために、ここにパッケージごとの相関値（一般的には `context.buyer_ref`）を含めるべきです（SHOULD）。                                                                                                                                                                                                                                                                                                                                                           |
| `measurement_terms`     | [MeasurementTerms](/docs/media-buy/advanced-topics/pricing-models#measurement-terms-and-performance-standards)        | No       | バイヤーが提案する課金計測とメイクグッド条件。プロダクトのデフォルトを上書きします。セラーは受諾（確定パッケージでエコー）、`TERMS_REJECTED` で拒否、または調整します。省略時はプロダクトの `measurement_terms` が適用されます。                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `performance_standards` | [PerformanceStandard\[\]](/docs/media-buy/advanced-topics/pricing-models#measurement-terms-and-performance-standards) | No       | バイヤーが提案するパフォーマンス基準（ビューアビリティ、IVT、完了率、ブランドセーフティ、アテンションスコア）。プロダクトのデフォルトを上書きします。セラーは受諾、`TERMS_REJECTED` で拒否、または調整します。省略時はプロダクトの `performance_standards` が適用されます。                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `committed_metrics`     | object\[]                                                                                                             | No       | バイヤーが提案するレポート契約——バイヤーがセラーに配信レポートで埋めることをコミットしてほしいメトリクス。`measurement_terms`/`performance_standards` と同じ交渉パターン: 各エントリは `scope: "standard"`（閉じた列挙の `metric_id` を伴う）または `scope: "vendor"`（`vendor` BrandRef ＋ベンダーの `metric_id` を伴う）をタグ付けします。リクエスト側のエントリは `committed_at` を持ちません——そのタイムスタンプは受諾時にセラーが刻印します。セラーは受諾（`committed_at` 付きでレスポンスにエコー）、`TERMS_REJECTED` で拒否、または正規化（異なるが互換なリストをエコー）します。省略時、セラーはプロダクトの `available_metrics` と、バイヤーがディスカバリー時に渡した `required_metrics` フィルターに基づいて、何をコミットするかを決めます。                                                                                            |

## レスポンス

### 成功レスポンス

| Field               | Description                                                                                                                                                                                                                                                |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `media_buy_id`      | セラーの一意 ID                                                                                                                                                                                                                                                  |
| `account`           | このメディアバイに請求される解決済みアカウント。完全な [Account](/docs/building/by-layer/L2/accounts-and-agents#account-references) オブジェクトとしてエコーされます（`account_id`、`name`、`status`、および解決済みの `brand`/`operator` を含む）。リクエストが暗黙的解決（`brand` + `operator`）を使った場合、これはセラーが解決したアカウントを確認します。任意。 |
| `confirmed_at`      | セラーがメディアバイにコミットした ISO 8601 タイムスタンプ。設定後は安定します。遅延/手動承認フローでは、セラーのコミットが発生するまで `null` になりうる。                                                                                                                                                                    |
| `creative_deadline` | クリエイティブ提出期限 (ISO 8601)                                                                                                                                                                                                                                     |
| `revision`          | 初期のメディアバイリビジョン。状態変更を意図する次の `update_media_buy` 呼び出しで、この値を `revision` トークンとして使います。                                                                                                                                                                           |
| `packages`          | 作成されたパッケージの配列（完全な状態付き）。パッケージは、メディアバイの期限と異なる場合にパッケージごとの `creative_deadline` を含みうる。また、一つのセレクターが優先される場合でも読み取り面がロスレスになるよう、作成時に供給されたすべてのフォーマットセレクターフィールド（`format_option_refs`、`format_ids`、および/または `format_kind`/`params`）をエコーすべきです（SHOULD）。                    |

`confirmed_at` はセラーのコミット時刻であり、配信ステータスのタイムスタンプではありません。購入が後で一時停止、再開、配信開始、完了、またはパフォーマンス報告しても更新しないでください。コミット済みの同期作成は即座にこれを刻印します。バイヤーに `media_buy_id` を返さない場合は `submitted` レスポンス分岐を使います。セラーは代わりに、暫定購入について `media_buy_id`、`packages`、`confirmed_at: null` を伴う同期成功を返してもよい（MAY）。そのような購入は `get_media_buys` で取得可能でなければならず（MUST）、コミット時に `confirmed_at` を正確に一度だけ設定して遷移しなければなりません（MUST）。`confirmed_at: null` の暫定購入は `active` であってはならず（MUST NOT）、`packages[].committed_metrics` を含んではなりません（MUST NOT）。

#### 確定パッケージのレポート契約

レスポンス内の各パッケージは `committed_metrics` を運びうる（MAY）——このパッケージについてセラーが配信レポートで埋めることに合意した拘束的なレポート契約です。このフィールドは、標準メトリクス（閉じた `available-metric.json` 列挙由来）とベンダー定義メトリクス（BrandRef に紐付く）の両方を運ぶ統一配列で、各エントリは明示的な `scope` 判別子でタグ付けされ、`committed_at` でタイムスタンプされます:

`confirmed_at` が `null` の場合、セラーは `packages[].committed_metrics` を省略しなければなりません（MUST）。`confirmed_at` を設定する最初のレスポンスは初期の committed-metrics セットを含んでもよく（MAY）、各エントリの `committed_at` は `confirmed_at` と等しくなければなりません（MUST）。

```json theme={null}
{
  "package_id": "pkg_001",
  "committed_metrics": [
    { "scope": "standard", "metric_id": "impressions",     "committed_at": "2026-04-29T10:53:00Z" },
    { "scope": "standard", "metric_id": "completed_views", "committed_at": "2026-04-29T10:53:00Z" },
    { "scope": "vendor",   "vendor": { "domain": "attentionvendor.example" },
                           "metric_id": "attention_units", "committed_at": "2026-04-29T10:53:00Z" },
    { "scope": "standard", "metric_id": "viewable_rate",
                           "qualifier": { "viewability_standard": "mrc" },
                           "committed_at": "2026-05-30T14:22:00Z" }
  ]
}
```

**契約の仕組み:**

* **Day-1 のエントリ**は `committed_at = confirmed_at` を共有します。セラーは、プロダクトの `reporting_capabilities` から配信する準備があるものに基づいて、`create_media_buy` レスポンスで day-1 セットを刻印します。
* **フライト中の追加**は `update_media_buy` を通じて追記されます——それぞれ独自の `committed_at` タイムスタンプを持つ追記専用です。これにより、セラーは購入をキャンセルして再発行することなく、「Adelaide のアテンションは30日目以降から契約の一部です」と正直に言えます。
* **既存のエントリは不変です。** セラーは、既存エントリを変更または削除しようとする `update_media_buy` リクエストを `validation_error`（推奨コード: `IMMUTABLE_FIELD`）で拒否しなければなりません（MUST）。新しいエントリは追記できます。
* **標準メトリクスの qualifier。** 一部のメトリクスは複数の非互換な計測パスを持ち、曖昧さの解消が必要です:

  * **`viewability_standard`** — `metric_id` が `viewable_impressions`、`viewable_rate`、`measurable_impressions` のいずれかで、セラーが特定のビューアビリティ標準にコミットする場合（MRC と GroupM は実質的に異なる閾値——`viewability-standard` 列挙を参照）、エントリは `qualifier.viewability_standard` を持たなければなりません（MUST）。`missing_metrics` でも対称: MRC ビューアビリティを期待するバイヤーは、GroupM のみの配信レポートを MRC コミットの欠如としてフラグします。
  * **`completion_source`** — `metric_id` が `completion_rate` で、セラーが特定のソース（プレーヤー/広告サーバー自身の完了イベント vs. `performance_standard.vendor` に紐付く第三者計測ベンダー）にコミットする場合、エントリは `qualifier.completion_source`（`seller_attested` または `vendor_attested`）を持たなければなりません（MUST）。二つのパスは、特に SSAI 環境で実質的に異なるレートを生みうる。`missing_metrics` でも対称。
  * **`attribution_methodology`** — `metric_id` が成果メトリクス（`conversions`、`conversion_value`、`roas`、`cost_per_acquisition`、`incremental_sales_lift`、`brand_lift`、`foot_traffic`、`conversion_lift`、`brand_search_lift`、`units_sold`、`new_to_brand_rate`、`new_to_brand_units`、`leads`）で、セラーが特定のアトリビューション手法にコミットする場合、エントリは `qualifier.attribution_methodology`（リテールメディアのクローズドループには `deterministic_purchase`、その他のパスには `probabilistic`、`panel_based`、`modeled`）を持つべきです（SHOULD）。異なる手法の下の二つの成果行は交換不可。`missing_metrics` でも対称。
  * **`attribution_window`** — `metric_id` が成果メトリクスで、セラーが特定のルックバックウィンドウにコミットする場合、エントリは構造化された期間として `qualifier.attribution_window`（`{ interval: 14, unit: "days" }`）を持つべきです（SHOULD）。異なるウィンドウの二つの成果行は、バイヤーが誤って期間をまたいで集計しないよう、別々の行として報告されます。

  qualifier がなければ契約は曖昧になり、照合は配信レポートがたまたま運ぶものにフォールバックします。qualifier の語彙は閉じています（`additionalProperties: false`）。新しいキーは後続のマイナーで明示的に出荷されます。
* **照合:** `get_media_buy_delivery` の `missing_metrics` は、`committed_metrics` を `committed_at < reporting_period.end` のエントリにフィルタし、レポートで埋められていないものをフラグします。フライト中にコミットされたメトリクスは、そのコミットタイムスタンプ以降のみ監査されます。qualifier は逐語的に一致します——コミット済みの `{viewable_rate, mrc}` は、`viewability.standard: groupm` を運ぶ配信された `viewable_rate` では満たされません。
* **v1 では任意。** パッケージごとのスナップショットインフラを持たないセラーは段階的に採用できます。欠如は適合ですが、既知の監査ギャップを伴います: スナップショットがなければ、`missing_metrics` はレポート時のプロダクトのライブ `available_metrics` に対して照合され、作成時にコミットされた内容を反映しないことがあります。`committed_metrics` を省略するセラーはこのリスクを受け入れます。バイヤーは欠如を「クリーンな配信」ではなく「監査グレードの契約なし」として扱うべきです（SHOULD）。次のメジャーで必須になる見込み。

### エラーレスポンス

| Field    | Description        |
| -------- | ------------------ |
| `errors` | 失敗理由を示すエラーオブジェクト配列 |

### Submitted レスポンス

購入を同期的に確定できない場合に返されます——例: IO 署名を待つ保証付き購入、ガバナンスレビューのキュー入り、バッチ処理など。完了アーティファクト（`tasks/get` またはプッシュ通知 Webhook で配信）が `media_buy_id` と `packages` を運びます。

プロポーザル固有の受諾 Webhook はありません。人間の承認、IO 署名、または非同期処理を要するプロポーザル実行は、この同じ submitted タスクエンベロープと標準のタスク/Webhook 完了パスを使います。

| Field     | Description                                                                                                                                 |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`  | リテラルの `"submitted"` — ライフサイクル状態に `media_buy_status` を使う同期成功分岐からこの形状を区別します。3.1 移行期間中、セラーは後方互換のため同期成功で非推奨のトップレベル MediaBuyStatus 値も出してよい（MAY）。 |
| `task_id` | バイヤーが `tasks/get` でポーリングする、または Webhook コールバックで受け取るハンドル。                                                                                     |
| `message` | 任意の人が読める説明（例: 「営業チームの IO 署名待ち」）。                                                                                                            |
| `errors`  | 任意の助言的な警告（非ブロッキング）。最終的な失敗はエラーレスポンスに属します。                                                                                                    |

**Note**: レスポンスはこれら三つの形状で相互排他です。まず `status` でディスパッチします: `"submitted"` → 非同期エンベロープ、それ以外は成功フィールドにアクセスする前に `errors` を確認します。

### Submitted と同期 Success をいつ返すか（規範的）

`submitted` と同期成功の選択は**呼び出しごと**で、プロダクトごとの属性と各特定の作成に対するセラーのポリシーに駆動されます——一律のセラーごとのルールではありません。営業保証のセラーは、同じセッション内で一部の `create_media_buy` 呼び出しに同期成功を、他に `submitted` を正当に返しうる。適合的な SDK skill は、入力に関わらずすべての `create_media_buy` について `submitted` を返すようエージェントに指示してはなりません（MUST NOT）。一律に `submitted` を返すセラーは、`sales-guaranteed` コンプライアンスストーリーボードの非 IO 承認パスで失敗します。

セラーは次の場合に `submitted` を返さなければなりません（MUST）:

* リクエストが `delivery_type: "guaranteed"` のプロダクトを一つ以上参照し、**かつ**セラーが `requires_io_approval` 機能を宣言する場合——人間の承認ハンドシェイクはレスポンス内で完了できません。完了アーティファクトは IO 署名の完了後に `tasks/get` または Webhook で配信されます。
* リクエストが同期的に完了できないセラー側のガバナンスレビューをトリガーする場合（例: 規制業種向けの手動ブランドセーフティレビュー）。
* リクエストが、セラーがレスポンスタイムアウト内に消化できないバッチ処理キューに入る場合。

セラーは次の場合に同期成功を返さなければなりません（MUST）:

* 参照されるすべてのプロダクトが `delivery_type: "non_guaranteed"` の場合。購入はインラインで作成・確認され、`media_buy_id` と `packages` が即座に発行されます。これはセラーの専門領域に関わらず適用されます——非保証プロダクトを提供する営業保証のセラーは同期成功を返します。
* リクエストが保証プロダクトを参照し、セラーが `requires_io_approval` を宣言しない場合（まれ。通常はセラーが承認を事前クリアしているリテール SKU や見積レートの保証フロー）。
* 購入が、バイヤーに即座に観測可能な既知の非終端状態（`pending_creatives` / `pending_start` / `active` / `paused`）に入る場合。

コンプライアンスグレーダーは、別々のストーリーボードシナリオを通じて同じセラーに対して両パスを観測します: `create_buy_submitted` シナリオは `requires_io_approval` を持つ保証プロダクトをシードし、四つの共有シナリオ（`measurement_terms_rejected`、`pending_creatives_to_start`、`inventory_list_targeting`、`invalid_transitions`）は非保証プロダクトをシードして同期の `media_buy_id` 返却を期待します。同期期待のシナリオで `submitted` を返すセラーはコンプライアンスに失敗します——フィクスチャパターンは [`sales-guaranteed` 専門領域](https://github.com/adcontextprotocol/adcp/tree/main/static/compliance/source/specialisms/sales-guaranteed) を参照（オープンブリーフの `get_products` 呼び出しが同期作成パスに解決されるよう、非保証プロダクトが最初にリストされます）。

このルールは、[#3822](https://github.com/adcontextprotocol/adcp/issues/3822) で追跡される skill ↔ storyboard の矛盾を解決します: 「すべての `create_media_buy` にタスクエンベロープを返す」ようエージェントに指示する SDK skill は非適合です。正しい skill は、プロダクトごとの `delivery_type` とセラーの `requires_io_approval` 機能でディスパッチするようエージェントに指示します。

## 主なシナリオ

### ターゲティング付きキャンペーン

地理制限やフリークエンシーキャップを追加:

<CodeGroup>
  ```javascript JavaScript test=false theme={null}
  import { testAgent } from '@adcp/sdk/testing';
  import { CreateMediaBuyResponseSchema } from '@adcp/sdk';

  // Calculate end date dynamically - 90 days from now
  const endDate = new Date();
  endDate.setDate(endDate.getDate() + 90);

  const result = await testAgent.createMediaBuy({
    brand: {
      domain: 'acmecorp.com'
    },
    packages: [{
      product_id: 'prod_d979b543',
      pricing_option_id: 'cpm_usd_auction',
      format_ids: [{
        agent_url: 'https://creative.adcontextprotocol.org',
        id: 'display_300x250_image'
      }],
      budget: 2500,
      bid_price: 5.00,
      targeting_overlay: {
        geo_countries: ['US'],
        geo_regions: ['US-CA', 'US-NY'],
        frequency_cap: {
          suppress: { interval: 60, unit: 'minutes' }
        }
      }
    }],
    start_time: 'asap',
    end_time: endDate.toISOString()
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = CreateMediaBuyResponseSchema.parse(result.data);
  if ('errors' in validated && validated.errors) {
    throw new Error(`Creation failed: ${JSON.stringify(validated.errors)}`);
  }

  if ('media_buy_id' in validated) {
    console.log(`Campaign ${validated.media_buy_id} created with targeting`);
  }
  ```

  ```python Python test=false theme={null}
  import asyncio
  import time
  from datetime import datetime, timedelta, timezone
  from adcp.testing import test_agent

  async def create_targeted_campaign():
      # Calculate end date dynamically - 90 days from now
      end_date = datetime.now(timezone.utc) + timedelta(days=90)

      result = await test_agent.simple.create_media_buy(
          brand={
              'domain': 'acmecorp.com'
          },
          packages=[{
              'product_id': 'prod_d979b543',
              'pricing_option_id': 'cpm_usd_auction',
              'format_ids': [{
                  'agent_url': 'https://creative.adcontextprotocol.org',
                  'id': 'display_300x250_image'
              }],
              'budget': 2500,
              'bid_price': 5.00,
              'targeting_overlay': {
                  'geo_countries': ['US'],
                  'geo_regions': ['US-CA', 'US-NY'],
                  'frequency_cap': {
                      'suppress': {'interval': 60, 'unit': 'minutes'}
                  }
              }
          }],
          start_time='asap',
          end_time=end_date.isoformat().replace('+00:00', 'Z')
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Creation failed: {result.errors}")

      print(f"Campaign {result.media_buy_id} created with targeting")

  asyncio.run(create_targeted_campaign())
  ```
</CodeGroup>

### コンバージョン最適化付きキャンペーン

コンバージョン最適化配信のために per\_ad\_spend ターゲットを設定します。プロダクトが `conversion_tracking.supported_targets` でサポートを宣言しており、`sync_event_sources` 経由でイベントソースが設定済みである必要があります:

<CodeGroup>
  ```javascript JavaScript test=false theme={null}
  import { testAgent } from '@adcp/sdk/testing';
  import { CreateMediaBuyResponseSchema } from '@adcp/sdk';

  const endDate = new Date();
  endDate.setDate(endDate.getDate() + 90);

  const result = await testAgent.createMediaBuy({
    brand: {
      domain: 'acmecorp.com'
    },
    packages: [{
      product_id: 'prod_retail_sp',
      pricing_option_id: 'cpc_usd_auction',
      budget: 10000,
      bid_price: 1.20,
      optimization_goals: [{
        kind: 'event',
        event_sources: [
          { event_source_id: 'retailer_sales', event_type: 'purchase', value_field: 'value' }
        ],
        target: { kind: 'per_ad_spend', value: 4.0 },
        priority: 1
      }]
    }],
    start_time: 'asap',
    end_time: endDate.toISOString()
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = CreateMediaBuyResponseSchema.parse(result.data);
  if ('errors' in validated && validated.errors) {
    throw new Error(`Creation failed: ${JSON.stringify(validated.errors)}`);
  }

  if ('media_buy_id' in validated) {
    console.log(`Campaign ${validated.media_buy_id} created with per_ad_spend target`);
  }
  ```

  ```python Python test=false theme={null}
  import asyncio
  import time
  from datetime import datetime, timedelta, timezone
  from adcp.testing import test_agent

  async def create_optimized_campaign():
      end_date = datetime.now(timezone.utc) + timedelta(days=90)

      result = await test_agent.simple.create_media_buy(
          brand={
              'domain': 'acmecorp.com'
          },
          packages=[{
              'product_id': 'prod_retail_sp',
              'pricing_option_id': 'cpc_usd_auction',
              'budget': 10000,
              'bid_price': 1.20,
              'optimization_goals': [{
                  'kind': 'event',
                  'event_sources': [
                      { 'event_source_id': 'retailer_sales', 'event_type': 'purchase', 'value_field': 'value' }
                  ],
                  'target': { 'kind': 'per_ad_spend', 'value': 4.0 },
                  'priority': 1
              }]
          }],
          start_time='asap',
          end_time=end_date.isoformat().replace('+00:00', 'Z')
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Creation failed: {result.errors}")

      print(f"Campaign {result.media_buy_id} created with per_ad_spend target")

  asyncio.run(create_optimized_campaign())
  ```
</CodeGroup>

### カタログ連動パッケージ

カタログ連動パッケージは、カタログ全体のアイテムに対して単一の予算枠を割り当てます。アイテムごとにパッケージを個別作成する代わりに、プラットフォームがパフォーマンスに基づいてカタログ全アイテムへの配信を最適化します。これは Google Performance Max や Meta Dynamic Product Ads などのカタログベースのキャンペーンタイプに相当する AdCP の機能です。

パッケージにカタログ連動を設定するには `catalogs` フィールドを含めます。各カタログはそれぞれ異なるタイプ（例：プロダクトカタログ 1 件、ストアカタログ 1 件）を持つ必要があります。参照するカタログは [`sync_catalogs`](/docs/media-buy/task-reference/sync_catalogs) 経由で事前に同期されている必要があります。

**同期済みジョブカタログを使ったジョブキャンペーン:**

```json test=false theme={null}
{
  "brand": { "domain": "acme-restaurants.com" },
  "packages": [{
    "product_id": "prod_job_board",
    "pricing_option_id": "cpc_eur_auction",
    "budget": 5000,
    "bid_price": 2.50,
    "catalogs": [{
      "catalog_id": "chef-vacancies",
      "type": "job"
    }]
  }],
  "start_time": "asap",
  "end_time": "2026-06-30T23:59:59Z"
}
```

**プロダクトカタログとストア集客圏ターゲティングを使ったリテールメディア:**

```json test=false theme={null}
{
  "brand": { "domain": "acmecorp.com" },
  "packages": [{
    "product_id": "prod_retail_sp",
    "pricing_option_id": "cpc_usd_auction",
    "budget": 10000,
    "bid_price": 1.20,
    "catalogs": [{
      "catalog_id": "gmc-primary",
      "type": "product",
      "tags": ["summer"]
    }],
    "targeting_overlay": {
      "store_catchments": [{
        "catalog_id": "retail-locations",
        "catchment_ids": ["drive"]
      }]
    }
  }],
  "start_time": "asap",
  "end_time": "2026-09-30T23:59:59Z"
}
```

プラットフォームはパフォーマンスに基づいてカタログアイテム間で予算を配分します。アイテムごとのレポートには、`by_catalog_item` ブレークダウンを返す [`get_media_buy_delivery`](/docs/media-buy/task-reference/get_media_buy_delivery) を使用します。カタログ連動パッケージのクリエイティブバリアントは、広告としてレンダリングされた個別のカタログアイテムを表します。

**明示的なシグナルターゲティング付きパッケージ:**

バイヤーがセラー提供のシグナルを特定のパッケージに適用したい場合は `targeting_overlay.signal_targeting_groups` を使います。選択したプロダクトは `signal_targeting_allowed: true` を設定し、シグナルを適格にしなければなりません——インラインの `signal_targeting_options`（存在する場合）、インラインオプションを省略するホールセールプロダクトには `get_signals`、そして `signal_targeting_rules` を通じて。常にグループ化された式の形状を使います: トップレベルの `operator: "all"` と、include グループには `operator: "any"`、除外グループには `operator: "none"` を使う子グループ。単純な include のみのターゲティングには一つの `any` グループを送ります。バイナリシグナルでは、include と除外の両グループで `value: true` を送ります。除外は `value: false` ではなく親の `none` グループで表現します。シグナルは `signal_ref` で参照します: プロダクトローカルのシグナルオプションには `scope: "product"`、データプロバイダーが公開する adagents.json の `signals[]` で定義されたシグナルには `data_provider_domain` を伴う `scope: "data_provider"`、ソースネイティブなシグナルには `signal_source_url` を伴う `scope: "signal_source"`。これは、`sync_audiences` を通じて登録されたファーストパーティオーディエンスのみを参照する `audience_include` / `audience_exclude` とは別物です。`signal_agent_segment_id` は、選択したプロダクトオプションまたは `get_signals` の結果が、セラーが要求する別個の実行ハンドルとしてそれを公開した場合にのみ送ります。

クリエイティブがビルド時の `signal_condition`（`build_creative` の `signal_conditions` ファンアウト由来、[#5240](https://github.com/adcontextprotocol/adcp/issues/5240)）を運ぶ場合、シグナルターゲティングが非互換なパッケージへの割り当て——例: 晴れのクリエイティブを雨ターゲットのパッケージへ——は `SIGNAL_TARGETING_INCOMPATIBLE` で拒否されます。互換性は、ここで使われる同じ共有 `signal_ref` アイデンティティで照合されます。規範的なトラフィッキング互換性契約は[シグナル仕様](/docs/signals/specification#creative-signal-fan-out-and-trafficking-compatibility)を参照してください。

```json test=false theme={null}
{
  "brand": { "domain": "acmecorp.com" },
  "packages": [{
    "product_id": "retail_video_premium",
    "pricing_option_id": "media_cpm_usd",
    "budget": 25000,
    "targeting_overlay": {
      "signal_targeting_groups": {
        "operator": "all",
        "groups": [{
          "operator": "any",
          "signals": [{
            "signal_ref": {
              "scope": "data_provider",
              "data_provider_domain": "pinnacle-data.example",
              "signal_id": "auto_intenders"
            },
            "value_type": "binary",
            "value": true,
            "pricing_option_id": "signal_cpm_usd_250",
            "signal_agent_segment_id": "seller_sig_auto_intenders"
          }]
        }]
      }
    }
  }],
  "start_time": "asap",
  "end_time": "2026-09-30T23:59:59Z"
}
```

include と除外を組み合わせた例:

```json test=false theme={null}
{
  "brand": { "domain": "acmecorp.com" },
  "packages": [{
    "product_id": "retail_video_premium",
    "pricing_option_id": "media_cpm_usd",
    "budget": 25000,
    "targeting_overlay": {
      "signal_targeting_groups": {
        "operator": "all",
        "groups": [
          {
            "operator": "any",
            "signals": [
              {
                "signal_ref": { "scope": "product", "signal_id": "high_intent_shoppers" },
                "value_type": "binary",
                "value": true
              },
              {
                "signal_ref": { "scope": "product", "signal_id": "loyalty_members" },
                "value_type": "binary",
                "value": true
              }
            ]
          },
          {
            "operator": "none",
            "signals": [
              {
                "signal_ref": { "scope": "product", "signal_id": "recent_purchasers" },
                "value_type": "binary",
                "value": true
              }
            ]
          }
        ]
      }
    }
  }],
  "start_time": "asap",
  "end_time": "2026-09-30T23:59:59Z"
}
```

### クリエイティブをインライン指定したキャンペーン

キャンペーン作成と同時にクリエイティブをアップロードします:

<CodeGroup>
  ```javascript JavaScript test=false theme={null}
  import { testAgent } from '@adcp/sdk/testing';
  import { CreateMediaBuyResponseSchema } from '@adcp/sdk';

  // Calculate end date dynamically - 90 days from now
  const endDate = new Date();
  endDate.setDate(endDate.getDate() + 90);

  const result = await testAgent.createMediaBuy({
    brand: {
      domain: 'acmecorp.com'
    },
    packages: [{
      product_id: 'prod_d979b543',
      pricing_option_id: 'cpm_usd_auction',
      format_ids: [{
        agent_url: 'https://creative.adcontextprotocol.org',
        id: 'display_300x250_image'
      }],
      budget: 2500,
      bid_price: 5.00,
      creatives: [{
        creative_id: 'hero_video_30s',
        name: 'Hero Video',
        format_id: {
          agent_url: 'https://creative.adcontextprotocol.org',
          id: 'display_300x250_image'
        },
        assets: {
          image: {
            url: 'https://cdn.example.com/hero-banner.jpg',
            width: 300,
            height: 250
          }
        }
      }]
    }],
    start_time: 'asap',
    end_time: endDate.toISOString()
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = CreateMediaBuyResponseSchema.parse(result.data);
  if ('errors' in validated && validated.errors) {
    throw new Error(`Creation failed: ${JSON.stringify(validated.errors)}`);
  }

  if ('packages' in validated) {
    console.log(`Campaign created with ${validated.packages[0].creative_assignments.length} creatives`);
  }
  ```

  ```python Python test=false theme={null}
  import asyncio
  import time
  from datetime import datetime, timedelta, timezone
  from adcp.testing import test_agent

  async def create_with_creatives():
      # Calculate end date dynamically - 90 days from now
      end_date = datetime.now(timezone.utc) + timedelta(days=90)

      result = await test_agent.simple.create_media_buy(
          brand={
              'domain': 'acmecorp.com'
          },
          packages=[{
              'product_id': 'prod_d979b543',
              'pricing_option_id': 'cpm_usd_auction',
              'format_ids': [{
                  'agent_url': 'https://creative.adcontextprotocol.org',
                  'id': 'display_300x250_image'
              }],
              'budget': 2500,
              'bid_price': 5.00,
              'creatives': [{
                  'creative_id': 'hero_video_30s',
                  'name': 'Hero Video',
                  'format_id': {
                      'agent_url': 'https://creative.adcontextprotocol.org',
                      'id': 'display_300x250_image'
                  },
                  'assets': {
                      'image': {
                          'url': 'https://cdn.example.com/hero-banner.jpg',
                          'width': 300,
                          'height': 250
                      }
                  }
              }]
          }],
          start_time='asap',
          end_time=end_date.isoformat().replace('+00:00', 'Z')
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Creation failed: {result.errors}")

      print(f"Campaign created with {len(result.packages[0].creative_assignments)} creatives")

  asyncio.run(create_with_creatives())
  ```
</CodeGroup>

### レポート用 Webhook を設定したキャンペーン

自動レポート通知を受け取ります。

<CodeGroup>
  ```javascript JavaScript test=false theme={null}
  import { testAgent } from '@adcp/sdk/testing';
  import { CreateMediaBuyResponseSchema } from '@adcp/sdk';

  // Calculate end date dynamically - 90 days from now
  const endDate = new Date();
  endDate.setDate(endDate.getDate() + 90);

  const result = await testAgent.createMediaBuy({
    brand: {
      domain: 'acmecorp.com'
    },
    packages: [{
      product_id: 'prod_d979b543',
      pricing_option_id: 'cpm_usd_auction',
      format_ids: [{
        agent_url: 'https://creative.adcontextprotocol.org',
        id: 'display_300x250_image'
      }],
      budget: 2500,
      bid_price: 5.00
    }],
    start_time: 'asap',
    end_time: endDate.toISOString(),
    reporting_webhook: {
      url: 'https://buyer.example.com/webhooks/reporting',
      authentication: {
        schemes: ['Bearer'],
        credentials: 'secret_token_xyz_minimum_32_chars'
      },
      reporting_frequency: 'daily',
      requested_metrics: ['impressions', 'spend', 'video_completions']
    }
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = CreateMediaBuyResponseSchema.parse(result.data);
  if ('errors' in validated && validated.errors) {
    throw new Error(`Creation failed: ${JSON.stringify(validated.errors)}`);
  }

  if ('media_buy_id' in validated) {
    console.log(`Campaign created - daily reports will be sent to webhook`);
  }
  ```

  ```python Python test=false theme={null}
  import asyncio
  import time
  from datetime import datetime, timedelta, timezone
  from adcp.testing import test_agent

  async def create_with_reporting():
      # Calculate end date dynamically - 90 days from now
      end_date = datetime.now(timezone.utc) + timedelta(days=90)

      result = await test_agent.simple.create_media_buy(
          brand={
              'domain': 'acmecorp.com'
          },
          packages=[{
              'product_id': 'prod_d979b543',
              'pricing_option_id': 'cpm_usd_auction',
              'format_ids': [{
                  'agent_url': 'https://creative.adcontextprotocol.org',
                  'id': 'display_300x250_image'
              }],
              'budget': 2500,
              'bid_price': 5.00
          }],
          start_time='asap',
          end_time=end_date.isoformat().replace('+00:00', 'Z'),
          reporting_webhook={
              'url': 'https://buyer.example.com/webhooks/reporting',
              'authentication': {
                  'schemes': ['Bearer'],
                  'credentials': 'secret_token_xyz_minimum_32_chars'
              },
              'reporting_frequency': 'daily',
              'requested_metrics': ['impressions', 'spend', 'video_completions']
          }
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Creation failed: {result.errors}")

      print('Campaign created - daily reports will be sent to webhook')

  asyncio.run(create_with_reporting())
  ```
</CodeGroup>

### プロポーザルの実行

`get_products` のプロポーザルを、パッケージを手作業で組まずに実行します。

<CodeGroup>
  ```javascript JavaScript test=false theme={null}
  import { testAgent } from '@adcp/sdk/testing';
  import { CreateMediaBuyResponseSchema } from '@adcp/sdk';

  // Calculate end date dynamically - 90 days from now
  const endDate = new Date();
  endDate.setDate(endDate.getDate() + 90);

  const result = await testAgent.createMediaBuy({
    proposal_id: 'swiss_balanced_v1',  // From get_products response
    total_budget: {
      amount: 50000,
      currency: 'USD'
    },
    brand: {
      domain: 'acmecorp.com'
    },
    start_time: 'asap',
    end_time: endDate.toISOString()
  });

  if (!result.success) {
    throw new Error(`Request failed: ${result.error}`);
  }

  const validated = CreateMediaBuyResponseSchema.parse(result.data);
  if ('errors' in validated && validated.errors) {
    throw new Error(`Creation failed: ${JSON.stringify(validated.errors)}`);
  }

  if ('media_buy_id' in validated) {
    // パブリッシャーがプロポーザルの配分をパッケージに変換
    console.log(`Created media buy ${validated.media_buy_id}`);
    console.log(`Packages created: ${validated.packages.length}`);
  }
  ```

  ```python Python test=false theme={null}
  import asyncio
  import time
  from datetime import datetime, timedelta, timezone
  from adcp.testing import test_agent

  async def execute_proposal():
      # Calculate end date dynamically - 90 days from now
      end_date = datetime.now(timezone.utc) + timedelta(days=90)

      result = await test_agent.simple.create_media_buy(
          proposal_id='swiss_balanced_v1',  # From get_products response
          total_budget={
              'amount': 50000,
              'currency': 'USD'
          },
          brand={
              'domain': 'acmecorp.com'
          },
          start_time='asap',
          end_time=end_date.isoformat().replace('+00:00', 'Z')
      )

      if hasattr(result, 'errors') and result.errors:
          raise Exception(f"Creation failed: {result.errors}")

      # パブリッシャーがプロポーザルの配分をパッケージに変換
      print(f"Created media buy {result.media_buy_id}")
      print(f"Packages created: {len(result.packages)}")

  asyncio.run(execute_proposal())
  ```
</CodeGroup>

プロポーザルを実行する際:

* パブリッシャーが `total_budget` を使って配分割合を実額に変換
* 配分に基づきパッケージが自動生成
* それ以外のフィールド（brand、start\_time、end\_time など）は Manual モードと同じ

会話的なリファインを含む完全なフローは [Proposals](/docs/media-buy/product-discovery/media-products#proposals) を参照。

### 相関のための Context

`context` フィールドは、セラーがレスポンスと Webhook でそのまま返す不透明なオブジェクトです。別個のルックアップテーブルを維持することなく、セラーが割り当てた ID を自分の内部システムにマッピングするために使います。

Context は二つのレベルで機能します:

* **メディアバイレベル** — `create_media_buy` レスポンスでエコーされる
* **パッケージレベル** — 各パッケージのレスポンス、Webhook、読み取り面でエコーされ、`package_id` を内部ラインアイテムにマッピングするのに有用。明示的なパッケージリクエストでは、セラーは `product_id` もエコーしなければなりません（MUST）。

混在したセラー集団を対象とする場合、`product_id` をエコーしないかもしれない古いセラーのためのレガシーセーフなフォールバックとして、`context.buyer_ref` のようなパッケージ context を含めます。

**内部のキャンペーン ID・ラインアイテム ID へのマッピング:**

```json test=false theme={null}
{
  "brand": { "domain": "acmecorp.com" },
  "context": {
    "campaign_id": "camp-2026-q3-awareness",
    "planner": "media-team-west",
    "trace_id": "req-8f3a-4b2c"
  },
  "packages": [
    {
      "product_id": "prod_d979b543",
      "pricing_option_id": "cpm_usd_auction",
      "budget": 15000,
      "bid_price": 5.00,
      "context": {
        "line_item_id": "li-001",
        "flight": "june-awareness"
      }
    },
    {
      "product_id": "prod_e8fd6012",
      "pricing_option_id": "cpm_usd_auction",
      "budget": 10000,
      "bid_price": 4.50,
      "context": {
        "line_item_id": "li-002",
        "flight": "june-retargeting"
      }
    }
  ],
  "start_time": "2026-06-01T00:00:00Z",
  "end_time": "2026-08-31T23:59:59Z"
}
```

セラーのレスポンスは、セラーが割り当てた ID と並べて context を返します:

```json test=false theme={null}
{
  "media_buy_id": "mb_12345",
  "context": {
    "campaign_id": "camp-2026-q3-awareness",
    "planner": "media-team-west",
    "trace_id": "req-8f3a-4b2c"
  },
  "packages": [
    {
      "package_id": "pkg_001",
      "product_id": "prod_d979b543",
      "context": {
        "line_item_id": "li-001",
        "flight": "june-awareness"
      }
    },
    {
      "package_id": "pkg_002",
      "product_id": "prod_e8fd6012",
      "context": {
        "line_item_id": "li-002",
        "flight": "june-retargeting"
      }
    }
  ]
}
```

セラーは context データをパースしたり、それに基づいて動作したりしてはなりません——これは純粋にバイヤーの内部利用のために存在します。

## エラーハンドリング

よくあるエラーと解決策:

| Error Code               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | Resolution                                                                                                                                                                                                                                  |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PRODUCT_NOT_FOUND`      | Invalid product\_id                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Verify product exists via `get_products`                                                                                                                                                                                                    |
| `UNSUPPORTED_FEATURE`    | Format not supported by the product — covers legacy named-format selectors (`format_ids[]` not in the product's accepted formats), 3.1+ format-option selectors (`format_option_refs[]` entries that do not resolve against the product's `format_options[]`, legacy-format-only products with no `format_options[]`, or product `format_options[]` entries that do not publish selectable `format_option_id` values), and direct canonical selectors (`format_kind`/`params` outside or under-specifying the product declaration) | Check the product's `format_ids` and/or `format_options[]` from `get_products` — re-author against a supported format, add the required canonical parameters, or pick a `format_option_ref` from the product's published `format_options[]` |
| `BUDGET_TOO_LOW`         | Budget below product minimum                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Increase budget or choose different product                                                                                                                                                                                                 |
| `TARGETING_TOO_NARROW`   | Targeting yields zero inventory                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Broaden geographic or audience criteria                                                                                                                                                                                                     |
| `POLICY_VIOLATION`       | Brand/product violates policy                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Review publisher's content policies                                                                                                                                                                                                         |
| `INVALID_PRICING_OPTION` | pricing\_option\_id not found                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Use ID from product's `pricing_options`                                                                                                                                                                                                     |
| `CREATIVE_ID_EXISTS`     | Creative ID already exists in the seller's creative namespace                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | For library-backed sellers, assign existing creatives via `creative_assignments` or update via `sync_creatives`; for inline-only sellers, use a different package-scoped `creative_id`                                                      |

Example error response:

```json theme={null}
{
  "errors": [{
    "code": "UNSUPPORTED_FEATURE",
    "message": "Product 'prod_d979b543' does not support format 'display_728x90'",
    "field": "packages[0].format_ids[0]",
    "suggestion": "Use display_300x250_image, display_300x250_html, or display_300x250_generative formats"
  }]
}
```

## Key Concepts

### フォーマット指定

各パッケージは、使用するフォーマットを `format_ids[]`（レガシーの名前付きフォーマットパス——構造化された `{agent_url, id}` 参照）、`format_option_refs[]`（3.1 以降のフォーマットオプションパス——プロダクトの `format_options[]` への参照）、または直接の正準セレクター（`format_kind` と任意の `params`）で指定すべきです（SHOULD）。すべてのフォーマットセレクターを省略すると、プロダクトがサポートするすべてのフォーマットがデフォルトになります。指定することで、システムは次を行えます:

* アドサーバーにプレースホルダークリエイティブを公開する
* 必要なクリエイティブアセットを正確にピン留めする
* プロダクトが要求フォーマットをサポートするか検証する
* 不足しているアセットを追跡する

セレクターの優先順位は決定的です: `format_option_refs[]` が存在すればそれが勝ち、なければ `format_ids[]` が存在すればそれが勝ち、なければ直接の `format_kind`/`params` が使われ、それもなければパッケージはすべてのプロダクトフォーマットにデフォルトします。バイヤーのコードベースが `Product.format_options[]` を読み、プロダクトが選択可能な `format_option_id` 値を公開する場合は `format_option_refs[]` を使います。レガシーフォーマットのみのセラーやライブラリと統合する場合は `format_ids[]` を使います。直接の `format_kind` は、バイヤーがプロダクトローカルの参照なしで対象プロダクト宣言を満たすのに十分な正準パラメータを持つ場合にのみ使います。`format_option_refs[]` と `format_ids[]` の二重出力は許可され、混在したセラー集団を対象とするバイヤー SDK には推奨されます——上記の `format_ids` 行を参照。

3.1 以降のフォーマットオプションの例（パブリッシャースコープの `Product.format_options[]` エントリに対してバイヤーが作成する場合）:

```json test=false theme={null}
{
  "packages": [
    {
      "product_id": "prod_d979b543",
      "pricing_option_id": "cpm_usd_auction",
      "format_option_refs": [
        {
          "scope": "publisher",
          "publisher_domain": "daily-pulse.example",
          "format_option_id": "daily_pulse_homepage_image"
        }
      ],
      "budget": 2500,
      "bid_price": 5.00
    }
  ]
}
```

詳細は下記の [フォーマットワークフロー](#format-workflow) を参照。

### ブランド参照

`brand` フィールドはポリシー準拠とビジネス目的のために広告主を識別します。

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

ブランドの完全なアイデンティティデータ（色、フォント、プロダクトカタログ）は実行時に brand.json から解決されます。[brand.json](/docs/brand-protocol/brand-json) を参照。

### 価格と通貨

各パッケージは `pricing_option_id` を指定し、以下を決定します:

* 通貨（USD、EUR など）
* 価格モデル（CPM、CPCV、CPP など）
* レートと固定/オークションの区別

セラーがサポートする場合、パッケージごとに異なる通貨を使用できます。[Pricing Models](/docs/media-buy/advanced-topics/pricing-models) 参照。

### ターゲティングオーバーレイ

**使用は最小限に** — ターゲティングの大部分はブリーフに含め、プロダクト選択で処理されるべきです。

オーバーレイは以下に限定して使用します:

* 地理的制限（RCT テスト、規制対応）
* フリークエンシーキャップ
* AXE セグメントの包含/除外（レガシー——新規統合は [TMP](/docs/trusted-match) を使用）

詳細は [Targeting](/docs/media-buy/advanced-topics/targeting) を参照。

## フォーマットワークフロー

### フォーマット指定が重要な理由

メディアバイ作成時にフォーマットを指定すると次が可能になります:

1. **プレースホルダー作成** - パブリッシャーが正しい仕様でアドサーバーにプレースホルダーを用意
2. **検証** - 要求フォーマットをプロダクトがサポートするかシステムが検証
3. **期待値の明確化** - 双方が必要なものを正確に把握
4. **進捗トラッキング** - 不足アセットと必須アセットを可視化
5. **技術セットアップ** - クリエイティブ到着前にアドサーバーを設定

### 完全なワークフロー

```
1. list_creative_formats → 利用可能なフォーマット仕様を取得
2. get_products → プロダクトを発見（サポートする format_ids[] および/または format_options[] を返す）
3. 互換性を検証 → 望むフォーマットをプロダクトがサポートするか確認
4. create_media_buy → フォーマットを format_ids[]（v1）、
                       format_option_refs[]（v2 参照）、または
                       format_kind/params（直接正準）で指定;
                       省略すると all-formats デフォルト
   └── パブリッシャーがプレースホルダーを作成
   └── クリエイティブ要件を明確化
5. クリエイティブ提供 → ライブラリ対応セラーには `sync_creatives`、
   インライン専用セラーにはインラインの `packages[].creatives` で
   合致するファイルをアップロード
6. キャンペーン有効化 → プレースホルダーを実クリエイティブに置換
```

### フォーマット検証

パブリッシャーが必ず検証する事項:

* すべてのフォーマットがプロダクトでサポートされています
* フォーマット仕様が `list_creative_formats` の出力と一致
* 期限内にクリエイティブ要件を満たせる

無効なレガシー名前付きフォーマットの例:

```json theme={null}
{
  "errors": [{
    "code": "UNSUPPORTED_FEATURE",
    "message": "Product 'ctv_sports_premium' does not support format 'audio_standard_30s'",
    "field": "packages[0].format_ids[0]",
    "supported_formats": [
      { "agent_url": "https://creative.adcontextprotocol.org", "id": "video_standard_30s" },
      { "agent_url": "https://creative.adcontextprotocol.org", "id": "video_standard_15s" }
    ]
  }]
}
```

無効な 3.1 以降のフォーマットオプションの例:

```json theme={null}
{
  "errors": [{
    "code": "UNSUPPORTED_FEATURE",
    "message": "Product 'ctv_sports_premium' has no format_options[] entry for format option 'audio_standard'",
    "field": "packages[0].format_option_refs[0]",
    "supported_format_option_refs": [
      { "scope": "publisher", "publisher_domain": "streamhaus.example", "format_option_id": "ctv_video_30s_premium" },
      { "scope": "publisher", "publisher_domain": "streamhaus.example", "format_option_id": "ctv_video_15s_premium" }
    ]
  }]
}
```

### フライト日程バリデーション

新規メディアバイでは、トップレベルの `start_time` は `"asap"` か、過去でない日時のいずれかでなければなりません（MUST）。過去の具体的な `start_time` は `INVALID_REQUEST` エラーを返さなければなりません（MUST）。

パッケージに `start_time` または `end_time` を指定した場合、セラーは以下を検証すべきだ:

* 両日程がメディアバイの日付範囲内に収まっています
* `start_time` が `end_time` より前です

範囲外または逆転した日程は `INVALID_REQUEST` エラーを返すべきだ:

```json theme={null}
{
  "errors": [{
    "code": "INVALID_REQUEST",
    "message": "Package 'week_5' end_time 2026-04-05T23:59:59Z is after media buy end_time 2026-03-31T23:59:59Z",
    "field": "packages[3].end_time"
  }]
}
```

## 非同期オペレーション

このタスクは即時完了する場合も、複雑さや承認要件によっては日数を要する場合もあります。レスポンスの `status` フィールドで結果と次のアクションを確認してください。

| Status           | Meaning    | Your Action              |
| ---------------- | ---------- | ------------------------ |
| `completed`      | 即時完了       | 結果を処理                    |
| `working`        | 処理中（約2分）   | 高頻度でポーリング or Webhook を待つ |
| `submitted`      | 長時間（数時間〜日） | Webhook を使うか低頻度でポーリング    |
| `input-required` | 追加情報が必要    | メッセージを読み、情報を返す           |
| `failed`         | エラー発生      | エラーに対応                   |

**Note:** 完全なステータス一覧は [Task Lifecycle](/docs/building/by-layer/L3/task-lifecycle) を参照。

<Tabs>
  <Tab title="MCP">
    ### 即時成功 (`completed`)

    タスクが同期的に完了しました。非同期処理は不要です。

    **Request:**

    ```javascript test=false theme={null}
    const response = await session.call('create_media_buy', {
      brand: { domain: 'acmecorp.com' },
      packages: [
        {
          product_id: 'prod_ctv_sports',
          pricing_option_id: 'cpm_fixed',
          budget: 50000
        }
      ]
    });
    ```

    **Response:**

    ```json theme={null}
    {
      "status": "completed",
      "media_buy_id": "mb_12345",
      "account": {
        "account_id": "acc_acme_direct",
        "name": "Acme",
        "status": "active",
        "brand": { "domain": "acmecorp.com" },
        "operator": "acmecorp.com"
      },
      "media_buy_status": "active",
      "confirmed_at": "2025-06-01T10:00:00Z",
      "creative_deadline": "2025-06-15T23:59:59Z",
      "revision": 1,
      "packages": [
        {
          "package_id": "pkg_001",
          "product_id": "prod_ctv_sports"
        }
      ]
    }
    ```

    トップレベルの `status` はエンベロープのタスクステータス（TaskStatus）です——同期成功では `completed`。ボディレベルの `media_buy_status` は購入のライフサイクル状態（`pending_creatives`、`pending_start`、`active`、`paused`）を運びます。3.0 形式のレスポンスはこの二つの列挙を同じルートキーで衝突させていました。3.1 ではこれらは別々のフィールドです。セラーは、3.0 バイヤーとの後方互換のため 3.1 非推奨期間中に非推奨のトップレベル `status: MediaBuyStatus` を出し続けてもよい（MAY）が、3.1 バイヤーは `media_buy_status` を優先しなければなりません（MUST）。下記の [メディアバイステータスフィールド（3.1 移行）](#media-buy-status-field-3-1-migration) を参照。

    ### 長時間処理 (`submitted`)

    タスクが手動承認キューに入っています。更新を受け取るため Webhook を設定します。

    **Request with webhook:**

    ```javascript test=false theme={null}
    const response = await session.call('create_media_buy',
      {
        brand: { domain: 'acmecorp.com' },
        packages: [
          {
            product_id: 'prod_premium_ctv',
            pricing_option_id: 'cpm_fixed',
            budget: 500000  // Large budget triggers approval
          }
        ]
      },
      {
        pushNotificationConfig: {
          url: 'https://your-app.com/webhooks/adcp',
          authentication: {
            schemes: ['bearer'],
            credentials: 'your_webhook_secret'
          }
        }
      }
    );
    ```

    **Initial response:**

    ```json theme={null}
    {
      "status": "submitted",
      "task_id": "task_abc123",
      "message": "Budget exceeds auto-approval limit. Sales review required (2-4 hours)."
    }
    ```

    **Webhook POST when approved:**

    ```json theme={null}
    {
      "task_id": "task_abc123",
      "task_type": "create_media_buy",
      "status": "completed",
      "timestamp": "2025-01-22T14:30:00Z",
      "message": "Media buy approved and created",
      "result": {
        "media_buy_id": "mb_67890",
        "creative_deadline": "2025-06-20T23:59:59Z",
        "packages": [
          {
            "package_id": "pkg_002",
          }
        ]
      }
    }
    ```

    ### Error (`failed`)

    **Response:**

    ```json theme={null}
    {
      "status": "failed",
      "errors": [
        {
          "code": "INSUFFICIENT_INVENTORY",
          "message": "Requested targeting yields no available impressions",
          "field": "packages[0].targeting",
          "suggestion": "Expand geographic targeting or increase CPM bid"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="A2A">
    ### 即時成功 (`completed`)

    **Request:**

    ```javascript test=false theme={null}
    const response = await a2a.send({
      message: {
        parts: [{
          kind: 'data',
          data: {
            skill: 'create_media_buy',
            parameters: {
              brand: { domain: 'acmecorp.com' },
              packages: [
                {
                  product_id: 'prod_ctv_sports',
                  pricing_option_id: 'cpm_fixed',
                  budget: 50000
                }
              ]
            }
          }
        }]
      }
    });
    ```

    **Response:**

    ```json theme={null}
    {
      "status": "completed",
      "taskId": "task_123",
      "contextId": "ctx_456",
      "artifacts": [{
        "parts": [
          { "text": "Media buy created successfully" },
          {
            "data": {
              "media_buy_id": "mb_12345",
              "creative_deadline": "2025-06-15T23:59:59Z",
              "packages": [
                {
                  "package_id": "pkg_001",
                }
              ]
            }
          }
        ]
      }]
    }
    ```

    ### 処理中 (`working`)

    タスクが処理中です。SSE ストリーミングまたはポーリングで更新を取得します。

    **Initial response:**

    ```json theme={null}
    {
      "status": "working",
      "taskId": "task_789",
      "contextId": "ctx_456"
    }
    ```

    **SSE status update:**

    ```json theme={null}
    {
      "taskId": "task_789",
      "status": {
        "state": "working",
        "message": {
          "parts": [
            { "text": "Validating inventory availability..." },
            {
              "data": {
                "percentage": 50,
                "current_step": "inventory_check"
              }
            }
          ]
        }
      }
    }
    ```

    ### 長時間処理 (`submitted`)

    **Request with push notification:**

    ```javascript test=false theme={null}
    const response = await a2a.send({
      message: {
        parts: [{
          kind: 'data',
          data: {
            skill: 'create_media_buy',
            parameters: {
              packages: [{ budget: 500000 }]  // Triggers approval
            }
          }
        }]
      },
      pushNotificationConfig: {
        url: 'https://your-app.com/webhooks/a2a',
        authentication: {
          schemes: ['bearer'],
          credentials: 'your_webhook_secret'
        }
      }
    });
    ```

    **Initial response:**

    ```json theme={null}
    {
      "status": "submitted",
      "taskId": "task_abc",
      "contextId": "ctx_456"
    }
    ```

    **Webhook POST (Task) when completed:**

    ```json theme={null}
    {
      "id": "task_abc",
      "contextId": "ctx_456",
      "status": {
        "state": "completed",
        "message": {
          "parts": [
            { "text": "Media buy approved and created" },
            {
              "data": {
                "media_buy_id": "mb_67890",
                "packages": [{ "package_id": "pkg_002" }]
              }
            }
          ]
        },
        "timestamp": "2025-01-22T14:30:00Z"
      }
    }
    ```

    ### 入力要求 (`input-required`)

    タスクが確認または承認待ちで一時停止しています。

    **Response:**

    ```json theme={null}
    {
      "status": "input-required",
      "taskId": "task_def",
      "contextId": "ctx_456",
      "artifacts": [{
        "parts": [
          { "text": "The requested budget exceeds your pre-approved limit. Please confirm you want to proceed with $500K spend." },
          {
            "data": {
              "reason": "APPROVAL_REQUIRED",
              "errors": [
                {
                  "code": "BUDGET_EXCEEDS_LIMIT",
                  "message": "Requested budget exceeds pre-approved limit",
                  "field": "total_budget"
                }
              ]
            }
          }
        ]
      }]
    }
    ```

    **Follow-up to approve:**

    ```javascript test=false theme={null}
    await a2a.send({
      contextId: 'ctx_456',  // Continue the conversation
      message: {
        parts: [{ kind: 'text', text: 'Yes, I confirm the $500K budget' }]
      }
    });
    ```

    ### Error (`failed`)

    **Response:**

    ```json theme={null}
    {
      "status": "failed",
      "taskId": "task_xyz",
      "artifacts": [{
        "parts": [
          { "text": "Failed to create media buy" },
          {
            "data": {
              "errors": [
                {
                  "code": "INSUFFICIENT_INVENTORY",
                  "message": "Requested targeting yields no available impressions",
                  "suggestion": "Expand geographic targeting"
                }
              ]
            }
          }
        ]
      }]
    }
    ```
  </Tab>
</Tabs>

非同期処理の完全なパターンは [Async Operations](/docs/building/by-layer/L3/async-operations) を参照。

## 使用上の注意

* 総予算は各パッケージの個別の `budget` 値に基づいて配分されます
* クリエイティブアセットはキャンペーン有効化のためにデッドライン前にアップロードしなければなりません
* インプレッション時のターゲティング（オーディエンス、フリークエンシー、適合性）は [TMP](/docs/trusted-match) が処理します
* `working`、`submitted` などの保留状態は正常であり、エラーではありません
* オーケストレーターは保留状態を通常のワークフローの一部として処理しなければなりません
* **インラインクリエイティブ**: `creatives` 配列はパッケージのクリエイティブをインラインで作成または提供します。セラーが `creative.has_creative_library: true` を宣言する場合、インラインクリエイティブはライブラリに入ります。既存のライブラリクリエイティブを更新するには [`sync_creatives`](/docs/creative/task-reference/sync_creatives) を、割り当てるには `creative_assignments` を使用。セラーがクリエイティブライブラリなしで `inline_creative_management: true` を宣言する場合、`create_media_buy` と `update_media_buy` で `packages[].creatives` を使い、`sync_creatives` は呼びません。
* **インラインクリエイティブのライフサイクル**: ライブラリ対応のインラインクリエイティブは、`sync_creatives` のアップロードと同じライフサイクルでライブラリに入ります。インライン専用のセラーはクリエイティブをパッケージスコープに保ち、後の `creative_id` による再利用を宣言しないことがあります。クリエイティブレビューは購入の結果とは独立しています。セラーは、購入がアクティベートされなかったというだけでレビューをスキップしてはなりません（MUST NOT）。未割り当てのライブラリクリエイティブの保持は 3.0 ではセラー定義です。[パッケージ上のインラインクリエイティブ](/docs/creative/creative-libraries#path-2-inline-creatives-on-the-package)を参照。

## Content Standards

メディアバイがコンテンツ標準を含む場合（`get_products` レスポンスの `governance.content_standards` フィールド、またはメディアバイリクエスト経由）、バイヤーは配信中のブランド適合性の強制を要求しています。

<Note>
  コンテンツ標準は、検証エージェント（例: IAS、DoubleVerify）で [`create_content_standards`](/docs/governance/content-standards/tasks/create_content_standards) を呼び出すことで作成されます。標準は、セラーのローカル評価モデルが検証エージェントの解釈と整合するよう、本番で使う前に各セラーと[キャリブレーション](/docs/governance/content-standards/tasks/calibrate_content)されなければなりません（MUST）。完全なセットアップワークフロー（create → calibrate → activate → validate）は[コンテンツ標準の概要](/docs/governance/content-standards/index)を参照してください。
</Note>

## ポリシー準拠

ブランドとプロダクトは作成時に検証されます。ポリシー違反はエラーを返します:

```json theme={null}
{
  "errors": [{
    "code": "POLICY_VIOLATION",
    "message": "Brand or product category not permitted on this publisher",
    "field": "brand",
    "suggestion": "Contact publisher for category approval process"
  }]
}
```

パブリッシャーは以下を確認すべきだ:

* ブランド/プロダクトが選択したパッケージと整合しています
* クリエイティブが宣言したブランド/プロダクトと一致しています
* キャンペーンがすべての広告ポリシーに準拠しています

## 次のステップ

メディアバイ作成後:

1. **クリエイティブの提供**: ライブラリ対応のセラーには [`sync_creatives`](/docs/creative/task-reference/sync_creatives) を、インライン専用のセラーには [`update_media_buy`](/docs/media-buy/task-reference/update_media_buy) の `packages[].creatives` を使用
2. **ステータスの監視**: [`get_media_buy_delivery`](/docs/media-buy/task-reference/get_media_buy_delivery) を使用
3. **最適化**: [`provide_performance_feedback`](/docs/media-buy/task-reference/provide_performance_feedback) を使用
4. **更新**: [`update_media_buy`](/docs/media-buy/task-reference/update_media_buy) でキャンペーンを変更

## メディアバイステータスフィールド（3.1 移行）

3.1 は、3.0 が同じルートキーで衝突させていた二つの列挙を分割します——すべてのレスポンスの先頭にあるエンベロープの `status`（TaskStatus）と、購入のライフサイクル状態を並べて運ぶボディの `media_buy_status`（MediaBuyStatus、**3.1 の新機能**）。レガシーのトップレベル `status: MediaBuyStatus` 形式は 3.1 で `deprecated: true` となり、3.2 で削除されます（[#4906](https://github.com/adcontextprotocol/adcp/issues/4906)）。`get_media_buys`、`get_media_buy_delivery`、`core/media-buy.json` のネストされた `status` は 4.0 で続きます（[#4905](https://github.com/adcontextprotocol/adcp/issues/4905)）。

3.1 バイヤーは、存在する場合 `media_buy_status` を優先しなければなりません（MUST）。3.1 コンプライアンスストーリーボードは `path: "media_buy_status"` をアサートします——レガシーの `status` のみを出す 3.1 セラーはスキーマ上有効ですが認定に失敗します。ストーリーボードが拘束的な適合性チェックです。

完全な移行: [移行 › `media_buy_status`](/docs/reference/migration/media-buy-status)。

## 関連ドキュメント

* [Media Buy Lifecycle](/docs/media-buy/media-buys/) - キャンペーンの完全なワークフロー
* [get\_products](/docs/media-buy/task-reference/get_products) - インベントリの発見
* [Targeting](/docs/media-buy/advanced-topics/targeting) - ターゲティング戦略
* [Pricing Models](/docs/media-buy/advanced-topics/pricing-models) - 通貨と価格設定
