Skip to main content
クリエイティブライブラリにクリエイティブアセットをアップロードして管理します。一括アップロード、アップサートセマンティクス、ジェネレーティブクリエイティブをサポートします。クリエイティブライブラリをホストするすべてのエージェント — クリエイティブエージェント(広告サーバー、クリエイティブ管理プラットフォーム)およびクリエイティブを管理するセールスエージェント — が実装します。 レスポンスタイム: 即時〜数日(completed を返すか、数時間/数日かかるレビューのために submitted を返す) リクエストスキーマ: creative/sync-creatives-request.json レスポンススキーマ: creative/sync-creatives-response.json

クイックスタート

クリエイティブアセットをアップロードする:
import { testAgent } from "@adcp/client/testing";
import { SyncCreativesResponseSchema } from "@adcp/client";

const result = await testAgent.syncCreatives({
  creatives: [
    {
      creative_id: "creative_video_001",
      name: "Summer Sale 30s",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "video_standard_30s",
      },
      assets: {
        video: {
          url: "https://cdn.example.com/summer-sale-30s.mp4",
          width: 1920,
          height: 1080,
          duration_ms: 30000,
        },
      },
    },
  ],
});

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

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

// Check for operation-level errors first (discriminated union)
if ("errors" in validated && validated.errors) {
  throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
}

if ("creatives" in validated) {
  console.log(`Synced ${validated.creatives.length} creatives`);
}
注意: クリエイティブに承認が必要な場合、レスポンスは task_id を持つ status: "submitted" を返します。これらのケースの処理については非同期承認ワークフローを参照。

リクエストパラメータ

パラメータタイプ必須説明
accountobjectYesこの同期の広告主/ワークスペースを識別するアカウント参照(account-ref
creativesCreative[]Yesアップロード/更新するクリエイティブアセット(最大100)
creative_idsstring[]No同期スコープを特定のクリエイティブ ID に限定するオプションフィルター。これらのクリエイティブのみが影響を受け、その他はそのまま残る。部分更新とエラー復旧に有用。
assignmentsarrayNo一括アサインメント用の {creative_id, package_id} オブジェクトの配列。アサインメントごとにオプションの weightplacement_ids
dry_runbooleanNotrue の場合、変更を適用せずにプレビューする(デフォルト: false)
validation_modestringNo検証の厳格さ: "strict"(デフォルト)または "lenient"
delete_missingbooleanNotrue の場合、この同期に含まれないクリエイティブはアーカイブされます(デフォルト: false)。creative_ids と組み合わせることはできません。アクティブで一時停止されていないパッケージにアサインされているクリエイティブは削除できません。

クリエイティブオブジェクト

フィールドタイプ必須説明
creative_idstringYesこのクリエイティブの一意の識別子
namestringYes人間が読める名前
format_idFormatIdYesフォーマット仕様(agent_urlid を持つ構造化オブジェクト)
assetsobjectYesロール名をキーとしたアセット(例: {video: {...}, thumbnail: {...}})。カタログは asset_type: "catalog" を持つアセットとして含まれます。カタログを参照。
tagsstring[]Noクリエイティブ整理のための検索可能なタグ

アセット構造

アセットはロール名をキーとします。各ロールにはアセットの詳細が含まれます:
test=false
{
  "assets": {
    "video": {
      "url": "https://cdn.example.com/video.mp4",
      "width": 1920,
      "height": 1080,
      "duration_ms": 30000
    },
    "thumbnail": {
      "url": "https://cdn.example.com/thumb.jpg",
      "width": 300,
      "height": 250
    }
  }
}

アサインメント構造

アサインメントはリクエストレベルにあり、クリエイティブ ID をパッケージ ID にマッピングします。メディアバイを管理しないスタンドアロンのクリエイティブエージェントはこのフィールドを無視します。
test=false
{
  "assignments": [
    { "creative_id": "creative_video_001", "package_id": "pkg_premium" },
    { "creative_id": "creative_video_001", "package_id": "pkg_standard" },
    { "creative_id": "creative_display_002", "package_id": "pkg_standard" }
  ]
}

レスポンス

成功レスポンス:
  • creatives - 処理された各クリエイティブの結果(成功と失敗の両方のアイテムを含む)
  • dry_run - これがドライランだったかどうかを示すブール値(オプション)
エラーレスポンス:
  • errors - 操作レベルのエラーの配列(認証失敗、サービス利用不可)
注意: レスポンスは識別されたユニオンを使用する — 成功フィールドまたはエラーのいずれかを取得し、両方は取得しません。クリエイティブごとのエラーは action: "failed" の場合に個別のクリエイティブオブジェクトの errors 配列に表示されます。 成功レスポンスの各クリエイティブに含まれるもの:
  • すべてのリクエストフィールド
  • platform_id - プラットフォームの内部 ID(actionfailed でない場合)
  • action - 何が起きたか: createdupdatedunchangedfaileddeleted
  • errors - エラーメッセージの配列(action: "failed" の場合のみ)
  • warnings - 非致命的な警告の配列(オプション)
完全なフィールドリストについてはスキーマを参照: sync-creatives-response.json

一般的なシナリオ

一括アップロード

1回の呼び出しで複数のクリエイティブをアップロードする:
import { testAgent } from "@adcp/client/testing";
import { SyncCreativesResponseSchema } from "@adcp/client";

const result = await testAgent.syncCreatives({
  creatives: [
    {
      creative_id: "creative_display_001",
      name: "Summer Sale Banner 300x250",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "display_300x250",
      },
      assets: {
        image: {
          url: "https://cdn.example.com/banner-300x250.jpg",
          width: 300,
          height: 250,
        },
      },
    },
    {
      creative_id: "creative_video_002",
      name: "Product Demo 15s",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "video_standard_15s",
      },
      assets: {
        video: {
          url: "https://cdn.example.com/demo-15s.mp4",
          width: 1920,
          height: 1080,
          duration_ms: 15000,
        },
      },
    },
    {
      creative_id: "creative_display_002",
      name: "Summer Sale Banner 728x90",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "display_728x90",
      },
      assets: {
        image: {
          url: "https://cdn.example.com/banner-728x90.jpg",
          width: 728,
          height: 90,
        },
      },
    },
  ],
});

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

