mcpField
M
meta-capi

meta-capi

github.com/cognyaiマーケティング・グロース11169 回インストール2 週間前に更新
リポジトリ

meta-capi について

meta-capiは、Meta Conversions APIの実装とトラブルシューティング向け技術リファレンススキルです。イベント仕様、ハッシュ処理、重複排除、テストに加え、直接APIやGTMサーバーサイドの設定例を開発者やマーケターに提供します。

主な機能

  1. 01標準イベントとカスタムイベントの解説
  2. 02顧客データの正規化とハッシュ処理
  3. 03PixelとCAPIのイベント重複排除
  4. 04イベントマッチ品質の改善方法
  5. 05Node.js、Python、GTMの例

活用シーン

  1. 01CAPIイベントのパラメーターを設計
  2. 02イベント計測と重複排除の問題を調査
  3. 03イベントマッチデータの品質を改善
  4. 04直接APIまたはGTMサーバーサイド計測を設定

MCP 対応

Cogny MCPツールが利用可能な場合、Pixel設定、広告アカウント設定、キャンペーンデータの確認に使用できます。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cognyai/claude-code-marketing-skills --skill meta-capi

インストール後、Claude Code で/meta-capiを入力して読み込まれたか確認します。

詳細

Meta Conversions API(CAPI)セットアップリファレンス

Meta Conversions API の技術リファレンスです。アーキテクチャ、パラメーターを含むすべての標準イベントタイプ、顧客情報のハッシュ化、実装方法、イベントの重複排除、テスト、Aggregated Event Measurement について説明します。

ドキュメント全文:https://cogny.com/docs/meta-conversions-api

使用方法

/meta-capi                          # Full CAPI overview
/meta-capi deduplication            # Event dedup strategy
/meta-capi purchase event           # Purchase event parameters
/meta-capi emq                      # Improve Event Match Quality
/meta-capi aem                      # Aggregated Event Measurement
/meta-capi node.js                  # Node.js implementation example
/meta-capi gtm server-side          # GTM SS container setup

手順

あなたは Meta Conversions API のエキスパートです。このリファレンスを使用して、ユーザーによる CAPI の正しい実装、イベントトラッキングの問題のデバッグ、Event Match Quality の改善、重複排除の設定、Aggregated Event Measurement の理解を支援してください。

ユーザーから質問されたら、以下から関連するセクションを探し、すぐに使えるコード例を添えて、正確で実行可能な回答を提供してください。

ユーザーが特定のトピックを引数として指定した場合は、その領域に焦点を当ててください。それ以外の場合は、CAPI アーキテクチャと主な実装手順の概要を説明してください。

Cogny MCP ツールを利用できる場合は、それらを使用してユーザーの実際の Pixel 設定、広告アカウントのセットアップ、キャンペーンデータを確認し、状況に応じた推奨事項を提供してください。


アーキテクチャ:ブラウザ Pixel とサーバーサイド CAPI

                         User's Browser
                        +------------------------------+
                        |  Meta Pixel (fbevents.js)     |
                        |  - Fires on page interaction  |
                        |  - Sets _fbp / _fbc cookies   |
                        |  - Sends event_id for dedup   |
                        +----------+-------------------+
                                   |  HTTPS (browser -> Meta)
                                   v
                        +------------------------------+
                        |       Meta Servers            |
                        |  - Receives Pixel events      |
                        |  - Receives CAPI events       |
                        |  - Deduplicates via event_id  |
                        |  - Matches users (EMQ)        |
                        |  - Feeds ad optimization      |
                        +------------------------------+
                                   ^
                                   |  HTTPS (server -> Meta)
                        +----------+-------------------+
                        |  Your Server / GTM SS         |
                        |  - Conversions API endpoint   |
                        |  - POST /v21.0/{pixel_id}/    |
                        |    events                     |
                        |  - Hashes PII before sending  |
                        |  - Sends same event_id        |
                        +------------------------------+

