多渠道网站线索接收
本文档描述了一个单一的 API 契约,网站后端通过该契约在一个请求中将线索数据、访客联系详情和营销 UTM 指标发送到 ReactiveCRM。
1. 目的
网站集成者无需分别创建联系人、电话、邮箱、线索和营销事件。一个请求必须原子性地创建:
- 联系人;
- 联系人的主要电话;
- 联系人的主要邮箱(如果提供);
- 线索;
- 联系人与线索之间的关联;
- 营销事件和 UTM 归因。
如果任何步骤失败,整个请求将被回滚,部分创建的数据不会保存。
2. 端点
POST /api/site/leads
Authorization: Bearer <CRM_ACCESS_TOKEN>
Content-Type: application/json
令牌必须仅从网站后端或 Serverless 函数传递。绝不要将 CRM 令牌放在浏览器 JavaScript 中。
租户由授权令牌确定。所有提供的 UUID 都在此租户内进行验证。
3. 完整 JSON 契约
{
"externalId": "site-form-01J7K9A2M4Y5T6",
"lead": {
"leadSourceId": "7b33b18f-55bd-48a5-a8f0-e450a56dde47",
"quality": "WARM",
"message": "我想咨询 CRM 实施"
},
"contact": {
"firstName": "伊万",
"lastName": "伊万诺夫",
"phone": "+79991234567",
"email": "ivan@example.com"
},
"marketing": {
"occurredAt": "2026-09-06T18:00:00Z",
"visitorId": "visitor-8b7f",
"sessionId": "session-31ac",
"source": "website",
"channel": "paid",
"utmSource": "google",
"utmMedium": "cpc",
"utmCampaign": "summer-consulting",
"utmContent": "banner-a",
"utmTerm": "crm consultation",
"gclid": "EAIaIQobChMI-example",
"fbclid": null,
"landingUrl": "https://example.com/consultation",
"referrer": "https://www.google.com/"
}
}
4. 请求字段
4.1. 根字段
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
externalId | 字符串 | 推荐 | 用于幂等性的表单提交稳定唯一 ID |
lead | 对象 | 是 | 正在创建的线索数据 |
contact | 对象 | 是 | 联系人数据 |
marketing | 对象 | 否 | 营销访问的 UTM 指标和技术数据 |
externalId 在首次发送尝试之前生成。在超时或网络错误后重复请求时,请使用相同的值。
4.2. lead 对象
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
leadSourceId | uuid | 是 | 当前租户中的线索来源 ID |
quality | 字符串 | 否 | 初始评级:HOT、WARM、COOL 或 COLD |
message | 字符串 | 否 | 访客消息或提交评论 |
如果网站不执行预评估,最好不发送 quality 字段。
4.3. contact 对象
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
firstName | 字符串 | 是 | 联系人的名 |
lastName | 字符串 | 否 | 联系人的姓 |
phone | 字符串 | 是 | 主要电话;推荐 E.164 格式 |
email | 字符串(邮箱) | 否 | 联系人的主要邮箱 |
处理提交所需的最小数据是 firstName 和 phone。
4.4. marketing 对象
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
occurredAt | 日期-时间 | 否 | 表单提交时间;未提供时使用 CRM 时间 |
visitorId | 字符串 | 否 | 匿名访客 ID |
sessionId | 字符串 | 否 | 网站会话 ID |
source | 字符串 | 否 | 事件来源,默认为 website |
channel | 字符串 | 否 | 渠道:例如 paid、organic、social、email、direct |
utmSource | 字符串 | 否 | utm_source 值 |
utmMedium | 字符串 | 否 | utm_medium 值 |
utmCampaign | 字符串 | 否 | utm_campaign 值 |
utmContent | 字符串 | 否 | utm_content 值 |
utmTerm | 字符串 | 否 | utm_term 值 |
gclid | 字符串 | 否 | Google 点击 ID |
fbclid | 字符串 | 否 | Meta/Facebook 点击 ID |
landingUrl | 字符串 | 否 | 着陆页 URL |
referrer | 字符串 | 否 | 上一页 URL |
个人数据不得在营销对象中重复。姓名、电话、邮箱和消息文本仅在 contact 和 lead 中传递。
5. 最小请求
{
"externalId": "site-form-550e8400-e29b-41d4-a716-446655440000",
"lead": {
"leadSourceId": "7b33b18f-55bd-48a5-a8f0-e450a56dde47"
},
"contact": {
"firstName": "伊万",
"phone": "+79991234567"
}
}
6. 成功响应
首次请求 — 201 Created
{
"leadId": "22222222-2222-2222-2222-222222222222",
"contactId": "33333333-3333-3333-3333-333333333333",
"phoneId": "44444444-4444-4444-4444-444444444444",
"emailId": "55555555-5555-5555-5555-555555555555",
"marketingEventId": "66666666-6666-6666-6666-666666666666",
"duplicate": false,
"createdAt": "2026-09-06T18:00:01Z"
}
如果未提供邮箱或营销数据,相应的 ID 将以 null 返回。
使用相同 externalId 重复 — 200 OK
{
"leadId": "22222222-2222-2222-2222-222222222222",
"contactId": "33333333-3333-3333-3333-333333333333",
"phoneId": "44444444-4444-4444-4444-444444444444",
"emailId": "55555555-5555-5555-5555-555555555555",
"marketingEventId": "66666666-6666-6666-6666-666666666666",
"duplicate": true,
"createdAt": "2026-09-06T18:00:01Z"
}
重复请求不得创建第二个线索或联系人。
7. cURL 示例
curl -X POST "$CRM_BASE_URL/api/site/leads" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"externalId": "site-form-01J7K9A2M4Y5T6",
"lead": {
"leadSourceId": "7b33b18f-55bd-48a5-a8f0-e450a56dde47",
"quality": "WARM",
"message": "回电给我"
},
"contact": {
"firstName": "伊万",
"lastName": "伊万诺夫",
"phone": "+79991234567",
"email": "ivan@example.com"
},
"marketing": {
"utmSource": "google",
"utmMedium": "cpc",
"utmCampaign": "crm-demo",
"landingUrl": "https://example.com/demo"
}
}'
8. TypeScript 接口
type LeadQuality = 'HOT' | 'WARM' | 'COOL' | 'COLD';
interface SiteLeadRequest {
externalId?: string;
lead: {
leadSourceId: string;
quality?: LeadQuality;
message?: string;
};
contact: {
firstName: string;
lastName?: string;
phone: string;
email?: string;
};
marketing?: {
occurredAt?: string;
visitorId?: string;
sessionId?: string;
source?: string;
channel?: string;
utmSource?: string;
utmMedium?: string;
utmCampaign?: string;
utmContent?: string;
utmTerm?: string;
gclid?: string;
fbclid?: string;
landingUrl?: string;
referrer?: string;
};
}
interface SiteLeadResponse {
leadId: string;
contactId: string;
phoneId: string;
emailId: string | null;
marketingEventId: string | null;
duplicate: boolean;
createdAt: string;
}
9. 服务端示例
export async function sendLeadToCrm(payload: SiteLeadRequest): Promise<SiteLeadResponse> {
const response = await fetch(`${process.env.CRM_BASE_URL}/api/site/leads`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CRM_ACCESS_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
const body = await response.text();
throw new Error(`ReactiveCRM returned ${response.status}: ${body}`);
}
return response.json() as Promise<SiteLeadResponse>;
}
10. 错误
| HTTP | 原因 | 集成者操作 |
|---|---|---|
400 | 格式错误、缺少必填字段、邮箱/电话/quality 无效 | 修复数据;不要在不修改的情况下自动重试 |
401 | 令牌缺失或无效 | 刷新集成令牌 |
403 | 无权访问租户或操作 | 检查集成用户和角色 |
404 | 在当前租户中未找到 leadSourceId | 在网站设置中更新来源 ID |
409 | externalId 已链接到不兼容的请求 | 检查 ID 生成和集成日志 |
5xx | 临时 CRM 错误 | 使用相同的 externalId 重试相同请求 |
验证错误示例:
{
"status": 400,
"error": "Bad Request",
"message": "contact.phone must not be blank",
"path": "/api/site/leads"
}
11. 幂等性
externalId在租户和website来源内必须唯一。- 在首次请求之前生成
externalId并将其存储在网站提交中。 - 超时时,使用相同的正文和相同的
externalId重试请求。 - 重试单个提交时不要创建新的
externalId。 - 如果
duplicate: true,提交已处理并视为成功送达。
12. 网站开发者迷你指南
- 首次访问时,存储 UTM 标签、
gclid、fbclid、着陆 URL 和引用来源。 - 提交表单时,生成稳定的
externalId。 - 将表单发送到网站后端。
- 后端添加 CRM 令牌并调用
POST /api/site/leads。 - 在
201或200且duplicate: true时,视为提交已送达。 - 超时或
5xx时,使用相同的externalId重试请求。 - 绝不要从浏览器直接发送 CRM 令牌。
13. CRM 管理者获得的内容
成功请求后,CRM 包含一个线索,该线索:
- 已设置
leadSourceId来源; - 保留访客的消息;
- 如果网站提供了初始质量评级,则拥有该评级;
- 链接到具有姓名和主要电话的联系人;
- 如果提供了主要邮箱,则链接到该邮箱;
- 保留用于分析的 UTM 指标和广告标识符。
这些信息足以让管理者查看提交、联系联系人并评估线索。
Reactive CRM