关于 meta-capi
meta-capi 是实现和排查 Meta Conversions API 的技术参考技能,面向开发者和营销人员。内容涵盖事件参数、哈希处理、去重、测试,以及直接 API 和 GTM 服务端配置示例。
主要功能
- 01说明标准事件与自定义事件
- 02介绍客户数据规范化与哈希
- 03涵盖 Pixel 与 CAPI 事件去重
- 04提供事件匹配质量改进建议
- 05包含 Node.js、Python 和 GTM 示例
适用场景
- 01规划 CAPI 事件参数
- 02排查事件跟踪和去重问题
- 03改善事件匹配数据质量
- 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 的完整技术参考:架构、所有标准事件类型及其参数、客户信息哈希处理、实现方法、事件去重、测试和汇总事件衡量。
完整文档: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、调试事件跟踪问题、提升事件匹配质量、配置去重,并了解汇总事件衡量。
当用户提出问题时,请找到下方相关章节,并提供准确、可操作且可直接使用的代码示例。
如果用户提供了具体主题作为参数,请重点介绍该主题。否则,请概述 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
交易完成时触发。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | float | 是 | 交易总金额 |
currency | string | 是 | ISO 4217 代码(例如 USD、EUR) |
content_ids | array | 推荐 | 目录中的产品 ID |
content_type | string | 推荐 | product 或 product_group |
contents | array | 推荐 | {id, quantity, item_price} 数组 |
content_name | string | 可选 | 产品或页面名称 |
content_category | string | 可选 | 产品类别 |
num_items | integer | 可选 | 商品数量 |
order_id | string | 可选 | 内部订单 ID |
AddToCart
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | float | 推荐 | 商品金额 |
currency | string | 推荐 | ISO 4217 代码 |
content_ids | array | 推荐 | 产品 ID |
content_type | string | 推荐 | product 或 product_group |
contents | array | 推荐 | {id, quantity, item_price} |
content_name | string | 可选 | 产品名称 |
content_category | string | 可选 | 产品类别 |
InitiateCheckout
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | float | 推荐 | 购物车金额 |
currency | string | 推荐 | ISO 4217 代码 |
content_ids | array | 推荐 | 购物车中的产品 ID |
content_type | string | 推荐 | product 或 product_group |
contents | array | 推荐 | {id, quantity, item_price} |
num_items | integer | 可选 | 商品数量 |
CompleteRegistration
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | float | 可选 | 注册金额 |
currency | string | 可选 | ISO 4217 代码 |
content_name | string | 可选 | 表单或页面名称 |
status | string | 可选 | 注册状态 |
Lead
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
value | float | 可选 | 预估潜在客户价值 |
currency | string | 可选 | ISO 4217 代码 |
content_name | string | 可选 | 潜在客户表单名称 |
content_category | string | 可选 | 潜在客户类别 |
ViewContent
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
value | float | 建议填写 | 内容价值 |
currency | string | 建议填写 | ISO 4217 代码 |
content_ids | array | 建议填写 | 内容/产品 ID |
content_type | string | 建议填写 | product 或 product_group |
content_name | string | 可选 | 内容名称 |
content_category | string | 可选 | 内容类别 |
Search
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
search_string | string | 建议填写 | 搜索查询 |
value | float | 可选 | 指定的价值 |
currency | string | 可选 | ISO 4217 代码 |
content_ids | array | 可选 | 结果 ID |
content_category | string | 可选 | 结果类别 |
AddPaymentInfo
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
value | float | 可选 | 购物车价值 |
currency | string | 可选 | ISO 4217 代码 |
content_ids | array | 可选 | 产品 ID |
content_type | string | 可选 | product 或 product_group |
content_category | string | 可选 | 付款方式类别 |
AddToWishlist
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
value | float | 可选 | 商品价值 |
currency | string | 可选 | ISO 4217 代码 |
content_ids | array | 可选 | 产品 ID |
content_name | string | 可选 | 产品名称 |
content_category | string | 可选 | 产品类别 |
Contact
当用户发起联系(电话、短信、电子邮件、聊天)时触发。除客户信息外,没有必填或建议填写的参数。
CustomizeProduct
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
content_ids | array | 可选 | 产品 ID |
content_type | string | 可选 | product 或 product_group |
content_name | string | 可选 | 产品名称 |
Donate
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
value | float | 建议填写 | 捐赠金额 |
currency | string | 建议填写 | ISO 4217 代码 |
FindLocation
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
content_name | string | 可选 | 地点名称或查询内容 |
content_category | string | 可选 | 地点类型 |
Schedule
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
content_name | string | 可选 | 预约类型 |
content_category | string | 可选 | 服务类别 |
StartTrial
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
value | float | 建议填写 | 预计试用价值 |
currency | string | 建议填写 | ISO 4217 代码 |
content_name | string | 可选 | 试用方案名称 |
SubmitApplication
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
content_name | string | 可选 | 申请类型 |
content_category | string | 可选 | 申请类别 |
Subscribe
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
value | float | 是 | 订阅价值 |
currency | string | 是 | ISO 4217 代码 |
content_name | string | 可选 | 方案名称 |
自定义事件
自定义事件用于涵盖未映射到标准事件的操作。可用于构建受众和自定义转化,但不能用于标准优化目标。
命名规则:
- 最多 40 个字符
- 仅限小写字母、数字和下划线
- 不得以数字开头
- 不得使用保留名称(标准事件名称、
fb_、_fb前缀) - 示例:
qualified_lead、demo_booked、pricing_page_scroll_50
客户信息参数
客户信息参数可帮助 Meta 将事件与用户个人资料匹配。匹配质量越高,广告优化效果越好。
可用参数
| 参数 | 键 | 哈希前的格式 |
|---|---|---|
| 电子邮箱 | em | 转为小写,去除空白字符 |
| 电话号码 | ph | 仅保留数字,包含国家代码(例如:14155551234) |
| 名 | fn | 转为小写,去除空白字符和标点符号 |
| 姓 | ln | 转为小写,去除空白字符和标点符号 |
| 城市 | ct | 转为小写,去除空白字符、标点符号和空格 |
| 州 | st | 2 个字母的缩写,转为小写(例如:ca) |
| 邮政编码 | zp | 去除空白字符。美国:仅使用 5 位数字 |
| 国家/地区 | country | 2 个字母的 ISO 3166-1 alpha-2 代码,转为小写(例如:us) |
| 出生日期 | db | YYYYMMDD 格式 |
| 性别 | ge | 单个字母:m 或 f |
| 外部 ID | external_id | 任意字符串。建议哈希,但并非必需 |
哈希要求
除 external_id 外,所有参数在通过 CAPI 发送前都必须进行 SHA-256 哈希处理。Pixel 会自动进行哈希处理;CAPI 不会。
**步骤:**规范化(转为小写、去除空白字符)-> SHA-256 -> 小写十六进制字符串(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()
常见错误:
- 规范化之前就进行哈希处理(输入中包含大写字母)
- 对已经哈希的值重复进行哈希处理
- 哈希输入中包含空白字符
- 电话号码缺少国家代码
- 使用 MD5 而非 SHA-256
事件匹配质量(EMQ)
EMQ 是 1 到 10 的评分,用于表示 Meta 将事件与用户个人资料匹配的效果。
| EMQ 评分 | 质量 | 影响 |
|---|---|---|
| 1-3 | 差 | 大多数事件无法匹配 |
| 4-5 | 一般 | 部分匹配 |
| 6-7 | 良好 | 匹配效果强 |
| 8-10 | 优秀 | 充分发挥优化潜力 |
如何提高 EMQ:
- 在每个事件中发送
em(电子邮箱)——影响最大 - 添加
ph(电话号码)作为第二个标识符 - 包含
fn+ln,以区分常见的电子邮箱 - 传递
external_id,以支持跨设备匹配 - 将浏览器中的
fbp和fbcCookie 转发到服务端 - 确保规范化和哈希处理正确
实施方法
直接 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 服务端容器
- 部署 GTM 服务端容器(Cloud Run、AWS 等)
- 在服务端容器中创建 Meta Conversions API 标签
- 配置:
- Pixel ID 和 API Access Token
- 操作来源:
website - **事件名称:**根据传入事件进行映射
- **用户数据:**从事件数据中映射电子邮箱、电话号码等
- **事件 ID:**必须与浏览器 Pixel 的
eventID匹配,以便去重
- 为相关的转发事件设置触发器
标签的关键字段:
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}}
合作伙伴集成
| 平台 | 方法 | 备注 |
|---|---|---|
| Shopify | 原生 Meta 渠道应用 | 自动去重;标准电商事件 |
| WooCommerce | Facebook for WooCommerce 插件 | 需要配置 |
| BigCommerce | 原生 Meta 集成 | 通过应用实现 |
| Magento | Meta Business Extension | 服务端事件 |
事件去重
同时运行 Pixel 和 CAPI 时,同一转化可能会被报告两次。Meta 使用 event_id + event_name 进行去重。
工作原理
- 浏览器 Pixel 以
eventID: "evt_abc123"和Purchase触发 - 服务端通过 CAPI 发送
event_id: "evt_abc123"和Purchase - Meta 根据这两个字段进行匹配,并计为一次转化
- 如果其中一条路径失败(广告拦截器、服务端错误),另一条仍可传递事件
去重模式
// 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 | 将 { eventID: id } 作为第 4 个参数添加到 fbq('track') |
| CAPI 缺少 event_id | 在负载中包含 event_id |
| event_name 大小写不同 | 使用完全一致的标准名称(Purchase,而非 purchase) |
| CAPI 延迟数小时发送 | 在几分钟内发送,而不是延迟批量发送(48 小时去重窗口) |
测试和验证
测试事件工具
- Events Manager > Your Pixel > Test Events 标签页
- 复制 Test Event Code(例如,
TEST12345) - 将
test_event_code添加到 CAPI 负载中 - 发送事件——它们会实时显示
- 生产环境中移除 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 秒,而非毫秒 |
2804001 | 缺少 user_data | 至少包含一个客户信息参数 |
368 | 暂时被阻止 | 触发速率限制;使用指数退避 |
2804002 | action_source 无效 | 使用:website、app、phone_call、chat、email、in_store、other |
803 | 权限被拒绝 | 系统用户需要 ads_management 权限 |
汇总事件衡量(AEM)
Meta 针对使用 iOS 14.5+ 且通过 ATT 选择退出跟踪的用户进行事件衡量的协议。
重要信息
- 每个域名最多 8 个事件,按优先级排序
- 选择退出用户的数据会有 72 小时延迟
- 1 天点击归因(而标准设置为 7 天点击 / 1 天浏览)
- 使用统计建模估算选择退出用户的转化
- 需要在 Business Settings 中进行域名验证
推荐的事件优先级(电子商务)
| 优先级 | 事件 |
|---|---|
| 1(最高) | Purchase |
| 2 | Subscribe |
| 3 | StartTrial |
| 4 | InitiateCheckout |
| 5 | AddPaymentInfo |
| 6 | AddToCart |
| 7 | CompleteRegistration |
| 8(最低) | ViewContent |
推荐的事件优先级(潜在客户开发)
| 优先级 | 事件 |
|---|---|
| 1(最高) | Purchase |
| 2 | Lead |
| 3 | SubmitApplication |
| 4 | Schedule |
| 5 | CompleteRegistration |
| 6 | Contact |
| 7 | ViewContent |
| 8(最低) | Search |
域名验证
- Business Settings > Brand Safety > Domains
- 添加域名,通过 DNS TXT 记录(推荐)、HTML 文件或 meta 标签进行验证
- 在 Events Manager > Aggregated Event Measurement 中配置 8 个事件
对报告的影响
| 指标 | iOS 14.5 之前 | 使用 AEM |
|---|---|---|
| 归因窗口 | 28 天点击,7 天浏览 | 7 天点击,1 天浏览 |
| 报告延迟 | 实时 | 最长 72 小时 |
| 细分项 | 完整 | 有限 |
| 转化次数 | 精确 | 对选择退出的用户使用建模结果 |
| 优化事件 | 不限 | 每个域名 8 个 |
缓解措施:
- 使用 CAPI 提高 EMQ(部分抵消 ATT 选择退出的影响)
- 优先选择 8 个最重要的事件
- 预计 iOS 转化量会低报 15-30%
- 考虑采用广泛定向策略
Resources
- Meta CAPI Docs: https://developers.facebook.com/docs/marketing-api/conversions-api
- CAPI Setup Guide: https://developers.facebook.com/docs/marketing-api/conversions-api/get-started
- EMQ Best Practices: https://developers.facebook.com/docs/marketing-api/conversions-api/best-practices
- Standard Events Reference: https://developers.facebook.com/docs/meta-pixel/reference
- Full Cogny Docs: https://cogny.com/docs/meta-conversions-api