両方が重要な理由:

  • Pixel のみ: 広告ブロッカー(シグナル損失 15〜30%)、ITP による Cookie の有効期限(Safari では上限 7 日)、ネットワーク障害の影響を受けます。
  • CAPI のみ: リアルタイムのブラウザー操作を捕捉できず、ファーストパーティ Cookie を設定できません。
  • Pixel + CAPI(推奨): 重複排除を伴う冗長なデータ経路を確保します。失われたコンバージョンの 10〜25%を補完します。

標準イベント

Purchase

取引が完了したときに発生します。

パラメーター型必須説明
valuefloatはい取引の合計金額
currencystringはいISO 4217 コード(例:USD、EUR)
content_idsarray推奨カタログの商品 ID
content_typestring推奨product または product_group
contentsarray推奨{id, quantity, item_price} の配列
content_namestring任意商品名またはページ名
content_categorystring任意商品カテゴリ
num_itemsinteger任意商品数
order_idstring任意内部注文 ID
AddToCart
パラメーター型必須説明
valuefloat推奨商品の価格
currencystring推奨ISO 4217 コード
content_idsarray推奨商品 ID
content_typestring推奨product または product_group
contentsarray推奨{id, quantity, item_price}
content_namestring任意商品名
content_categorystring任意商品カテゴリ
InitiateCheckout
パラメーター型必須説明
valuefloat推奨カートの合計金額
currencystring推奨ISO 4217 コード
content_idsarray推奨カート内の商品 ID
content_typestring推奨product または product_group
contentsarray推奨{id, quantity, item_price}
num_itemsinteger任意商品数
CompleteRegistration
パラメーター型必須説明
valuefloat任意登録の価値
currencystring任意ISO 4217 コード
content_namestring任意フォーム名またはページ名
statusstring任意登録ステータス
Lead
パラメーター型必須説明
valuefloat任意見込み客の推定価値
currencystring任意ISO 4217 コード
content_namestring任意リードフォーム名
content_categorystring任意リードカテゴリ
ViewContent
パラメーター型必須説明
valuefloat推奨コンテンツの価値
currencystring推奨ISO 4217 コード
content_idsarray推奨コンテンツ/商品の ID
content_typestring推奨product または product_group
content_namestring任意コンテンツ名
content_categorystring任意コンテンツカテゴリ
Search
パラメーター型必須説明
search_stringstring推奨検索クエリ
valuefloat任意割り当てられた価値
currencystring任意ISO 4217 コード
content_idsarray任意検索結果の ID
content_categorystring任意検索結果のカテゴリ
AddPaymentInfo
パラメーター型必須説明
valuefloat任意カートの価値
currencystring任意ISO 4217 コード
content_idsarray任意商品 ID
content_typestring任意product または product_group
content_categorystring任意支払い方法のカテゴリ
AddToWishlist
パラメーター型必須説明
valuefloat任意アイテムの価値
currencystring任意ISO 4217 コード
content_idsarray任意商品 ID
content_namestring任意商品名
content_categorystring任意商品カテゴリ
Contact

ユーザーが電話、SMS、メール、チャットで連絡を開始したときに発生します。顧客情報以外に必須または推奨されるパラメーターはありません。

CustomizeProduct
パラメーター型必須説明
content_idsarray任意商品 ID
content_typestring任意product または product_group
content_namestring任意商品名
Donate
パラメーター型必須説明
valuefloat推奨寄付額
currencystring推奨ISO 4217 コード
FindLocation
パラメーター型必須説明
content_namestring任意場所の名前または検索クエリ
content_categorystring任意場所の種類
Schedule
パラメーター型必須説明
content_namestring任意予約の種類
content_categorystring任意サービスカテゴリ
StartTrial
パラメーター型必須説明
valuefloat推奨予測されるトライアルの価値
currencystring推奨ISO 4217 コード
content_namestring任意トライアルプラン名
SubmitApplication
パラメーター型必須説明
content_namestring任意申請の種類
content_categorystring任意申請カテゴリ
Subscribe
パラメーター型必須説明
valuefloatはいサブスクリプションの価値
currencystringはいISO 4217 コード
content_namestring任意プラン名

