ReactiveCRM 集成指南
为希望与 ReactiveCRM 构建自定义集成的公司(租户)提供的技术文档:导入线索和客户、创建交易、发送营销事件以及导出数据。
本文档仅涵盖外部集成中最常用的 API。内部参考数据和管理服务端点被有意排除在外。
1. 集成概述
典型的集成流程如下:
您的系统(后端 / 服务端代理)
|
| 1. POST /api/auth/login (获取访问 + 刷新令牌)
v
ReactiveCRM
| 2. 引用: GET /api/users/paged, GET /api/statuses, GET /api/stages, GET /api/lead-sources
| (获取 ownerId、authorId、statusId 等的 UUID)
v
| 3. 核心操作:
| POST /api/leads/create — 创建线索
| POST /api/clients/create — 创建客户
| POST /api/contacts/create — 创建联系人
| POST /api/deals/create — 创建交易
| POST /api/dashboard/marketing/events — 发送营销事件
| POST /api/leads/import/batch — 批量导入线索
v
| 4. 读取 / 导出:
| GET /api/leads/paged — 带过滤器的分页读取
| GET /api/export/leads — 所有线索的 NDJSON 导出
关键安全规则:绝不要从最终用户的浏览器直接调用 CRM API。将 CRM 令牌和内部标识符保存在您的后端(或 Serverless 函数)中。
2. 认证
2.1. 获取令牌
认证端点不需要令牌:
| 方法 | URL | 描述 |
|---|---|---|
POST | /api/auth/login | 使用用户名 + 密码登录,返回访问 + 刷新令牌 |
POST | /api/auth/refresh | 将刷新令牌交换为新的令牌对 |
POST | /api/auth/logout | 撤销刷新令牌 |
curl -X POST "$CRM_BASE_URL/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"username": "integration", "password": "secret123"}'
{
"token": "eyJhbGciOiJIUzI1NiJ9...",
"refreshToken": "a8f3k2m9Qx7Tt1Vv...",
"tokenType": "Bearer",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"firstName": "集成",
"lastName": "机器人",
"tenantId": "660e8400-e29b-41d4-a716-446655440001"
},
"tenant": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Zunga Corp"
}
}
2.2. 令牌处理规则
- 访问令牌(
token)— 一个有效期为 1 小时 的 JWT。在每个请求中发送:Authorization: Bearer <token>。 - 刷新令牌(
refreshToken)— 一个有效期为 7 天 的随机字符串。用于获取新的令牌对。 - 每次
/api/auth/refresh时,服务器会轮换刷新令牌:旧令牌被删除,新令牌被签发。请持久保存这两个新值。 - 使用过期访问令牌的请求会返回
401。在这种情况下,刷新并重试原始请求 — 不要再次登录。
2.3. 基础设置
CRM_BASE_URL=https://crm.example.com
以下所有示例都假设使用这些头信息:
Authorization: Bearer <CRM_ACCESS_TOKEN>
Content-Type: application/json
3. 分页 API 约定
所有形式为 GET /api/*/paged 的列表端点都遵循相同的约定:
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
page | 整数 | 0 | 页码,从 0 开始 |
size | 整数 | 每个端点不同 | 页面大小 |
sort | 字符串 | createdAt,desc | 排序格式为 字段,方向。方向:asc 或 desc |
分页响应结构
{
"content": [ { "..." } ],
"page": 0,
"size": 20,
"totalElements": 137,
"totalPages": 7
}
日期过滤
使用 字段From / 字段To 参数进行范围过滤(ISO 8601):
createdAtFrom=2026-01-01T00:00:00Z
createdAtTo=2026-01-31T23:59:59Z
排序
始终使用 ?sort=字段,方向:
?sort=createdAt,desc
?sort=name,asc
某些过滤器字段有专用的范围参数(例如
dealAmountFrom/dealAmountTo)。
过滤语义
- 所有过滤和排序均在服务端执行(无需下载全部数据再在客户端过滤)。
- 多个过滤器以 AND 组合。
- 文本(子字符串)过滤器使用不区分大小写的搜索(ILIKE)。
- 通用
search过滤器跨多个字段以 OR 进行搜索。
4. 引用(获取 UUID)
在创建实体之前,请获取相关引用数据的 UUID。主要引用包括:
4.1. 用户(GET /api/users/paged)
用于 ownerId、authorId、developingManagerIds。
curl "$CRM_BASE_URL/api/users/paged?page=0&size=50&sort=createdAt,asc" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
响应示例(content 片段):
[
{
"id": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"firstName": "Roman",
"lastName": "Posledovskiy",
"username": "roman",
"email": "roman@example.com",
"tenantId": "660e8400-e29b-41d4-a716-446655440001"
}
]
4.2. 状态(GET /api/statuses)
用于线索、交易和交易参与方客户的 statusId。返回一个数组:
curl "$CRM_BASE_URL/api/statuses" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "New",
"entityType": "LEAD"
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"name": "In progress",
"entityType": "STAGE"
}
]
4.3. 阶段(GET /api/stages)
用于交易的 stageId:
curl "$CRM_BASE_URL/api/stages" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
4.4. 线索来源(GET /api/lead-sources)
返回线索来源的树形结构。用于线索的 leadSourceId:
curl "$CRM_BASE_URL/api/lead-sources" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
[
{
"id": "cccc0001-0000-0000-0000-000000000001",
"name": "Website",
"children": [
{
"id": "cccc0001-0000-0000-0000-000000000002",
"name": "Feedback form",
"children": []
}
]
}
]
5. 线索
5.1. 创建线索(POST /api/leads/create)
curl -X POST "$CRM_BASE_URL/api/leads/create" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "网站咨询:咨询",
"ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"leadSourceId": "cccc0001-0000-0000-0000-000000000002",
"statusId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"quality": "WARM"
}'
请求字段:
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
message | 字符串 | 否 | 消息 / 咨询文本 |
ownerId | uuid | 是 | 负责用户 |
authorId | uuid | 是 | 创建线索的用户 |
clientId | uuid | 否 | 关联客户 |
contactId | uuid | 否 | 关联联系人 |
leadSourceId | uuid | 否 | 线索来源树节点 |
statusId | uuid | 否 | 状态 |
quality | 枚举 | 否 | HOT、WARM、COOL、COLD |
201 Created 响应示例:
{
"id": "22222222-2222-2222-2222-222222222222",
"message": "网站咨询:咨询",
"status": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "New"
},
"quality": "WARM",
"dealId": null,
"createdAt": "2026-09-05T20:00:00Z",
"updatedAt": "2026-09-05T20:00:00Z",
"version": 0,
"author": {
"id": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"firstName": "Roman",
"lastName": "Posledovskiy"
},
"owner": {
"id": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"firstName": "Roman",
"lastName": "Posledovskiy"
}
}
请保留返回的
id— 营销事件的leadId需要用到它(参见第 8 节)。
5.2. 分页读取(GET /api/leads/paged)
curl "$CRM_BASE_URL/api/leads/paged?page=0&size=20&createdAtFrom=2026-09-01T00:00:00Z&sort=createdAt,desc" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
关键过滤器:
| 参数 | 类型 | 模式 | 描述 |
|---|---|---|---|
statusId | uuid | 精确 | 按状态过滤 |
leadSourceId | uuid | 精确 | 按线索来源过滤 |
quality | 枚举 | 精确 | HOT、WARM、COOL、COLD |
message | 字符串 | ILIKE | 消息中的子字符串 |
search | 字符串 | ILIKE(OR) | 跨消息、联系人、邮箱、电话搜索 |
contactEmail | 字符串 | ILIKE | 按联系人邮箱 |
contactPhone | 字符串 | ILIKE | 按联系人电话 |
company | 字符串 | ILIKE | 按公司名称 |
clientId | uuid | 精确 | 按客户 ID |
createdAtFrom / createdAtTo | 日期-时间 | 范围 | 按创建日期 |
updatedAtFrom / updatedAtTo | 日期-时间 | 范围 | 按更新日期 |
createdBy | uuid | 精确 | 按线索作者 |
还有关联交易的过滤器:dealStatusId、dealStageId、dealAmountFrom/dealAmountTo、dealProbabilityFrom/dealProbabilityTo。
排序:createdAt、updatedAt、message、quality、状态/来源等(字段,方向 格式)。
5.3. 获取单个线索(GET /api/leads/{id})
curl "$CRM_BASE_URL/api/leads/$LEAD_ID" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
5.4. 批量导入线索(POST /api/leads/import/batch)
如需批量导入大量线索,请使用批处理端点。它接受一个线索数组,创建导入历史记录,并允许回滚整个导入。
curl -X POST "$CRM_BASE_URL/api/leads/import/batch" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fileName": "leads-2026-09-05.csv",
"leads": [
{
"message": "咨询 #1",
"ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"quality": "WARM"
},
{
"message": "咨询 #2",
"ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"quality": "COOL"
}
]
}'
响应示例:
{
"importId": "44444444-4444-4444-4444-444444444444",
"imported": 2,
"total": 2,
"skipped": []
}
imported— 已创建的数量。skipped— 跳过的行数组,包含index(从 0 开始)和reason。
历史记录与回滚:
# 导入历史
curl "$CRM_BASE_URL/api/leads/import/history" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
# 回滚导入
curl -X POST "$CRM_BASE_URL/api/leads/import/rollback/$IMPORT_ID" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
5.5. 快速网站线索(POST /api/site/leads)
对于网站表单,有一个组合端点,可在一次请求中原子性地创建联系人、其主要电话和邮箱、线索、联系人-线索关联以及营销事件 — 通过 externalId 实现幂等性。
请参阅专门指南:site-lead-multi-contract.md。
6. 客户与联系人
6.1. 创建客户(POST /api/clients/create)
curl -X POST "$CRM_BASE_URL/api/clients/create" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "COMPANY",
"name": "Romashka LLC",
"taxId": "7700000001",
"regNumber": "1234567890",
"country": "RU",
"phone": "+7-495-000-00-01",
"email": "info@romashka.ru",
"website": "https://romashka.ru",
"ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35"
}'
关键字段:
| 字段 | 类型 | 适用对象 | 描述 |
|---|---|---|---|
type | 枚举 | 全部 | INDIVIDUAL 或 COMPANY(必填) |
name | 字符串 | 全部 | 显示名称(必填) |
firstName / lastName | 字符串 | INDIVIDUAL | 名/姓 |
taxId | 字符串 | COMPANY | 税号(INN) |
regNumber | 字符串 | COMPANY | 注册号 |
legalAddress | 字符串 | COMPANY | 法定地址 |
phone / email / website | 字符串 | 全部 | 联系方式 |
country | 字符串 | 全部 | ISO 国家代码 |
ownerId | uuid | 全部 | 负责用户 |
authorId | uuid | 全部 | 作者 |
developingManagerIds | uuid[] | 全部 | 开发经理 |
6.2. 分页读取客户(GET /api/clients/paged)
curl "$CRM_BASE_URL/api/clients/paged?page=0&size=20&type=COMPANY&search=Romashka&sort=name,asc" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
关键过滤器:name、type(INDIVIDUAL/COMPANY)、country、taxId、email、phone、lastName(个人)、search(按名称/税号/电话)、createdAtFrom/createdAtTo、createdBy、developingManagerId。
6.3. 重复检查(GET /api/clients/duplicates)
在创建客户之前,检查是否已存在相似客户:
# 按税号和名称
curl "$CRM_BASE_URL/api/clients/duplicates?type=COMPANY&taxId=7700000001&name=Romashka" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
6.4. 创建联系人(POST /api/contacts/create)
curl -X POST "$CRM_BASE_URL/api/contacts/create" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Ivan",
"lastName": "Petrov",
"dateOfBirth": "1990-05-15",
"gender": "MALE",
"countryCode": "RU",
"ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35"
}'
字段:firstName(必填)、lastName、patronymicName、dateOfBirth(date)、gender(MALE/FEMALE)、countryCode、ownerId、authorId。
6.5. 分页读取联系人(GET /api/contacts/paged)
curl "$CRM_BASE_URL/api/contacts/paged?page=0&size=20&search=Petrov&sort=createdAt,desc" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
7. 交易
7.1. 创建交易(POST /api/deals/create)
curl -X POST "$CRM_BASE_URL/api/deals/create" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "服务器硬件交付",
"clientId": "9f128931-69fd-493a-9a08-be5be0e6603d",
"statusId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"stageId": "dddd0001-0000-0000-0000-000000000001",
"probability": 60,
"amount": 150000.00,
"ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
"authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35"
}'
关键字段:
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | 字符串 | 是 | 交易名称 |
clientId | uuid | 是 | 客户 ID |
statusId | uuid | 否 | 状态(阶段状态) |
stageId | uuid | 否 | 销售阶段 |
probability | 整数 | 否 | 概率 0-100 |
amount | 数字 | 否 | 金额 |
plannedAmount | 数字 | 否 | 计划金额 |
discountPercent | 整数 | 否 | 折扣 0-100 |
startDate / expectedCloseDate | 日期-时间 | 否 | 日期 |
ownerId | uuid | 否 | 所有者 |
leadId | uuid | 否 | 关联线索 |
contactId | uuid | 否 | 关联联系人 |
productIds | uuid[] | 否 | 产品(简化格式) |
dealProducts | 数组 | 否 | 交易行项目(完整格式) |
dealParties | 数组 | 否 | 交易参与方 |
7.2. 分页读取交易(GET /api/deals/paged)
curl "$CRM_BASE_URL/api/deals/paged?page=0&size=20&stageKind=OPEN&sort=createdAt,desc" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
关键过滤器:name(ILIKE)、clientId、clientName、statusId、stageId、stageKind(OPEN/WON/LOST)、ownerId、search、startDateFrom/startDateTo、expectedCloseDateFrom/expectedCloseDateTo、actualCloseDateFrom/actualCloseDateTo、createdAtFrom/createdAtTo。
8. 营销事件(归因)
要发送 UTM 标签、广告标识符和流量来源,请使用:
POST /api/dashboard/marketing/events
curl -X POST "$CRM_BASE_URL/api/dashboard/marketing/events" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"eventType": "lead_submitted",
"occurredAt": "2026-09-05T20:00:00Z",
"visitorId": "visitor-8b7f",
"sessionId": "session-31ac",
"leadId": "22222222-2222-2222-2222-222222222222",
"externalId": "site-form-submit-20260905-000123",
"source": "website",
"channel": "paid",
"utmSource": "google",
"utmMedium": "cpc",
"utmCampaign": "summer-consulting",
"utmContent": "banner-a",
"utmTerm": "crm consultation",
"gclid": "EAIaIQobChMI-example",
"landingUrl": "https://www.example.com/consultation",
"referrer": "https://www.google.com/",
"metadata": {
"formName": "consultation",
"pageType": "landing"
}
}'
响应示例:
{
"accepted": true,
"duplicate": false,
"eventId": "33333333-3333-3333-3333-333333333333"
}
规则:
- 构建一个稳定的
externalId(UUID 或唯一的 requestId)。对相同的source/租户使用相同的externalId重新发送会返回duplicate: true— 这不是错误。 - 重试时不要生成新的
externalId。 - 不要 将个人身份信息(邮箱、电话、姓名、消息文本)放入
metadata。仅允许技术属性,如表单名称或页面类型。
详情请参见 site-leads-integration-guide.md。
9. 数据导出(NDJSON)
导出端点以 NDJSON 格式返回租户的所有记录(每行一个 JSON 对象,以 \n 分隔)。
| 端点 | 描述 |
|---|---|
GET /api/export/leads | 所有租户线索 |
GET /api/export/clients | 所有租户客户 |
GET /api/export/contacts | 所有租户联系人 |
curl "$CRM_BASE_URL/api/export/leads" \
-H "Authorization: Bearer $CRM_ACCESS_TOKEN"
响应示例(行流):
{"id":"550e8400-e29b-41d4-a716-446655440001","message":"网站咨询","quality":"WARM","statusName":"New","createdAt":"2026-08-20T10:00:00+03:00","ownerName":"Ivan Ivanov","clientName":"Romashka LLC","contactFirstName":"Petr","contactLastName":"Petrov","leadSourceName":"Paid search"}
{"id":"550e8400-e29b-41d4-a716-446655440002","message":"电话","quality":"COOL","statusName":"In progress","createdAt":"2026-08-19T09:00:00+03:00","ownerName":"Maria Smirnova","clientName":null}
重要:NDJSON 不是有效的 JSON 数组。请通过 ReadableStream 逐行读取响应(不要对整个响应调用 JSON.parse())。
10. 端到端集成示例
以下场景创建了一个网站线索,关联了联系人和客户,创建了交易,并发送了营销事件。
CRM_BASE_URL=https://crm.example.com
CRM_TOKEN="<access-token>"
# 1. 登录
curl -s -X POST "$CRM_BASE_URL/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"username": "integration", "password": "secret123"}' | tee /tmp/login.json
CRM_TOKEN=$(jq -r '.token' /tmp/login.json)
OWNER_ID=$(curl -s "$CRM_BASE_URL/api/users/paged?page=0&size=50" \
-H "Authorization: Bearer $CRM_TOKEN" | jq -r '.content[0].id')
# 2. 创建客户
curl -s -X POST "$CRM_BASE_URL/api/clients/create" \
-H "Authorization: Bearer $CRM_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"type\": \"COMPANY\",
\"name\": \"Romashka LLC\",
\"taxId\": \"7700000001\",
\"country\": \"RU\",
\"ownerId\": \"$OWNER_ID\",
\"authorId\": \"$OWNER_ID\"
}" | tee /tmp/client.json
CLIENT_ID=$(jq -r '.id' /tmp/client.json)
# 3. 创建联系人
curl -s -X POST "$CRM_BASE_URL/api/contacts/create" \
-H "Authorization: Bearer $CRM_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"firstName\": \"Ivan\",
\"lastName\": \"Petrov\",
\"countryCode\": \"RU\",
\"ownerId\": \"$OWNER_ID\",
\"authorId\": \"$OWNER_ID\"
}" | tee /tmp/contact.json
CONTACT_ID=$(jq -r '.id' /tmp/contact.json)
# 4. 创建线索
curl -s -X POST "$CRM_BASE_URL/api/leads/create" \
-H "Authorization: Bearer $CRM_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"message\": \"网站咨询\",
\"clientId\": \"$CLIENT_ID\",
\"contactId\": \"$CONTACT_ID\",
\"ownerId\": \"$OWNER_ID\",
\"authorId\": \"$OWNER_ID\",
\"quality\": \"WARM\"
}" | tee /tmp/lead.json
LEAD_ID=$(jq -r '.id' /tmp/lead.json)
# 5. 创建关联线索的交易
curl -s -X POST "$CRM_BASE_URL/api/deals/create" \
-H "Authorization: Bearer $CRM_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"为 Ivan Petrov 提供咨询\",
\"clientId\": \"$CLIENT_ID\",
\"leadId\": \"$LEAD_ID\",
\"contactId\": \"$CONTACT_ID\",
\"amount\": 50000.00,
\"ownerId\": \"$OWNER_ID\",
\"authorId\": \"$OWNER_ID\"
}"
# 6. 发送营销事件
curl -s -X POST "$CRM_BASE_URL/api/dashboard/marketing/events" \
-H "Authorization: Bearer $CRM_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"eventType\": \"lead_submitted\",
\"occurredAt\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
\"leadId\": \"$LEAD_ID\",
\"externalId\": \"request-$(uuidgen)\",
\"source\": \"website\",
\"channel\": \"direct\",
\"landingUrl\": \"https://www.example.com/form\",
\"metadata\": {\"formName\": \"consultation\"}
}"
11. 幂等性与错误处理
- 稳定标识符:为每次提交生成您自己的
externalId(UUID 或 requestId)。重新发送相同的externalId不得创建重复项(对于营销事件,这由服务器处理 —duplicate: true)。 - 使用相同标识符重试:发生网络错误时,使用相同的
externalId重试;不要生成新的。 - 不要盲目重复:如果创建请求超时,请先验证结果(使用您自己的 requestId 或查找已创建的实体),而不是创建新的。
400:无效负载 — 不修改数据直接重试无济于事;请修正数据。401:访问令牌过期 — 调用/api/auth/refresh并重试请求。403:无权限 — 检查角色和租户。5xx/超时:临时错误 — 使用相同的externalId重试(对于线索,请使用队列)。
12. 快速开始
- 认证:通过
POST /api/auth/login进行认证;保存token和refreshToken。 - 添加:在每个请求中添加
Authorization: Bearer <token>。遇到401时,通过/api/auth/refresh刷新。 - 获取引用:一次获取引用(用户/状态/阶段/线索来源)并缓存 UUID。
- 创建实体:按逻辑顺序创建:客户 → 联系人 → 线索 → 交易。
- 使用分页端点:进行带服务端过滤和排序的读取。
- 导出:使用 NDJSON 端点并逐行读取流。
- 批量导入:使用批处理端点(
/api/leads/import/batch、/api/clients/import/batch)并支持回滚。 - 发送营销归因:通过
POST /api/dashboard/marketing/events并使用稳定的externalId。 - 绝不存储 或在营销事件的
metadata中传递 PII。 - 查看各 API 的详细文档:
site-leads-integration-guide.md。
Reactive CRM