Skip to main content
アトリビューションと最適化のためにコンバージョンまたはマーケティングイベントを送信します。バッチ送信、テストイベント、および部分的な失敗レポートをサポートしています。 レスポンス時間: 約1秒(イベントは処理キューに追加されます) リクエストスキーマ: /schemas/v3/media-buy/log-event-request.json レスポンススキーマ: /schemas/v3/media-buy/log-event-response.json

クイックスタート

購入イベントをログに記録する:
import { testAgent } from "@adcp/client/testing";
import { LogEventResponseSchema } from "@adcp/client";

const result = await testAgent.logEvent({
  event_source_id: "website_pixel",
  events: [
    {
      event_id: "evt_purchase_12345",
      event_type: "purchase",
      event_time: "2026-01-15T14:30:00Z",
      action_source: "website",
      event_source_url: "https://www.example.com/checkout/confirm",
      user_match: {
        click_id: "abc123def456",
        click_id_type: "gclid",
      },
      custom_data: {
        value: 149.99,
        currency: "USD",
        order_id: "order_98765",
        num_items: 3,
      },
    },
  ],
});

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

// Validate response against schema
const validated = LogEventResponseSchema.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 ("events_received" in validated) {
  console.log(`Received: ${validated.events_received}, Processed: ${validated.events_processed}`);
  if (validated.match_quality !== undefined) {
    console.log(`Match quality: ${(validated.match_quality * 100).toFixed(0)}%`);
  }
}

リクエストパラメータ

パラメータ必須説明
event_source_idstringはいsync_event_sources でアカウントに設定されたイベントソース
eventsEvent[]はいログに記録するイベント(最小1件、最大10,000件)
test_event_codestringいいえ本番データに影響を与えずに検証するためのテストイベントコード

Event オブジェクト