const validated = SyncCreativesResponseSchema.parse(result.data);

if ("errors" in validated && validated.errors) {
  throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
}

if ("creatives" in validated) {
  console.log(`Successfully synced ${validated.creatives.length} creatives`);
  validated.creatives.forEach((creative) => {
    console.log(`  ${creative.name}: ${creative.platform_id}`);
  });
}

ジェネレーティブクリエイティブ

クリエイティブエージェントを使用してブランドアイデンティティデータからクリエイティブを生成します。完全なワークフローの詳細はジェネレーティブクリエイティブガイドを参照。
import { testAgent } from "@adcp/client/testing";
import { SyncCreativesResponseSchema } from "@adcp/client";

const result = await testAgent.syncCreatives({
  creatives: [
    {
      creative_id: "creative_gen_001",
      name: "AI-Generated Summer Banner",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "display_300x250",
      },
      assets: {
        manifest: {
          url: "https://cdn.example.com/brand.json",
        },
      },
    },
  ],
});

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

const validated = SyncCreativesResponseSchema.parse(result.data);

if ("errors" in validated && validated.errors) {
  throw new Error(`Operation failed: ${JSON.stringify(validated.errors)}`);
}

if ("creatives" in validated) {
  console.log(
    "Generative creative synced:",
    validated.creatives[0].creative_id
  );
}

ドライラン検証

アップロードせずにクリエイティブ設定を検証する:
import { testAgent } from "@adcp/client/testing";
import { SyncCreativesResponseSchema } from "@adcp/client";

const result = await testAgent.syncCreatives({
  dry_run: true,
  creatives: [
    {
      creative_id: "creative_test_001",
      name: "Test Creative",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "video_standard_30s",
      },
      assets: {
        video: {
          url: "https://cdn.example.com/test-video.mp4",
          width: 1920,
          height: 1080,
          duration_ms: 30000,
        },
      },
    },
  ],
});

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

const validated = SyncCreativesResponseSchema.parse(result.data);

if ("errors" in validated && validated.errors && validated.errors.length > 0) {
  console.log("Validation errors found:");
  validated.errors.forEach((error) => console.log(`  - ${error.message}`));
} else {
  console.log("Validation passed! Ready to sync.");
}

creative_ids フィルターを使用したスコープ更新

大きなライブラリから特定のクリエイティブのみを更新し、その他には影響を与えない:
import { testAgent } from "@adcp/client/testing";
import { SyncCreativesResponseSchema } from "@adcp/client";

// ライブラリの 100+ のうち 2 つのクリエイティブのみを更新
const result = await testAgent.syncCreatives({
  creative_ids: ["creative_video_001", "creative_display_001"],
  creatives: [
    {
      creative_id: "creative_video_001",
      name: "Summer Sale 30s - Updated",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "video_standard_30s",
      },
      assets: {
        video: {
          url: "https://cdn.example.com/updated-video.mp4",
          width: 1920,
          height: 1080,
          duration_ms: 30000,
        },
      },
    },
    {
      creative_id: "creative_display_001",
      name: "Summer Sale Banner - Updated",
      format_id: {
        agent_url: "https://creative.adcontextprotocol.org",
        id: "display_300x250",
      },
      assets: {
        image: {
          url: "https://cdn.example.com/updated-banner.jpg",
          width: 300,
          height: 250,
        },
      },
    },
  ],
});

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