カスタムイベント

カスタムイベントは、標準イベントに対応付けられていないアクションを対象とします。オーディエンスの作成やカスタムコンバージョンに使用されますが、標準の最適化目標には利用できません。

命名規則:

  • 最大 40 文字
  • 小文字、数字、アンダースコアのみ使用可能
  • 数字で始めてはいけません
  • 予約済みの名前(標準イベント名、fb_、_fb のプレフィックス)は使用できません
  • 例:qualified_lead、demo_booked、pricing_page_scroll_50

顧客情報パラメーター

顧客情報パラメーターを使うと、Meta はイベントとユーザープロフィールを照合できます。照合品質が高いほど、広告の最適化が向上します。

利用可能なパラメーター
パラメーターキーハッシュ化前の形式
メールアドレスem小文字に変換し、空白を削除
電話番号ph国番号を含む数字のみ(例:14155551234)
名fn小文字に変換し、前後の空白と句読点を削除
姓ln小文字に変換し、前後の空白と句読点を削除
市区町村ct小文字に変換し、前後の空白と句読点、スペースを削除
州st2 文字の略称を小文字で指定(例:ca)
郵便番号zp前後の空白を削除。米国の場合は 5 桁のみ
国countryISO 3166-1 alpha-2 の 2 文字コードを小文字で指定(例:us)
生年月日dbYYYYMMDD 形式
性別ge1 文字:m または f
外部 IDexternal_id任意の文字列。ハッシュ化を推奨しますが、必須ではありません
ハッシュ化の要件

external_id を除くすべてのパラメーターは、CAPI で送信する前に SHA-256 でハッシュ化する必要があります。Pixel は自動的にハッシュ化しますが、CAPI は自動的にハッシュ化しません。

手順: 正規化(小文字に変換し、前後の空白を削除)-> SHA-256 -> 小文字の 16 進数文字列(64 文字)

// Node.js
const crypto = require('crypto');
function hashForMeta(value) {
  if (!value) return null;
  return crypto.createHash('sha256')
    .update(value.toString().trim().toLowerCase())
    .digest('hex');
}
# Python
import hashlib
def hash_for_meta(value):
    if not value:
        return None
    return hashlib.sha256(str(value).strip().lower().encode('utf-8')).hexdigest()

よくある間違い:

  • 正規化する前にハッシュ化する(入力値に大文字が含まれている)
  • すでにハッシュ化された値を二重にハッシュ化する
  • ハッシュ入力に空白を含める
  • 電話番号に国番号を付け忘れる
  • SHA-256 ではなく MD5 を使用する
イベント照合品質(EMQ)

EMQ は、Meta がイベントとユーザープロフィールをどの程度照合できたかを示す 1~10 のスコアです。

EMQ スコア品質影響
1-3低いほとんどのイベントが照合されない
4-5普通部分的に照合される
6-7良好高い精度で照合される
8-10非常に良好最適化の可能性を最大限に引き出せる

EMQ を改善する方法:

  1. すべてのイベントで em(メールアドレス)を送信する。最も効果があります
  2. 2 つ目の識別子として ph(電話番号)を追加する
  3. よくあるメールアドレスを区別できるよう、fn + ln を含める
  4. デバイスをまたいだ照合のため、external_id を渡す
  5. ブラウザーからサーバーへ fbp と fbc の Cookie を転送する
  6. 正しい正規化とハッシュ化が行われていることを確認する

実装方法

直接 API 連携

エンドポイント: POST https://graph.facebook.com/v21.0/{pixel_id}/events

認証: access_token クエリパラメーター(ads_management 権限を持つシステムユーザートークン)

Node.js の例
const crypto = require('crypto');

const PIXEL_ID = 'YOUR_PIXEL_ID';
const ACCESS_TOKEN = 'YOUR_ACCESS_TOKEN';

function hash(value) {
  if (!value) return undefined;
  return crypto.createHash('sha256')
    .update(value.toString().trim().toLowerCase())
    .digest('hex');
}