フィールド必須説明
event_idstringはい重複排除のための一意の識別子(event_type + event_source_id のスコープ内)。最大256文字。
event_typeEventTypeはい標準イベントタイプ(例:purchaseleadadd_to_cart
event_timedate-timeはいイベントが発生した時刻の ISO 8601 タイムスタンプ
user_matchUserMatchいいえアトリビューションマッチング用のユーザー識別子
custom_dataCustomDataいいえイベント固有のデータ(金額、通貨、アイテムなど)
action_sourceActionSourceいいえイベントが発生した場所(websiteappin_store など)
event_source_urluriいいえイベントが発生した URL(action_source が website の場合は必須)
custom_event_namestringいいえカスタムイベントの名前(event_type が custom の場合に使用)

User Match オブジェクト

uidshashed_emailhashed_phoneclick_id、または client_ip + client_user_agent のうち少なくとも1つが必須:
フィールド説明
uidsUID[]ユニバーサル ID の値(rampidid5uid2euidpairidmaid
hashed_emailstring小文字・トリミング済みのメールアドレスの SHA-256 ハッシュ(64文字の16進数)
hashed_phonestringE.164 形式の電話番号の SHA-256 ハッシュ(64文字の16進数)
click_idstringプラットフォームのクリック識別子(fbclid、gclid、ttclid など)
click_id_typestringクリック識別子の種類
client_ipstring確率的マッチング用のクライアント IP アドレス
client_user_agentstring確率的マッチング用のクライアントユーザーエージェント文字列
ハッシュ化: ハッシュ化された識別子は SHA-256 の16進数文字列(64文字、小文字)でなければなりません。ハッシュ化前に正規化すること: メールアドレスは小文字かつ前後の空白をトリミング、電話番号は E.164 形式(例:+12065551234)にします。

Custom Data オブジェクト

フィールド説明
valuenumberイベントの金額
currencystringISO 4217 通貨コード(例:USDEURGBP
order_idstring注文またはトランザクションの一意の識別子
content_idsstring[]商品またはコンテンツの識別子。カタログ駆動型キャンペーンでは、カタログの content_id_type(SKU、GTIN、求人 ID など)に対応します。カタログアイテムアトリビューションを参照。
content_typestringコンテンツのカテゴリ(商品、サービスなど)
num_itemsintegerイベント内のアイテム数
contentsContent[]アイテムごとの詳細(id、数量、価格、ブランド)

レスポンス

成功レスポンス:
  • events_received - 受信したイベント数
  • events_processed - 正常にキューに追加されたイベント数
  • partial_failures - バリデーションに失敗したイベント(event_id、コード、メッセージを含む)
  • warnings - 非致命的な問題(マッチ品質が低い、フィールドが欠落しているなど)
  • match_quality - 全体的なマッチ品質スコア(0.0 〜 1.0)
エラーレスポンス:
  • errors - オペレーションレベルのエラーの配列(無効なイベントソース、認証失敗など)
注意: レスポンスは判別共用体(discriminated union)を使用しており、成功フィールドまたは errors のどちらか一方のみが返されます。部分的な失敗は、成功レスポンス内にイベントごとに報告されます。

よくあるシナリオ

バッチイベント

複数のイベントを1つのリクエストで送信します:
import { testAgent } from "@adcp/client/testing";
import { LogEventResponseSchema } from "@adcp/client";

const result = await testAgent.logEvent({
  event_source_id: "website_pixel",
  events: [
    {
      event_id: "evt_purchase_001",
      event_type: "purchase",
      event_time: "2026-01-15T10:00:00Z",
      action_source: "website",
      user_match: {
        hashed_email: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
        uids: [{ type: "uid2", value: "AbC123XyZ..." }],
      },
      custom_data: {
        value: 89.99,
        currency: "USD",
        order_id: "order_001",
      },
    },
    {
      event_id: "evt_lead_002",
      event_type: "lead",
      event_time: "2026-01-15T11:30:00Z",
      action_source: "website",
      user_match: {
        hashed_email: "f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5",
        click_id: "abc123def456",
        click_id_type: "fbclid",
      },
    },
    {
      event_id: "evt_cart_003",
      event_type: "add_to_cart",
      event_time: "2026-01-15T12:15:00Z",
      action_source: "app",
      user_match: {
        uids: [{ type: "rampid", value: "Def456Ghi..." }],
      },
      custom_data: {
        content_ids: ["SKU-1234", "SKU-5678"],
        num_items: 2,
        value: 45.00,
        currency: "USD",
      },
    },
  ],
});

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

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

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

if ("events_received" in validated) {
  console.log(`${validated.events_processed}/${validated.events_received} events processed`);
  if (validated.partial_failures?.length) {
    for (const failure of validated.partial_failures) {
      console.log(`  Failed: ${failure.event_id} - ${failure.message}`);
    }
  }
}

テストイベント

本番データに影響を与えずにイベント連携を検証する:
import { testAgent } from "@adcp/client/testing";
import { LogEventResponseSchema } from "@adcp/client";

const result = await testAgent.logEvent({
  event_source_id: "website_pixel",
  test_event_code: "TEST_12345",
  events: [
    {
      event_id: "test_evt_001",
      event_type: "purchase",
      event_time: new Date().toISOString(),
      action_source: "website",
      event_source_url: "https://www.example.com/checkout",
      user_match: {
        click_id: "test_click_abc",
        click_id_type: "gclid",
      },
      custom_data: {
        value: 99.99,
        currency: "USD",
      },
    },
  ],
});

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

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

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

if ("events_received" in validated) {
  console.log("Test event sent successfully");
  if (validated.warnings?.length) {
    console.log("Warnings:", validated.warnings);
  }
}
テストイベントはセラーのテストイベント UI に表示されるが、本番のアトリビューションやレポートには影響しません。

店舗内コンバージョン

CRM データを使用してオフラインコンバージョンを報告する:
import { testAgent } from "@adcp/client/testing";
import { LogEventResponseSchema } from "@adcp/client";

const result = await testAgent.logEvent({
  event_source_id: "crm_import",
  events: [
    {
      event_id: "store_txn_20260115_001",
      event_type: "purchase",
      event_time: "2026-01-15T16:45:00Z",
      action_source: "in_store",
      user_match: {
        uids: [{ type: "rampid", value: "XyZ789AbC..." }],
      },
      custom_data: {
        value: 250.0,
        currency: "USD",
        order_id: "POS-2026-0115-001",
        contents: [
          { id: "SKU-JACKET-L", quantity: 1, price: 189.0 },
          { id: "SKU-SCARF-01", quantity: 1, price: 61.0 },
        ],
      },
    },
  ],
});

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

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

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

if ("events_received" in validated) {
  console.log(`In-store events processed: ${validated.events_processed}`);
}

イベントの重複排除

イベントは event_id + event_type + event_source_id の組み合わせで重複排除されます。同じイベントを複数回送信しても安全で、重複は無視されます。 リトライをまたいで安定した event_id の値を選ぶこと:
  • トランザクション ID: "order_98765"
  • 複合キー: "purchase_user123_20260115"
  • UUID: "550e8400-e29b-41d4-a716-446655440000"

エラーハンドリング

エラーコード説明対処方法
EVENT_SOURCE_NOT_FOUNDイベントソースが設定されていない先に sync_event_sources を実行する
INVALID_EVENT_TYPE認識されていない、または許可されていないイベントタイプイベントソースの event_types 設定を確認する
INVALID_EVENT_TIMEイベント時刻が過去または未来に遠すぎるセラーのアトリビューションウィンドウ内のタイムスタンプを使用する
MISSING_USER_MATCHユーザー識別子が提供されていないuids、hashed_email、hashed_phone、click_id、または client_ip + client_user_agent のうち少なくとも1つを含める
BATCH_TOO_LARGEイベントが10,000件を超えている小さいバッチに分割する
RATE_LIMITEDリクエストが多すぎる指数バックオフで待機してリトライする

ベストプラクティス

  1. 先にソースを設定する — イベントを送信する前に必ず sync_event_sources を実行します。設定されていないソースへのイベントは拒否されます。
  2. user_match を含める — ユーザー識別子のないイベントはアトリビューションできません。利用可能な最も強力な識別子を提供すること: ハッシュ化されたメール・電話番号 > UID > クリック ID > IP/UA。マッチ率を最大化するために、複数の識別子タイプを可能な限り送信します。
  3. 最初はテストイベントを使用する — 連携の検証時は test_event_code を設定し、本番データに影響を与えずにイベントが正しく表示されることを確認します。
  4. 可能な限りバッチ処理する — API 呼び出し回数を減らすために、1リクエストあたり最大10,000件のイベントを送信します。バッチ内のイベントはそれぞれ独立して処理されます。
  5. value と currency を含める — 購入イベントでは、ROAS レポートと最適化を有効にするために常に custom_data.valuecustom_data.currency を含めます。
  6. 安定したイベント ID を使用する — ランダムな UUID ではなく、決定論的なイベント ID(注文番号、トランザクション ID)を使用します。これにより重複カウントなしに安全なリトライが可能になります。
  7. イベントを迅速に送信する — できる限りリアルタイムに近いタイミングでイベントをログに記録します。セラーのアトリビューションウィンドウを超えたイベントはマッチングされない場合があります。

次のステップ