const validated = SyncCreativesResponseSchema.parse(result.data);

if ("errors" in validated && validated.errors) {
  throw new Error(`Update failed: ${JSON.stringify(validated.errors)}`);
}

if ("creatives" in validated) {
  console.log(
    `Updated ${validated.creatives.length} creatives, others untouched`
  );
}
creative_ids フィルターを使用する理由:
  • スコープ更新: 指定されたクリエイティブのみが変更され、ライブラリに 100+ あっても同様
  • エラー復旧: 一括同期の検証失敗後に失敗したクリエイティブのみをリトライ
  • パフォーマンス: スコープが事前にわかっているとパブリッシャーが処理を最適化できます
  • 安全性: 明示的なターゲティングにより意図しない変更のリスクを低減

非同期承認ワークフロー

クリエイティブがレビューを必要とする場合(ブランドセーフティ、ポリシーコンプライアンス)、初期レスポンスは status: "submitted" だ。結果を取得するためにウェブフックまたはポーリングを使用します。 最終レスポンスは status: "completed" とクリエイティブごとの結果を持ちます:
  • 承認されたクリエイティブ: platform_id を持つ action: "created"
  • 拒否されたクリエイティブ: errors 配列にエラー詳細を持つ action: "failed"
操作ステータス(completed)はレビュープロセスが完了したことを意味します。個々のクリエイティブの結果は action フィールドにある。 操作レベルの失敗(認証エラー、サービス利用不可)は creatives 配列なしで status: "failed" を返します。 参照: ウェブフック設定についてはウェブフックを参照。

同期モード

アップサート(デフォルト)

  • creative_id で既存のクリエイティブを作成または更新します
  • パッケージアサインメントをマージする(追加的)
  • 提供されたフィールドを更新し、その他はそのままにします
  • 特定のクリエイティブにスコープを制限するために creative_ids フィルターを使用します

ドライラン

  • 変更を加えずにリクエストを検証します
  • エラーと警告を返す
  • アセットを処理したりクリエイティブを作成したりしません
  • プリフライト検証チェックに使用します

エラー処理

エラーコード説明解決方法
INVALID_FORMATフォーマットがプロダクトでサポートされていないlist_creative_formats でプロダクトのサポートフォーマットを確認する
ASSET_PROCESSING_FAILEDアセットファイルが破損しているか無効アセットがフォーマット要件(コーデック、ディメンション、デュレーション)を満たしているか確認する
PACKAGE_NOT_FOUNDパッケージ ID がメディアバイに存在しないcreate_media_buy レスポンスから package_id を確認する
BRAND_SAFETY_VIOLATIONクリエイティブがブランドセーフティスキャンに失敗パブリッシャーのブランドセーフティガイドラインに対してコンテンツをレビューする
FORMAT_MISMATCHアセットがフォーマット要件に一致しないアセットタイプと仕様がフォーマット定義と一致しているか確認する
CREATIVE_IN_ACTIVE_DELIVERYクリエイティブがアクティブで一時停止されていないパッケージにアサインされている(更新と delete_missing による削除をブロック)まずパッケージを一時停止するか、新しいクリエイティブバージョンを作成する

ベストプラクティス

  1. アップサートセマンティクスを使用する — 同じ creative_id で既存のクリエイティブを更新し、重複を作成しません。これにより反復的なクリエイティブ開発が可能。注意: アクティブな配信中のクリエイティブは更新がブロックされます(#7 を参照)。
  2. まず検証するdry_run: true を使用して実際のアップロード前にエラーをキャッチします。帯域幅と処理時間を節約できます。
  3. アサインメントをバッチ処理する — 更新間の競合状態を避けるために、すべてのパッケージアサインメントを1回の同期呼び出しに含めます。
  4. CDN ホストのアセット — 高速処理のために公開アクセス可能な CDN URL を使用します。プラットフォームはプロキシ遅延なしに直接アセットをフェッチできます。
  5. ブランドアイデンティティ — ジェネレーティブクリエイティブの場合、処理失敗を避けるために同期前にブランドアイデンティティスキーマを検証します。
  6. フォーマットサポートを確認する — アップロード前に list_creative_formats を使用してプロダクトがクリエイティブフォーマットをサポートしているか確認します。
  7. アクティブ配信の保護 — アクティブで一時停止されていないパッケージにアサインされているクリエイティブは、delete_missing で更新または削除できません。まずパッケージを一時停止するか、update_media_buy でクリエイティブのアサインを解除するか、別の creative_id で新しいクリエイティブを作成します。

関連タスク