async function sendEvent(eventName, eventData, userData, eventId = null) {
  const payload = {
    data: [{
      event_name: eventName,
      event_time: Math.floor(Date.now() / 1000),
      event_id: eventId || crypto.randomUUID(),
      event_source_url: eventData.source_url,
      action_source: 'website',
      user_data: {
        em: hash(userData.email),
        ph: hash(userData.phone),
        fn: hash(userData.firstName),
        ln: hash(userData.lastName),
        ct: hash(userData.city),
        st: hash(userData.state),
        zp: hash(userData.zipCode),
        country: hash(userData.country),
        external_id: hash(userData.externalId),
        client_ip_address: userData.ipAddress,
        client_user_agent: userData.userAgent,
        fbp: userData.fbp,   // raw cookie value, not hashed
        fbc: userData.fbc,   // raw cookie value, not hashed
      },
      custom_data: eventData.customData || {},
    }],
  };

  const url = `https://graph.facebook.com/v21.0/${PIXEL_ID}/events?access_token=${ACCESS_TOKEN}`;
  const response = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });

  if (!response.ok) {
    const err = await response.json();
    throw new Error(`CAPI error: ${JSON.stringify(err)}`);
  }
  return response.json();
}

// Example: Purchase event
await sendEvent('Purchase', {
  source_url: 'https://example.com/checkout/thank-you',
  customData: {
    value: 99.99,
    currency: 'USD',
    content_ids: ['SKU-123', 'SKU-456'],
    content_type: 'product',
    order_id: 'ORDER-789',
    num_items: 2,
  },
}, {
  email: '[email protected]',
  phone: '14155551234',
  firstName: 'John',
  lastName: 'Doe',
  ipAddress: '203.0.113.50',
  userAgent: 'Mozilla/5.0 ...',
  fbp: 'fb.1.1612345678901.1234567890',
  fbc: 'fb.1.1612345678901.AbCdEfGhIjKl',
  externalId: 'user-12345',
}, 'evt_purchase_abc123');
Python の例
import hashlib, time, uuid, requests

PIXEL_ID = 'YOUR_PIXEL_ID'
ACCESS_TOKEN = 'YOUR_ACCESS_TOKEN'

def hash_value(value):
    if not value:
        return None
    return hashlib.sha256(str(value).strip().lower().encode('utf-8')).hexdigest()

def send_event(event_name, event_data, user_data, event_id=None):
    url = f'https://graph.facebook.com/v21.0/{PIXEL_ID}/events'
    payload = {
        'data': [{
            'event_name': event_name,
            'event_time': int(time.time()),
            'event_id': event_id or str(uuid.uuid4()),
            'event_source_url': event_data.get('source_url'),
            'action_source': 'website',
            'user_data': {k: v for k, v in {
                'em': hash_value(user_data.get('email')),
                'ph': hash_value(user_data.get('phone')),
                'fn': hash_value(user_data.get('first_name')),
                'ln': hash_value(user_data.get('last_name')),
                'ct': hash_value(user_data.get('city')),
                'st': hash_value(user_data.get('state')),
                'zp': hash_value(user_data.get('zip_code')),
                'country': hash_value(user_data.get('country')),
                'external_id': hash_value(user_data.get('external_id')),
                'client_ip_address': user_data.get('ip_address'),
                'client_user_agent': user_data.get('user_agent'),
                'fbp': user_data.get('fbp'),
                'fbc': user_data.get('fbc'),
            }.items() if v is not None},
            'custom_data': event_data.get('custom_data', {}),
        }],
        'access_token': ACCESS_TOKEN,
    }
    response = requests.post(url, json=payload)
    response.raise_for_status()
    return response.json()

# Example: Purchase event
send_event('Purchase', {
    'source_url': 'https://example.com/checkout/thank-you',
    'custom_data': {
        'value': 99.99,
        'currency': 'USD',
        'content_ids': ['SKU-123'],
        'content_type': 'product',
    },
}, {
    'email': '[email protected]',
    'phone': '14155551234',
    'first_name': 'John',
    'last_name': 'Doe',
    'ip_address': '203.0.113.50',
    'user_agent': 'Mozilla/5.0 ...',
    'fbp': 'fb.1.1612345678901.1234567890',
    'external_id': 'user-12345',
}, event_id='evt_purchase_abc123')
GTM サーバーサイドコンテナ
  1. GTM サーバーサイドコンテナをデプロイします(Cloud Run、AWS など)
  2. サーバーコンテナにMeta Conversions API タグを作成します
  3. 次の項目を設定します:
    • Pixel ID と API Access Token
    • アクションソース: website
    • イベント名: 受信イベントからマッピング
    • ユーザーデータ: イベントデータからメールアドレス、電話番号などをマッピング
    • イベント ID: 重複排除のため、ブラウザーの Pixel の eventID と一致させる必要があります
  4. 関連する転送済みイベントにトリガーを設定します

主なタグフィールド:

Tag Type:          Meta Conversions API
Pixel ID:          {{Meta Pixel ID}}
API Access Token:  {{Meta CAPI Token}}
Event Name:        {{Event Name}}
Action Source:     website

User Data:
  Email:           {{User Email - Hashed}}
  Phone:           {{User Phone - Hashed}}
  IP Address:      {{Client IP}}  (auto-populated in SS GTM)
  User Agent:      {{Client User Agent}}  (auto-populated)
  FBP:             {{FBP Cookie}}
  FBC:             {{FBC Cookie}}

Event Parameters:
  Event ID:        {{Event ID}}  (must match browser Pixel eventID)
  Event Source URL: {{Page URL}}
  Value:           {{Event Value}}
  Currency:        {{Event Currency}}
パートナー連携
プラットフォーム方法備考
ShopifyMeta チャネルアプリを標準で利用重複排除を自動処理。標準的な e コマースイベントに対応
WooCommerceFacebook for WooCommerce プラグイン設定が必要
BigCommerceMeta 標準連携アプリ経由
MagentoMeta Business Extensionサーバーサイドイベント

イベントの重複排除

Pixel と CAPI を併用すると、同じコンバージョンが 2 回報告される場合があります。Meta は event_id + event_name を使って重複を排除します。

仕組み
  1. ブラウザーの Pixel が eventID: "evt_abc123" と Purchase を送信します
  2. サーバーが event_id: "evt_abc123" と Purchase を含む CAPI を送信します
  3. Meta は両方のフィールドで一致を確認し、1 件のコンバージョンとしてカウントします
  4. どちらか一方の経路でエラーが発生しても(広告ブロッカー、サーバーエラーなど)、もう一方からイベントが届きます
重複排除パターン
// Browser: generate event_id, fire Pixel, send to server
const eventId = crypto.randomUUID();

fbq('track', 'Purchase', {
  value: 99.99,
  currency: 'USD',
}, { eventID: eventId });

navigator.sendBeacon('/api/meta-capi', JSON.stringify({
  event_name: 'Purchase',
  event_id: eventId,
  custom_data: { value: 99.99, currency: 'USD' },
}));

// Server: forward to CAPI with same event_id
fbp と fbc Cookie

_fbp(Facebook ブラウザー ID):Pixel の初回読み込み時に設定されます。形式:fb.1.{timestamp}.{random}。90 日間保持されます。生の値を送信します(ハッシュ化しません)。

_fbc(Facebook クリック ID):Meta 広告のクリック時に設定されます。形式:fb.1.{timestamp}.{fbclid}。存在しない場合は、URL から fb.1.{timestamp_ms}.{fbclid} の形式で生成します。生の値を送信します(ハッシュ化しません)。

// Extract from cookies server-side
const fbp = req.cookies['_fbp'] || null;
const fbc = req.cookies['_fbc'] || null;

// Construct fbc from fbclid if cookie missing
function constructFbc(fbclid) {
  return fbclid ? `fb.1.${Date.now()}.${fbclid}` : null;
}
よくある重複排除の失敗
問題修正方法
Pixel と CAPI で event_id が異なるブラウザーで生成し、サーバーに渡します
Pixel に event_id がないfbq('track') の第 4 引数として { eventID: id } を追加します
CAPI に event_id がないペイロードに event_id を含めます
event_name の大文字・小文字が異なる標準の名前を正確に使用します(purchase ではなく Purchase)
CAPI の送信が数時間遅れる遅延バッチではなく、数分以内に送信します(重複排除ウィンドウは 48 時間です)

テストと検証

テストイベントツール
  1. Events Manager > Your Pixel > Test Events タブ
  2. Test Event Code をコピーします(例:TEST12345)
  3. CAPI ペイロードに test_event_code を追加します
  4. イベントを送信すると、リアルタイムで表示されます
  5. 本番環境に移行する前に test_event_code を削除します(テストイベントは広告配信に使用されません)
const payload = {
  data: [{ /* event data */ }],
  test_event_code: 'TEST12345',
};
イベントマッチ品質ダッシュボード

Events Manager > Data Sources > Your Pixel > Event Match Quality:

  • イベントごとの EMQ スコア
  • パラメーターの使用頻度の内訳
  • 改善の推奨事項
  • 時間の経過に伴う傾向
よくあるエラーコード
コードメッセージ修正方法
190無効な OAuth アクセストークンシステムユーザートークンを再生成します
100無効なパラメーター必須項目を確認します:event_name、event_time、action_source、user_data
2804003タイムスタンプが古すぎますevent_time は過去 7 日以内である必要があります
2804004無効な event_timeミリ秒ではなく、Unix 秒を使用する必要があります
2804001user_data がありません顧客情報パラメーターを少なくとも 1 つ含めます
368一時的にブロックされていますレート制限です。指数バックオフを使用します
2804002無効な action_source次のいずれかを使用します:website、app、phone_call、chat、email、in_store、other
803アクセスが拒否されましたシステムユーザーに ads_management 権限が必要です

集約イベント測定(AEM)

ATT によるトラッキングをオプトアウトした iOS 14.5 以降のユーザーのイベントを測定するための Meta のプロトコルです。

主な情報
  • ドメインごとに優先度順で設定できるイベントは 最大 8 件 です
  • オプトアウトしたユーザーのデータには 72 時間の遅延 があります
  • クリック後 1 日のアトリビューション(標準のクリック後 7 日/ビュー後 1 日と比較)
  • オプトアウトによるコンバージョンの推定には 統計モデリング が使用されます
  • Business Settings で ドメイン認証 が必要です
推奨イベント優先度(E コマース)
優先度イベント
1(最高)Purchase
2Subscribe
3StartTrial
4InitiateCheckout
5AddPaymentInfo
6AddToCart
7CompleteRegistration
8(最低)ViewContent
推奨イベント優先度(リード獲得)
優先度イベント
1(最高)Purchase
2Lead
3SubmitApplication
4Schedule
5CompleteRegistration
6Contact
7ViewContent
8(最低)Search
ドメイン認証
  1. Business Settings > Brand Safety > Domains
  2. ドメインを追加し、DNS TXT レコード(推奨)、HTML ファイル、またはメタタグで認証します
  3. Events Manager > Aggregated Event Measurement で 8 件のイベントを設定します
レポートへの影響
指標iOS 14.5 以前AEM 使用時
アトリビューション期間クリック後 28 日、ビュー後 7 日クリック後 7 日、ビュー後 1 日
レポートの遅延リアルタイム最大 72 時間
内訳完全制限あり
コンバージョン数正確オプトアウトしたユーザー分はモデルによる推定
最適化イベント無制限ドメインごとに 8 件

対策:

  • CAPI を使用して EMQ を最大化します(ATT のオプトアウトによる影響を部分的に相殺します)
  • 最も重要な 8 件のイベントに優先順位を付けます
  • iOS のコンバージョンが 15〜30%過少報告されることを想定します
  • 広範なターゲティング戦略を検討します

Resources

コメント