代理机构 API
作为代理机构,您可以使用客户所使用的相同 REST API,但将单个请求指向您管理的某个子账户,而不是您自己的账户。这使您可以构建能够端到端引导客户的工具——创建他们的 AI 智能体、在知识库上训练他们的 AI、导入他们的联系人、连接他们的消息渠道以及购买电话号码——所有这些都无需手动登录每个子账户。
本页面仅涵盖代理机构特有的行为:如何使用 sub_account_id 参数代表子账户执行操作。有关基础知识(生成密钥、身份验证、基础 URL、错误格式、速率限制),请从 API 访问 指南开始。其中的所有内容也适用于此处——您使用您的代理机构账户的 API 密钥进行身份验证。
注意: 本页面内容偏向技术性。如果您不是开发人员,请将其分享给负责构建集成的人员。
“代表执行”的工作原理
默认情况下,每个 API 请求都作用于拥有该 API 密钥的账户,即您的代理机构账户。要改为作用于受管理的客户账户,请在请求中添加可选的 sub_account_id 参数,并将其设置为该客户的账户 ID。
- 省略
sub_account_id→ 请求作用于您自己的代理机构账户。 - 包含
sub_account_id→ 请求作用于该子账户,但前提是平台确认该子账户确实属于您。
您始终使用代理机构账户的 API 密钥进行身份验证。您永远不需要子账户自己的密钥,也无需处理子账户的凭据。
如何使用
- GET / DELETE 端点 → 作为查询参数传递:
?sub_account_id=THE_SUB_ACCOUNT_ID(与您的apiKey一起,如果您通过查询进行身份验证)。 - POST / PUT / PATCH 端点 → 在 JSON 请求体中将其包含为
"sub_account_id": "THE_SUB_ACCOUNT_ID"。 - AI 助手 → 无需配置。MCP 服务器在其工具上携带相同的设置,因此使用您的代理密钥建立的一个连接即可报告所有客户:只需在请求中指明客户名称(例如“Bella’s Bistro 有多少联系人?”)。写操作也同样可用:每个接受
sub_account_id的端点都会作为工具公开,因此您可以从同一个连接中代表客户进行创建、更改和发送操作。
查找子账户的 ID
sub_account_id 是客户账户的唯一 ID。您可以从 SubAccounts API 端点(请参阅 子账户 指南)或侧边栏的 Sub Accounts 页面获取您的子账户列表及其 ID。
所有权始终会经过验证
当您传递 sub_account_id 时,平台会检查该账户是否为真实的子账户且是否属于您的代理机构。只有这样,请求才会通过。
如果 ID 未知、不是子账户或属于其他代理机构,请求将失败并返回 404 响应:
{
"success": false,
"error_code": 404,
"error": "Sub-account not found."
}
为什么返回 404 而不是 403? “禁止访问”(forbidden)响应会告诉外部人员该 ID 存在但并不属于他们。对“不存在”和“不属于你”的情况返回相同的
404,意味着该端点无法被用于探测哪些账户 ID 属于其他代理机构。在此处将404视为“这不是你管理的子账户”。
支持 sub_account_id 的位置
sub_account_id 基本上适用于所有的资源端点——即任何创建、读取、更新或删除账户自身数据的调用。实际上,你可以使用你的代理机构密钥来配置和运行整个子账户的设置:
- AI 设置 — 营销活动、智能体、常见问题解答、知识库来源(网站爬取和文档上传)、知识库分组、广播、自定义函数、MCP 服务器
- 联系人与 CRM — 联系人(包括导入)、列表、标签、任务、交易、预约、事件
- 渠道与号码 — 连接 WhatsApp / WhatsApp Web / Telegram / Instagram & Messenger / LINE,搜索 / 购买 / 管理电话号码,WhatsApp 模板,渠道路由
- 消息与内容 — 发送消息、聊天会话、聊天导出、每日摘要
- 设置与集成 — Webhook、聊天小部件配置、白标配置、BYOK 短信及其他账户设置、分析、错误日志
在所有这些参数中,该参数都是可选的——如果省略它,调用将作用于您自己的代理账户,因此一个集成即可同时服务两者。额度和使用量始终来自您定位的账户:子账户的 AI 回复、消息、标签和号码的费用将计入子账户的余额。
不适用的情况
少数端点属于代理机构级别或自引用端点,会忽略 sub_account_id:
- 管理子账户本身 — 子账户端点(创建 / 列出 / 更新子账户)和 BYOK 消费限额端点已经在其 URL 路径中指定了子账户。定价和策略端点以及聊天监控端点遵循相同的模式。
- 在账户之间复制代理 —
POST /v1/subaccounts/agents/copy本身指定了两个账户,将目标账户作为targetUserId。请参阅下方的工作示例。(旧版POST /v1/subaccounts/campaigns/copy的工作方式相同,但已与营销活动 API 的其余部分一起被弃用。) - 调整额度以及两个代理范围内的汇总 —
POST /v1/subaccounts/credits通过email来标识子账户;GET /v1/subaccounts/credit-usage和GET /v1/subaccounts/campaign-status会一次性报告所有子账户,因此没有单一的账户目标。 - 您代理机构自己的账户 — API 密钥管理、代理使用情况报告、团队管理以及您的定价层级始终作用于您的代理账户。
- 向列表添加联系人或从中移除联系人:
POST/DELETE /v1/contacts/lists和POST /v1/contacts/lists/batch作用于拥有该密钥的账户。创建、编辑和删除列表本身(/v1/lists)确实需要sub_account_id。 - 入站消息 Webhook — 外部系统向其发送数据的端点绑定到配置它们的凭据所属的账户,因此无需重定向。
每个端点接受哪些参数的实时、机器可读列表位于你的仪表板 API 参考(设置 → 集成 → API 密钥)以及
GET /v1/docs/openapi.yaml处的 OpenAPI 规范中。我们经常发布 API 变更——请以这些内容为准。

设置 → 集成 → API 密钥 — 您代理机构的密钥位于此处,旁边还有指向完整 API 参考文档的链接。
列出您的子账户,或查询某个邮箱
GET /v1/subaccounts
如果不带参数调用,它将以 data 数组的形式返回您代理机构下的所有子账户。添加可选的 email 查询参数以查找单个客户:
curl "https://api.dmchamp.com/v1/[email protected]&apiKey=YOUR_API_KEY"
- 该邮箱属于您的某个活跃子账户 → HTTP
200,仅返回该账户:{ "success": true, "data": { ... } }。 - 不属于 → HTTP
404,Agency Sub Account not found。
没有直接返回“是”或“否”的参数,因此请读取状态码:200 表示该邮箱是您的客户之一,404 表示不是。已删除的子账户会被排除,因此您移除的账户也会显示为 404。
每个账户返回的信息包括其个人资料、设置、使用限额以及已启用的功能,这些正是您在自己的仪表板中显示客户行所需的一切信息。
响应中绝不会包含凭据。API 密钥、密码、登录令牌以及客户已连接渠道(Twilio、Google、Meta 和自带密钥)的详细信息在发送前都会被移除。没有用于选择返回哪些字段的参数,因此请读取您需要的字段并忽略其余部分。
需要 API 访问权限和代理机构账户。
创建客户账户
POST /v1/subaccounts
创建账户只需调用一次,包含客户的邮箱、姓名和企业名称。在构建注册流程之前,有几点值得了解。
您无法选择密码。 没有密码字段:系统会自动为您生成一个密码,并作为 temporary_password 在 201 响应中返回一次。请立即存储或转发它,因为之后将无法再次查看。客户可以从其个人资料中更改密码,或从登录界面重置密码。
curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"first_name": "Alex",
"last_name": "Client",
"business_name": "Client Co",
"send_account_info_to_sub_account": true
}'
除非您要求,否则不会向客户发送任何邮件。 默认情况下,账户是在静默状态下创建的,通知客户是您的工作。发送 send_account_info_to_sub_account: true,他们就会收到一封欢迎邮件,其中包含他们的邮箱地址、临时密码以及登录链接,所有内容均在您自己的白标域名下并以您的品牌呈现。
该标志仅涵盖客户的电子邮件。您的代理机构始终会收到“已创建新子账户”的通知,但其中绝不包含密码:出于安全考虑,201 响应是您获取密码的唯一途径。如果密码丢失,客户可以在登录屏幕上通过“忘记密码”自行设置。
开篇额度由您设定。 usage_limits.credits 是客户的初始消费限额,usage_limits.monthly_credits 是每月循环额度。发送 "credits": 0,账户初始将没有任何可用额度;省略 credits,账户将以 100 点一次性余额启动,以便 AI 可以立即开始回答。在创建时,两者都不会从您的代理机构额度池中扣除任何内容:只有当客户实际使用额度时,才会从您的额度池中扣除。
企业名称在您的代理机构内必须是唯一的。 您的两个客户不能同时叫“Client Co”,因为该名称是用于在您的仪表板和报告中标识账户的依据。其他代理机构的名称不受此限制。
当调用失败时:
| 状态 | 发生了什么 |
|---|---|
400 |
缺少字段或字段错误,邮箱地址无效,或者您使用的密钥不属于代理机构账户。 |
401 |
API 密钥错误、已过期或已撤销。 |
402 |
您自己的订阅未激活,因此在解决账单问题之前无法创建新的客户账户。 |
403 |
您已达到套餐允许的客户账户数量上限。 |
409 |
该企业名称已被您的某个客户使用,或者该邮箱已属于某个账户。 |
删除客户账户
DELETE /v1/[email protected] (或 ?uid=SUB_ACCOUNT_UID)
curl -X DELETE "https://api.dmchamp.com/v1/[email protected]" \
-H "X-API-Key: YOUR_AGENCY_API_KEY"
这与“子账户”页面上的删除按钮功能相同,且无法撤销。客户会立即被锁定,不再计入您的客户总数;他们的对话、联系人、坐席和已连接的渠道将在接下来的几分钟内在后台被清除。客户通过您的结账页面购买的套餐将被取消。
{
"success": true,
"message": "Sub-account deletion started",
"data": { "uid": "SUB_ACCOUNT_UID", "email": "[email protected]", "status": "deletion_started" }
}
- 传入
email或uid。如果两者都传入,它们必须指向同一个客户。 - 只能删除您自己的客户。任何其他电子邮件或 uid,以及已被删除的客户,都会返回
404。 - 在删除操作仍在进行时再次调用,会返回带有
"status": "already_in_progress"的200。 - 通过 MCP 服务器 连接的 AI 助手在连接到标准 MCP 地址时,会将此作为
delete_subaccount工具(代理工具不包含在白标 MCP 地址中)。 - 若要暂时停止客户而不丢失任何内容,请改为 暂停他们:他们会被锁定,所有内容都会保留,且只需一次调用即可恢复。
示例:为子账户连接 Instagram 和 Messenger
连接 Instagram 和 Messenger 是一个基于浏览器的流程。你通过 API 启动它,将返回的授权 URL 交给客户(或为他们打开),等待他们在浏览器中进行授权,然后选择要连接的页面——所有这些操作都在使用 sub_account_id 针对其子账户的情况下完成。
第 1 步 — 启动连接
在请求体中使用客户的 sub_account_id 调用连接端点。此处不发送凭据;平台会返回一个客户必须在浏览器中打开的授权 URL,以及一个一次性的关联令牌。
cURL
curl -X POST "https://api.dmchamp.com/v1/channels/meta/connect?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sub_account_id": "abc123def456"
}'
JavaScript
const res = await fetch("https://api.dmchamp.com/v1/channels/meta/connect", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
sub_account_id: "abc123def456",
}),
});
const data = await res.json();
// data.oauth_url -> open this in the client's browser
Python
import requests
res = requests.post(
"https://api.dmchamp.com/v1/channels/meta/connect",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"sub_account_id": "abc123def456",
},
)
data = res.json()
# data["oauth_url"] -> open this in the client's browser
响应:
{
"success": true,
"oauth_url": "https://www.facebook.com/v21.0/dialog/oauth?client_id=...&state=...",
"state_token": "8sFq2yV0kQ7m4n1pZr3tWb6cXe9hJl2aD5gK7uN0oI",
"expires_at": "2026-06-10T12:30:00.000Z"
}
将客户端引导至浏览器中的 oauth_url 进行授权。state_token 用于关联此尝试,且是一个短效密钥,请勿记录它。该尝试将于 expires_at 过期;如果过期,请重新开始。
第 2 步 — 轮询直到页面加载
在客户端授权后,轮询状态端点(使用相同的 sub_account_id,此次作为查询参数),直到出现可连接的页面。
cURL
curl "https://api.dmchamp.com/v1/channels/meta/status?apiKey=YOUR_API_KEY&sub_account_id=abc123def456"
JavaScript
const res = await fetch(
"https://api.dmchamp.com/v1/channels/meta/status?sub_account_id=abc123def456",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
// Wait until data.status === "pages_loaded", then read data.pages
Python
import requests
res = requests.get(
"https://api.dmchamp.com/v1/channels/meta/status",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"sub_account_id": "abc123def456"},
)
data = res.json()
# Wait until data["status"] == "pages_loaded", then read data["pages"]
响应:
{
"success": true,
"status": "pages_loaded",
"pages": [
{
"id": "1098765432101234",
"name": "Acme Studio",
"category": "Hair Salon",
"instagram_business_account": {
"id": "17841400000000000",
"username": "acme.studio"
}
}
],
"selected_page": null
}
status 字段会经历 pending → token_received → pages_loaded → connected 的状态变化。请等待 pages_loaded 状态出现后再选择页面。除了正常流程,还可能出现两种终止错误状态:failed 和 expired(客户端拒绝了授权,或状态令牌的约 30 分钟有效期已过)——当发生这些情况时,会包含一个 reason 字段。如果看到这些状态,请停止轮询并从第 1 步重新开始;不要无限期地等待 pending。页面访问令牌永远不会被返回。
第 3 步 — 选择要连接的页面
从第 2 步获取的页面 ID 中选择一个。选择页面将同时连接该页面的 Instagram 和 Messenger。请再次在正文中包含 sub_account_id。
cURL
curl -X POST "https://api.dmchamp.com/v1/channels/meta/select-page?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"page_id": "1098765432101234",
"sub_account_id": "abc123def456"
}'
JavaScript
const res = await fetch("https://api.dmchamp.com/v1/channels/meta/select-page", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
page_id: "1098765432101234",
sub_account_id: "abc123def456",
}),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.dmchamp.com/v1/channels/meta/select-page",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"page_id": "1098765432101234",
"sub_account_id": "abc123def456",
},
)
data = res.json()
响应:
{
"success": true,
"page_id": "1098765432101234",
"instagram_business_account_id": "17841400000000000"
}
完成 — Instagram 和 Messenger 现已连接到客户端的子账户。您只需提供 page_id;底层凭据会在服务器端解析,绝不会通过您的集成进行传递。
示例:为子账户购买号码
购买号码的方式相同:在查询中使用 sub_account_id 进行搜索,然后在正文中使用它进行购买。积分将从子账户的余额中扣除,号码也会配置在该子账户下。
搜索 (cURL):
curl "https://api.dmchamp.com/v1/phone-numbers/available?apiKey=YOUR_API_KEY&country_code=US&sub_account_id=abc123def456"
购买 (JavaScript):
const res = await fetch("https://api.dmchamp.com/v1/phone-numbers", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
phone_number: "+14155551234",
country_code: "US",
display_name: "Support line",
sub_account_id: "abc123def456",
}),
});
const data = await res.json();
购买 (Python):
import requests
res = requests.post(
"https://api.dmchamp.com/v1/phone-numbers",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"phone_number": "+14155551234",
"country_code": "US",
"display_name": "Support line",
"sub_account_id": "abc123def456",
},
)
data = res.json()
响应:
{
"success": true,
"phone_number": "+14155551234",
"channel": "whatsapp",
"whatsapp_status": "PURCHASED",
"outgoing_status": "PURCHASED",
"status": "PURCHASED",
"purchase_credits": 11.5,
"monthly_credits": 11.5
}
号码将处于 PURCHASED 状态,WhatsApp 发送方注册会在后台继续进行。请轮询 GET /v1/phone-numbers/{phoneNumber}/status?sub_account_id=abc123def456,直到状态变为 ONLINE 后再发送消息。
工作示例:将模板智能体部署到每个新客户
常见的代理商模式是在您的代理商账户中保留一个主智能体,将其调整为您希望每个客户开始时使用的状态,并在配置时将副本分发到每个新子账户中。这只需三次调用,之后无需重复操作:副本会保留其设置,直到您更改它们为止。
第 1 步 — 复制智能体
POST /v1/subaccounts/agents/copy
curl -X POST "https://api.dmchamp.com/v1/subaccounts/agents/copy?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "YOUR_TEMPLATE_AGENT_ID",
"targetUserId": "abc123def456",
"newName": "Inbound Instagram Leads",
"copyFaqs": true
}'
响应中包含新智能体的 ID,位于 data.agent_id。常见问题解答、知识库和媒体库会一并复制;源账户的 WhatsApp 模板、已连接的社交帖子和联系人则不会被复制。完整字段列表请参阅人工智能智能体 API。
请注意,此端点采用 targetUserId 而非 sub_account_id — 它本身指定了两个账户。下方的两个调用使用常规的 sub_account_id 参数。
第 2 步 — 开启智能体
副本到达时始终处于暂停状态,因此在您确认之前它无法向任何人发送消息。这也是锁定您希望客户使用的 AI 层级的时刻;它会保持在该层级,因此无需按计划重新应用。
curl -X PATCH "https://api.dmchamp.com/v1/agents/NEW_AGENT_ID/active?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
-H "Content-Type: application/json" \
-d '{ "active": true }'
curl -X PUT "https://api.dmchamp.com/v1/agents/NEW_AGENT_ID?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
-H "Content-Type: application/json" \
-d '{ "anthropic_model": "max" }'
若要防止客户之后更改层级,请锁定允许的层级在子账户上,而不是重新发送该值。
第 3 步 — 将客户的渠道指向它
副本到达时也没有路由设置,因此在您将其设置为客户已连接渠道的应答者之前,没有任何消息会到达它。每个渠道调用一次:
curl -X PUT "https://api.dmchamp.com/v1/entry-points/channel-defaults?apiKey=YOUR_API_KEY&sub_account_id=abc123def456" \
-H "Content-Type: application/json" \
-d '{ "channel": "instagram", "agent_id": "NEW_AGENT_ID" }'
从这里开始,该渠道上来自未知联系人的首次消息将自动由复制的智能体接收。请参阅将渠道指向智能体以了解其他渠道和按号码路由的设置。
在创建子账户时设置客户的时区。 在
POST /v1/subaccounts上传递time_zone_id。智能体的活跃时间是在子账户自己的时区内评估的,因此如果创建客户时未设置时区,其日程安排将根据 UTC 时间读取——这会悄悄改变允许助手回复的时间。
为自行配置的客户跳过设置向导
POST /v1/subaccounts
默认情况下,新子账户所有者首次登录时,系统会引导他们完成“设置向导”。对于“代劳型”客户(即在客户登录之前,您就已经构建好 AI 智能体并连接了渠道),请在创建账户时传递 guided_onboarding: false。他们将直接进入正常的主屏幕——电脑上的仪表板或手机上的聊天界面——并且设置向导条目将从他们的侧边栏中隐藏。
curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"first_name": "Alex",
"last_name": "Client",
"business_name": "Client Co",
"guided_onboarding": false,
"usage_limits": { "monthly_credits": 500 }
}'
省略该字段(或发送 true),向导的行为将与以往完全一致,因此现有的集成无需更改。若要稍后将向导重新提供给客户,请使用 PUT /v1/subaccounts/{subAccountUid}/menu-visibility(见下文)重新显示 guided_onboarding 项目——菜单可见性控制向导是否可访问,guided_onboarding 仅控制首次登录时的重定向。
为客户关闭任务、每日摘要或媒体库
POST /v1/subaccounts
除非您另有说明,否则这三项功能对每个新客户都是开启的,它们的行为方式与本指南中的所有其他功能不同:它们是默认开启(opt-out),而非默认关闭(opt-in)。仅在 features 中省略它们是不够的,因为旧集成的 features 列表可能根本没有提及它们——我们无法区分“代理商关闭了此功能”和“此列表编写于该选项存在之前”。
因此,请使用 feature_settings 直接说明:
curl -X POST "https://api.dmchamp.com/v1/subaccounts" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"first_name": "Alex",
"last_name": "Client",
"business_name": "Client Co",
"feature_settings": {
"tasks": false,
"daily_summaries": false,
"ai_media_library": true
}
}'
每个键都是可选的;您省略的任何内容都将保持开启状态。使用 tasks: false,AI 将停止为该客户创建任务,也不会发送“已创建新任务”的电子邮件;使用 daily_summaries: false,将永远不会生成或发送每日摘要邮件。
feature_settings 是在创建时关闭这三项功能的唯一方法。无论您的列表其余部分看起来如何,仅在 features 中省略它们不会产生任何作用——这是刻意设计的,以防止旧集成在静默状态下丢失所有这三项功能。
若要在此后更改任何设置,请将完整的 features 列表发送至 PUT /v1/subaccounts/{subAccountUid}/features ——在那里,列表中存在即表示开启该功能,缺失则表示关闭。
让您的客户自动登录其子账户 (SSO)
POST /v1/subaccounts/{subAccountUid}/sso-link
使用您的代理 API 密钥进行一次调用,即可返回一个可直接打开的 URL,让客户直接登录其自己的子账户——无需登录屏幕,无需密码步骤,无需在之上进行任何构建。您可以在新标签页、重定向页面或您自己产品内的 iframe 中打开它。
| 字段 | 必填 | 说明 |
|---|---|---|
redirect |
否 | 客户端最终跳转的应用内页面,例如 "/chats" 或 "/agents"。在响应中作为 deep_link_url 返回。 |
app_base_url |
否 | 链接的仪表板主机。默认为您的白标应用域名(如果没有,则为平台域名)。必须是 https。 |
cURL
curl -X POST "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/sso-link" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "redirect": "/chats" }'
响应
{
"success": true,
"url": "https://app.yourdomain.com/auth?redirect=%2Fchats#token=eyJhbGciOi…",
"deep_link_url": "https://app.yourdomain.com/chats",
"expires_at": "2026-07-22T15:04:05.000Z",
"sub_account_uid": "SUB_ACCOUNT_UID"
}
如何有效使用:
- 一步到位。 打开
url可让客户登录并直接进入仪表板的redirect页面——没有登录屏幕,也没有中间页面。deep_link_url指定了相同的目标,适用于希望在登录后显式导航框架的集成商;一旦会话存在,任何仪表板路径在该浏览器上下文中均有效。 - 按需生成,立即打开。 该链接包含登录凭据,并在一小时左右后过期。请在客户点击时在服务器端请求它,切勿存储或通过电子邮件发送。
- 登录令牌在 URL 片段 (
#…) 中传输,浏览器从不将其发送到服务器,并且在被消耗的瞬间它会从地址栏中移除。 - 仅限您自己的子账户。 该端点拒绝任何非您代理机构拥有的账户。
- 过期的链接会显示清晰的错误提示及重试路径——请重新生成一个。
隐藏子账户上的导航项
PUT /v1/subaccounts/{subAccountUid}/menu-visibility
控制子账户可见的侧边栏和设置项——当您嵌入仪表板并只想显示您的产品尚未涵盖的功能时非常有用。未列出的任何内容都将保持可见;将 null 作为整个 menuVisibility 值发送以将所有内容重置为可见。隐藏某项会隐藏菜单条目——将其与您授予子账户的功能配对以进行严格限制。
cURL
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/menu-visibility" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"menuVisibility": {
"side_nav": { "Dashboard": false, "Deals": false, "Automations": false },
"settings_nav": { "team": false }
}
}'
响应
{
"success": true,
"data": {
"subAccountUid": "SUB_ACCOUNT_UID",
"menuVisibility": {
"side_nav": { "Dashboard": false, "Deals": false, "Automations": false },
"settings_nav": { "team": false }
}
}
}
side_nav 接受这 13 个键,它们与侧边栏项目名称相匹配:Dashboard、DailySummaries、Chats、Contacts、Deals、Tasks、Automations、Campaigns、Appointments、Settings、Help、CreditsCounter(侧边栏显示的额度余额)和 guided_onboarding(设置向导)。Campaigns 仅隐藏已停用的“营销活动”页面;“AI 智能体”和“广播”页面没有对应的键,无法通过这种方式隐藏。另外三个键——AiInsights、Sub Accounts 和 Agency Reselling——虽然被接受但不起作用:它们仅适用于已停用的经典仪表板,因此设置它们对您的子账户没有影响。缺失的键表示可见;当您亲自登录子账户时,隐藏的项目会暂时显示,以便您随时可以改回设置。
同一个 menuVisibility 对象还接受两个用于客户端主仪表板的可选字段。dashboard_widgets 将小部件 ID 映射到 true(显示)或 false(隐藏),而 dashboard_order 是一个小部件 ID 列表,按它们应出现的顺序排列。默认顺序下的 ID 为 kpis、performance、credits(额度使用情况)、funnel、inbox、outcomes、channel_health、ai_cost、ai_human、heatmap(最活跃时间)、top_campaigns(顶级坐席)、contacts_by_country、activity 和 tasks_deals。缺失的 ID 将保持可见,未包含在 dashboard_order 中的 ID 将按默认顺序排列。例如,"dashboard_widgets": { "credits": false } 会向客户端隐藏额度面板。
从菜单中隐藏页面并不会授予对其的访问权限。Automations 需要在子账户上授予 automations 功能——如果未授予该功能却将键设置为 true,页面仍然不会显示。Tasks 和 DailySummaries 的工作方式则相反:除非您将其关闭,否则它们对每个客户都是开启的(请参阅 为客户关闭任务、每日摘要或媒体库)。
选择客户可以连接的渠道类型
PUT /v1/subaccounts/{subAccountUid}/features
您在套餐层级中看到的渠道类型开关是普通的功能 ID,因此您可以直接通过 API 而非仪表板为每个客户进行设置。这是在 URL 中直接指定子账户名称的端点之一,因此不需要 sub_account_id。
| 功能 ID | 渠道 |
|---|---|
channel_chat_widget |
网站聊天小部件 |
channel_whatsapp_api |
WhatsApp Business API |
channel_whatsapp_web |
WhatsApp Web(二维码关联号码) |
channel_instagram |
|
channel_messenger |
Facebook Messenger |
channel_telegram |
Telegram |
channel_line |
LINE |
channel_viber |
Viber |
channel_email |
电子邮件邮箱 |
channel_sms |
短信 (SMS) |
channel_imessage |
iMessage |
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/features" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"features": [
"channels_3",
"channel_chat_widget",
"channel_whatsapp_web",
"channel_instagram",
"image_understanding",
"contact_tagging",
"incoming_campaigns",
"webhooks"
]
}'
需要注意的事项:
- 此调用将替换整个功能列表。 请发送客户应保留的所有功能,而不仅仅是你正在更改的功能。在创建账户时,相同的 ID 可作为
features在POST /v1/subaccounts上使用。 - 渠道类型和渠道数量是独立的限制条件,且两者均适用。
channels_1/channels_3/channels_unlimited控制连接的数量;channel_*ID 控制哪些类型。上面的示例意味着“最多 3 个连接,且仅限聊天小部件、WhatsApp Web 或 Instagram”。 automations_edit、broadcasts_send和smart_lists_create允许客户创建、编辑和删除他们自己的自动化、广播和智能列表。如果列表中未提及这三者中的任何一个,则保持其原样(在新的子账户上:三者均开启),因此旧的集成可以继续工作。如果至少命名其中一个,列表将设置所有三项:你遗漏的项将被关闭。无论哪种方式,客户仍然可以使用你为他们设置的功能,并且你的代理 API 密钥以及你在客户账户中的会话永远不会受到这三项的限制。- 其他所有功能在创建和更新时,均严格按照列表内容执行。 使用
features列表创建或更新的客户将仅获得这些功能。这包括crm_erp_integrations(CRM 和 ERP 集成部分,客户在此处连接 Odoo):它仅在你的列表中包含它时才会开启,因此如果客户需要连接 CRM 或 ERP,请务必添加它。在没有features列表的情况下创建的客户将获得默认设置,其中包括该功能。 - 不发送任何
channel_*ID 意味着没有渠道限制。 这是最初的行为,这就是为什么现有客户在功能发布时未受影响的原因。发送一个或多个 ID 后,其他所有内容在客户的“渠道”页面上都会显示为锁定状态,并带有升级提示,而不是“连接”按钮。客户已经连接的渠道将继续工作。
在套餐层级上设置渠道列表(以便购买该层级的每个客户端都能继承它)是在你的代理商套餐设置下的仪表板中完成的。此端点仅针对一个特定的子账户进行设置。
为客户设置精确的团队成员上限
PUT /v1/subaccounts/{subAccountUid}/limits
team_seats_* 功能仅提供预设的阶梯选项(3 / 5 / 10 / 不限)。若要为客户提供精确的团队席位数量(例如 2、7、15 或任何数字),请设置 usage_limits.team_seats_limit。该设置的优先级高于预设选项,平台会在每次邀请、直接添加和接受邀请时强制执行:一旦达到上限,服务器端将拒绝后续的邀请。
- 正整数即为精确上限。
0表示不包含团队成员——客户无法邀请任何人。-1表示不限。null将清除自定义上限,并回退到功能列表中所选的team_seats_*预设值。
降低上限不会移除现有的团队成员;它只会阻止添加新的成员。
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/limits" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"usageLimits": { "team_seats_limit": 7 }
}'
您也可以在创建时进行设置:POST /v1/subaccounts 接受具有相同语义的 usage_limits.team_seats_limit。要读取当前值,请使用 GET /v1/subaccounts?email=... 获取子账户并查看 usage_limits.team_seats_limit(不存在/null = 由预设决定)。同一端点也会更新 credits、monthly_credits、roll_over_to_next_month、rollover_cap_months、rollover_expiry_days 和 byok_monthly_limit_usd ——只需发送您想要更改的键即可。顶层的 creditManagementMode("manual" 或 "reselling")可切换客户端的信用额度模式;通过 API 创建的子账户默认处于手动模式,因此在客户端通过您的 SaaS 模式结账进行支付之前,请将其切换为 "reselling"(请参阅 子账户,运行免费试用)。
这如何与 SaaS 计划的席位限制交互。 您的 SaaS 计划可以携带其自身的席位配额(在计划编辑器中设置 — 请参阅 计划中的团队席位),当客户订阅时会自动应用该配额。您通过此端点设置的限制被视为手动授予:购买计划会将其替换为计划自身的席位配额(该购买是明确的计划选择),但无人值守的每月续订绝不会覆盖手动限制 — 因此,您授予客户的一次性例外情况会在其计费周期内持续有效。使用 null 清除手动限制后,该字段将在下一次续订时交还给计划管理。
限制客户在续订期间携带的额度。 另外两个 usage_limits 键位于 roll_over_to_next_month 旁边。两者在创建时也都被 POST /v1/subaccounts 接受,并且 null 可以清除其中任何一个。
| 键 | 作用 |
|---|---|
rollover_cap_months |
客户可以保留的额度月份数。0 到 120 之间的数字,允许小数(0.5 = 半个月)。在每次续订时,未使用的余额在添加新额度之前会被修剪为最多为该续订授予额度的倍数;0 不会结转任何内容。 |
rollover_expiry_days |
1 到 3650 之间的整数天数。在此期限内未使用的额度将在达到该期限后的第一次续订时被删除。消费总是优先扣除最旧的额度,因此每月用完额度的客户永远不会丢失任何额度。 |
如果未设置,两者都将回退到客户的套餐;此处发送的值将覆盖套餐的值。只有循环额度(每月津贴和套餐额度)受其限制:充值、自动充值和一次性添加的额度永远不会被限制或过期。每次修剪都会作为“结转上限额度调整”或“过期额度额度调整”写入客户的额度历史记录,并且永远不会计为使用量。套餐级别的等效项是定价层上的 rollover_cap_months 和 rollover_expiry_days —— 请参阅 定价层上的字段 和 限制结转内容。
设置每个客户的 AI 定价和策略
PUT /v1/subaccounts/{subAccountUid}/max-tier · /ai-tiers · /max-rate · /action-pricing · /insider-rate · /locked-bot-fields · /notifications · /zero-credit-reply
除了上述 /limits、/features 和 /menu-visibility 之外,还有八个针对每个客户的开关。每个开关都在 URL 中使用子账户的 uid(没有 sub_account_id 正文/查询参数 —— 目标已在路径中命名),并且作用域相同:您的代理密钥,且子账户必须属于您的代理。
客户可以使用哪些 AI 模型
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/max-tier" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "enabled": true }'
{ "enabled": boolean } 将客户选择加入(或退出)Max AI 层级,按平台标价计费。为自带密钥 (BYOK) 客户开启此功能会将他们的 AI 成本从“0 积分,使用我自己的密钥支付”更改为“从我的积分池中扣除”,因此这是一个针对每个客户的慎重决定,而不是整个代理机构的默认设置。
要限制客户的智能体可以选择哪些层级(而不仅仅是限制“最大值”),请使用 ai-tiers:
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/ai-tiers" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "allowed_ai_tiers": ["standard", "economy"] }'
allowed_ai_tiers 是一个从 standard、economy、max、mini 中提取的数组 —— 它会替换客户的允许列表。发送 null(或 [])以清除限制,允许他们选择任何层级。在此处设置的列表被视为手动锁定:计划自身的 allowed_ai_tiers(请参阅通过 API 管理您的定价层级)在续订时将不再影响此客户。这一点很重要,因为子账户选择自己的 AI 层级会消耗您的信用额度池,因此这是控制经销商客户可能产生的账单所使用的模型杠杆。
当客户额度用完时的保持回复
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/zero-credit-reply" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "enabled": true, "message": "Thanks for your message, we will get back to you shortly." }'
当客户的余额(或您的资源池)为空时,AI 无法回答,联系人也听不到任何回复。使用 enabled: true,每个在停机期间写入的联系人都会收到一次 message(最多 500 个字符,在每个频道上按原样发送),一旦额度恢复,AI 就会真正回答这些对话。enabled: false 会保留保存的文本以供稍后使用;enabled: false 且不带 message 会删除该设置。与子账户编辑模态中的“额度用完时的保持回复”开关相同 —— 请参阅 当客户额度用完时的保持回复。
客户每次 AI 操作的支付费用以及 WhatsApp 费用加价
设置面向客户费率的两种方法,从最简单到最精细:
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/max-rate" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "rate": 0.35 }'
rate 是子账户自身余额在每次 Max 模型 AI 操作时消耗的额度价格 — 这是您在平台实际支付成本之上的面向客户的加价。null 会清除覆盖设置,恢复为平台标价。费率必须至少等于 Max 操作对您自身额度池的成本(因此您永远不能将客户定价低于您的成本),且不超过 10 个额度;超出该范围的请求将被拒绝,并在错误消息中返回计算出的最低限额。
如果需要按操作类型定价而不是统一的 Max 费率,请使用 action-pricing:
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/action-pricing" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"actionPricing": {
"AI_MESSAGE": 0.6,
"CHAT_SUMMARY": 0.15,
"wa_carrier_multiplier": null
}
}'
actionPricing 是对客户现有映射的合并 — 您未提及的键将保持原样,而 null 会将该键重置回默认值。已识别的键:
| 键 | 价格 |
|---|---|
AI_MESSAGE |
AI 回复 |
AI_TOOL_USE |
AI 工具调用 |
EVALUATION_CALL |
聊天评估通过 |
INTERRUPTION_HANDLING |
处理回复中断 |
CONTACT_TAG |
AI 分配的联系人标签 |
CHAT_SUMMARY |
聊天摘要 |
wa_carrier_multiplier |
应用于客户支付的每笔非 AI WhatsApp 费用的加价乘数:月度号码租金、托管通道投递费以及 Meta/Twilio 模板转嫁成本。 |
每个操作的费率必须是大于 0 且不超过 10 的数字;wa_carrier_multiplier 必须至少为 1(低于成本价不打折)且不超过 10。发送无法识别的键或超出范围的值会导致整个请求被拒绝,并列出所有违规的键,因此拼写错误绝不会导致未实际应用的定价被静默保存。
如果您是 Champions Circle 会员,insider-rate 会将您的内部费率(Max 和 Mini 操作、Lead Finder 线索和自动化享 20% 折扣)下放给一位客户,而不是在整个代理机构范围内应用:
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/insider-rate" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "enabled": true }'
开启此功能需要您自己的代理机构账户实际拥有 Circle 会员资格;关闭此功能则无此限制,因此会员资格过期的用户随时可以将客户的费率调回。
锁定客户手册的部分内容
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/locked-bot-fields" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "locked_bot_fields": ["instructions", "rules"] }'
locked_bot_fields 是要冻结的剧本部分列表,它会替换客户的锁定列表。发送 null(或 [])以解锁所有内容。这对于由你代劳、你拥有剧本且以结果为考核标准的客户非常有用。
在当前编辑器中构建的智能体将其剧本保存在这些部分中,因此这些是需要锁定的部分:
| 智能体编辑器中的部分 | API 密钥 |
|---|---|
| 对话流程 | conversation_flow |
| 公司信息 | company_info |
| 报价 | offer |
| 线索来源 | lead_source |
| 独特卖点 | unique_selling_points |
| 市场定位 | market_positioning |
| 定价 | pricing_info |
| 异议处理 | objection_handling |
| 提问内容 | questions |
| 提醒团队成员的条件 | alert_human_when |
| 其他 | other |
| 资源 | resources |
| 邮件说明 | email_instructions |
| 个性 | personality |
| 目标 | goal |
| 规则 | rules |
| 结束条件 | conclude_unless |
| 说明(仅限旧版智能体) | instructions |
当前的智能体从不读取 instructions,因此仅锁定该部分无法保护任何内容:请锁定 conversation_flow、rules 以及客户不应触碰的其他部分。
任何以客户身份登录的人都无法更改已锁定的部分:包括客户自己的登录账号、其团队成员、他们自己的 API 密钥,以及当你从代理账户切换到客户仪表板时的你本人。无论是在实时智能体、未发布的草稿还是发布草稿时,更改都会被拒绝。若要自行编辑已锁定的部分,请使用带有你的代理密钥和 sub_account_id 的 API,或者先将其解锁,进行更改后再重新锁定。你未锁定的部分将保持完全可编辑状态。
代表客户设置其通知偏好
curl -X PUT "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/notifications" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"notifications": {
"settings": {
"credit_alerts": { "enabled": true, "channels": ["email", "in_app"] },
"new_contacts": { "enabled": false }
}
}
}'
仅更改您发送的类别:每个类别都会合并到客户端当前的设置中,而您省略的每个类别都将保留其原有值。settings 下的每个类别都接受 enabled(布尔值)以及最多三个来自 email、in_app、webhook 的 channels。发送 null 以重置为平台默认值。
所有七个端点都会响应 { "success": true, "data": { "subAccountUid": "...", ...the field(s) you set... } },并记录修改前后的审计日志。常见错误:如果您的账户不是代理机构/开发者账户,或者该子账户不归您管理,则返回 403;如果它不是代理机构子账户或值超出范围,则返回 400。
暂停已中止订阅的客户
POST /v1/subaccounts/{subAccountUid}/pause · POST /v1/subaccounts/{subAccountUid}/unpause
当客户暂停与您的订阅时,请暂停他们的账户而不是删除它:他们发送的所有内容都会立即停止——出站消息、广播、所有渠道上的 AI 回复——当他们登录时,他们会看到全屏的账户已暂停锁定界面(带有您的可选消息),而不是应用程序。没有任何内容会被删除或断开连接:智能体、广播、已连接的渠道、联系人和聊天记录都保持原样,因此取消暂停会将客户恢复到他们离开时的确切状态——无需重新设置。
| 字段 | 必填 | 描述 |
|---|---|---|
message |
否 | 在锁定屏幕上向客户显示。留空则使用默认措辞。 |
reason |
否 | 存储在暂停记录和审计日志中的代理内部备注——绝不会向客户显示。 |
cURL
curl -X POST "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/pause" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "message": "Your account is on hold — contact us to reactivate it.", "reason": "Subscription suspended per client email" }'
响应
{
"success": true,
"data": {
"subAccountUid": "SUB_ACCOUNT_UID",
"paused": true,
"level": "hard_blocked"
}
}
当客户回来时,POST /v1/subaccounts/SUB_ACCOUNT_UID/unpause(无正文)会解除锁定——发送功能和 AI 回复会立即恢复。
值得了解:
- 这与仪表板的“硬拦截”开关状态相同 (拦截/暂停子账户) —— 通过 API 暂停的客户在仪表板中显示为已拦截,反之亦然,取消暂停会清除从任一侧设置的拦截。当前状态可从
GET /v1/subaccounts上的agency_block字段读取("none"、"soft_blocked"或"hard_blocked"的level)。 - 两次调用都是幂等的。 暂停一个已暂停的客户只会刷新消息、原因和时间戳;取消暂停一个活跃的客户则不会有任何改变。
- 系统不会自动向客户发送电子邮件 —— 许多代理机构使用白标服务,因此通知客户的工作由您自行决定。
- 您自己的 DM Champ 账单不受影响。 暂停客户只会影响您与他们的关系。
- AI 助手也可以执行此操作:MCP 服务器 将这些端点作为标准 MCP 地址上的
pause_subaccount和unpause_subaccount工具公开(代理工具不包含在白标 MCP 地址中)。
直接授予或扣除额度
POST /v1/subaccounts/credits
从一个子账户的余额中添加或删除确切数量的额度 —— 这是仪表板手动额度调整的 API 等效项。这是一次性的余额更改,与 PUT /v1/subaccounts/{subAccountUid}/limits 上循环的 monthly_credits、roll_over_to_next_month、rollover_cap_months 和 rollover_expiry_days 设置不同。
这是本页面上唯一一个通过 电子邮件 而非 sub_account_id 来识别子账户的端点。
| 字段 | 必填 | 说明 |
|---|---|---|
email |
是 | 子账户的电子邮件地址(必须在您的代理机构下存在)。 |
amount |
是 | 非零整数额度,每次调用最多 100,000。正数表示增加,负数表示扣除。 |
description |
否 | 在客户的额度历史记录中显示的调整说明。默认为通用文本“Adjusted by agency via API”(由代理机构通过 API 调整)。 |
idempotency_key |
否 | 您为此调整选择的任何唯一字符串(最多 255 个字符,无空格)。您也可以将其作为 Idempotency-Key 标头发送。 |
安全重试。 在重试调用(例如在超时后)时发送相同的幂等键,这样额度只会增加或扣除一次。在 24 小时内,使用相同键和相同详细信息的重复请求将返回第一次调用的结果(带有 Idempotent-Replayed: true 标头),而不是再次更改余额。使用相同键但提供不同的电子邮件、金额或描述的请求将被拒绝 (422),而在第一次调用仍在运行时到达的重复请求将收到 409 错误:请稍候片刻再重试。不带键的调用将按原样工作。
cURL
curl -X POST "https://api.dmchamp.com/v1/subaccounts/credits" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: q3-bonus-client-example-com" \
-d '{ "email": "[email protected]", "amount": 500, "description": "Q3 bonus credits" }'
响应
{
"success": true,
"data": {
"email": "[email protected]",
"previous_balance": 1200,
"adjustment": 500,
"new_balance": 1700
}
}
如果负的 amount 会导致余额低于零,请求将被拒绝并返回 400,告知您当前可用余额以及您尝试扣除的金额。如果客户处于转售模式,增加的金额将被视为他们购买的额度:它会立即从您的代理机构额度池中扣除,就像通过结账流程购买一样,并且在下一次月度重置时,它会像真正的充值一样保留下来。当您的额度池不足以支付该金额时,调用将被拒绝并返回 402,且不会发生任何变动,因此请先为您的代理机构余额充值。对转售客户进行扣除只会从客户处移除额度;不会退还到您的额度池中。对于标准分配型客户,增加的额度被视为其周期性配额的一部分,在客户使用之前不会从您的额度池中扣除。无论哪种情况,它们都是一次性增加的额度,因此账户(或其套餐)设置的滚动上限或过期时间永远不会对其进行削减——只有周期性配额和套餐额度受这些限制。
读取子账户的对话
GET /v1/subaccounts/{subAccountUid}/chats · GET /v1/subaccounts/{subAccountUid}/chats/{contactId}/messages
无需登录客户账户,即可构建客户对话的监控或支持视图。首先列出他们的联系人以及最新消息的预览,然后读取某个联系人的完整消息历史记录。
列出联系人
curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats?apiKey=YOUR_AGENCY_API_KEY&pageSize=25"
| 查询参数 | 必需 | 描述 |
|---|---|---|
pageSize |
否 | 每页显示的联系人数量。默认 25,最大 50。 |
lastActivityAt |
否 | 分页游标 — 传入上一页的 lastActivityAt 以继续。 |
searchQuery |
否 | 按联系人姓名或电话号码进行筛选。 |
响应
{
"success": true,
"data": {
"contacts": [
{
"contactId": "contact456",
"firstName": "Jamie",
"lastName": "Lee",
"phoneNumber": "+14155551234",
"email": "[email protected]",
"channel": "whatsapp",
"lastActivityAt": "2026-08-30T14:22:00.000Z",
"lastMessage": { "body": "Thanks, that fixed it!", "direction": "inbound", "timestamp": "2026-08-30T14:22:00.000Z" },
"isBotActive": true,
"markChatClosed": false
}
],
"subAccountName": "Client Co",
"subAccountEmail": "[email protected]",
"hasMore": true,
"lastActivityAt": "2026-08-30T14:22:00.000Z"
}
}
联系人按最近活动时间排序。当 hasMore 为 true 时,请继续使用 lastActivityAt 进行分页。
读取单个联系人的消息
curl "https://api.dmchamp.com/v1/subaccounts/SUB_ACCOUNT_UID/chats/contact456/messages?apiKey=YOUR_AGENCY_API_KEY&pageSize=30"
| 查询参数 | 必需 | 描述 |
|---|---|---|
pageSize |
否 | 每页显示的消息数量。默认 30,最大 100。 |
beforeTimestamp |
否 | 分页游标 — 获取早于此 ISO 时间戳的消息。 |
响应
{
"success": true,
"data": {
"messages": [
{
"messageId": "msg789",
"body": "Thanks, that fixed it!",
"direction": "inbound",
"timestamp": "2026-08-30T14:22:00.000Z",
"status": "received",
"channel": "whatsapp",
"botReply": false,
"mediaUrl": null,
"mediaContentType": null,
"name": "Jamie Lee",
"role": null
}
],
"contactInfo": { "firstName": "Jamie", "lastName": "Lee", "phoneNumber": "+14155551234", "channel": "whatsapp" },
"hasMore": false,
"oldestTimestamp": "2026-08-30T14:22:00.000Z"
}
}
消息按最新时间优先返回;使用 beforeTimestamp 向后翻页查看历史记录。
读取您名下所有账户的额度使用情况和营销活动健康状况
GET /v1/subaccounts/credit-usage · GET /v1/subaccounts/campaign-status
针对您管理的所有子账户提供两种仪表板式的汇总,方便您构建自己的代理商报告,无需逐个点击进入每个客户的账户。
额度使用情况
curl "https://api.dmchamp.com/v1/subaccounts/credit-usage?apiKey=YOUR_AGENCY_API_KEY&from=2026-08-01&to=2026-08-31"
| 查询参数 | 必需 | 描述 |
|---|---|---|
from / to |
是 | ISO 日期范围。 |
subAccountId |
否 | 省略此项可获取代理商范围内的汇总,每个子账户一行。包含此项可切换至详细模式:显示该子账户的汇总及其原始的分页使用记录。 |
limitCount |
否 | 仅限详细模式。默认 500,最大 2000。 |
startAfterTimestamp |
否 | 仅限详细模式 — 分页游标。 |
{
"success": true,
"data": {
"subAccounts": [
{
"subAccountId": "abc123def456",
"subAccountName": "Client Co",
"subAccountEmail": "[email protected]",
"totalCreditsUsed": 842,
"totalCostUsd": 3.15,
"byReason": { "AI reply": 620, "Chat summary": 80 },
"topCampaigns": [{ "campaignName": "Inbound Leads", "creditsUsed": 500 }]
}
],
"totals": { "totalCreditsUsed": 842, "totalCostUsd": 3.15, "totalRecords": 214 },
"dateRange": { "from": "2026-08-01", "to": "2026-08-31" },
"hasMore": false,
"lastTimestamp": null
}
}
传入 subAccountId,相同的响应中还会包含 records:包含 amount、reason、campaignName、contactName 和 timestamp 的单笔费用。如果客户使用自己的 BYOK 密钥而非您的额度进行消费,则不会显示成本/代币数据(costsRedacted: true)——这是平台成本遥测数据,不应向经销商查看者展示。
营销活动状态
curl "https://api.dmchamp.com/v1/subaccounts/campaign-status?apiKey=YOUR_AGENCY_API_KEY&pageSize=20"
| 查询参数 | 必需 | 描述 |
|---|---|---|
pageSize |
否 | 每页显示的子账户数量。默认 10,最大 50。 |
lastDocumentId |
否 | 分页游标。 |
searchQuery |
否 | 按子账户名称或电子邮件进行筛选。 |
{
"success": true,
"data": {
"totalSubAccounts": 34,
"subAccountsWithIssues": 3,
"totalLiveCampaigns": 51,
"totalPausedCampaigns": 6,
"subAccounts": [
{
"userId": "abc123def456",
"email": "[email protected]",
"displayName": "Jamie Lee",
"businessName": "Client Co",
"totalCampaigns": 2,
"liveCampaigns": 1,
"pausedCampaigns": 1,
"hasIssues": true,
"issueDetails": ["1 campaign paused"],
"lastCampaignActivity": "2026-08-29T09:00:00.000Z"
}
],
"hasMore": true,
"lastDocumentId": "abc123def456",
"pageSize": 20
}
}
每一行还包含客户的 AI Agent 计数(totalAgents、activeAgents、pausedAgents、draftAgents),顶层则为页面添加了 totalActiveAgents 和 totalPausedAgents。营销活动字段仅涵盖经典营销活动。hasIssues / issueDetails 标记了值得关注的子账户。对于拥有 Agent 的账户,它们来自已开启 Agent 的就绪度评分(例如 "WhatsApp Web is disconnected" 或 "Agent \"Front desk\": Routed on a channel that is not connected");已关闭的 Agent 永远不会被标记。对于没有 Agent 的账户,它们会标记经典营销活动,例如已暂停的活动。利用此功能可以构建整个账簿的健康检查仪表板,而无需逐个打开客户查看哪些 Agent 已关闭。
若要获取所有客户的时间序列消息和信用活动(即适合图表展示的序列,而非特定时间点的快照),请参阅 Analytics API 指南中的
GET /analytics/agency-rollup。
交付一个已设置好的客户端账户
PUT /v1/snapshots/default · POST /v1/snapshots/{snapshotId}/apply
快照 是一个可重用的模板:一个或多个 AI 智能体及其知识库、工具和媒体,均从你自己的账户中捕获。有两个端点可将其放入你的配置流程中。
自动 —— 每个新客户端天生就拥有它。 将某个快照标记为默认值一次,此后你创建的每个账户都会在创建时自动安装它。这涵盖了通过 POST /v1/subaccounts 创建的账户、你在仪表板中创建的账户,以及当客户端通过你的结账链接付款时自动创建的账户。
首先,找到快照的 id:
curl "https://api.dmchamp.com/v1/snapshots" \
-H "X-API-Key: YOUR_AGENCY_API_KEY"
然后将其设置为默认值:
curl -X PUT "https://api.dmchamp.com/v1/snapshots/default" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "snapshot_id": "SNAPSHOT_ID" }'
这就是整个集成过程。发送 {"snapshot_id": null} 即可再次将其关闭。你也可以通过点击“快照”页面上的星号,在仪表板中执行相同的操作。
要读取当前已加星标的内容(例如,在配置脚本决定是否设置一个之前),GET /v1/snapshots/default 会返回 { "success": true, "data": { "default_snapshot_id": "SNAPSHOT_ID" } } ——当没有加星标的内容时返回 null。GET /v1/snapshots(用于查找上述 id)会返回相同的 default_snapshot_id 以及完整的 snapshots 数组,因此大多数集成只需要调用一次即可。完整快照对象的字段请参阅 快照 指南。
按需 —— 安装到单个账户中。 这对于引导现有客户端,或稍后为客户端提供第二个模板非常有用。
curl -X POST "https://api.dmchamp.com/v1/snapshots/SNAPSHOT_ID/apply" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "sub_account_id": "SUB_ACCOUNT_UID" }'
省略 sub_account_id,它将改为安装到你自己的代理商账户中。与 /subaccounts 端点一样,这些端点在路径或正文中指定目标账户,而不是通过环境 sub_account_id 参数指定。
在构建之前值得了解的内容:
- 安装的智能体默认处于暂停状态。 请先连接客户端的渠道,然后再激活智能体。这对于自动路径和按需路径都适用。
- 配置绝不会因为快照而失败。 如果安装无法完成,客户端账户仍然会被创建并可以使用 —— 它只是会以空状态到达,你可以稍后再应用快照。
- 渠道、日历和 OAuth 连接永远不会被复制。 每个账户都连接其自己的渠道。使用普通 API 密钥的工具会立即继续工作。
- 应用两次会创建第二个副本。 不会覆盖任何内容。
通过 API 构建模板本身
POST /v1/snapshots · 通过 API 管理智能体、自定义函数和媒体
上一节介绍了如何分发在仪表板中构建的快照。创作部分也同样开放,因此整个闭环——即一次性组装好主设置、捕获它,然后将其分发给每个客户端——都可以通过代码运行。
以下是配置脚本所使用的组件,按使用顺序排列:
- 创建自定义函数。
POST /v1/custom-functions用于创建一个函数;GET /v1/custom-functions列出您拥有的函数,而GET、PUT和DELETE在/v1/custom-functions/{customFunctionId}上用于读取、更新和删除函数。POST /v1/custom-functions/test在保存定义之前对其进行试运行。 - 创建并配置智能体。
POST /v1/agents用于创建智能体,PUT /v1/agents/{agentId}用于更新它,PATCH /v1/agents/{agentId}/active配合{ "active": false }可在您工作时将其保持在暂停状态(使用true进行相同的调用即可使其上线)。GET /v1/agents用于列出所有智能体。 - 赋予智能体能力。
POST /v1/agents/{agentId}/custom-functions配合{ "custom_function_id": "..." }将函数附加到智能体;对应的DELETE /v1/agents/{agentId}/custom-functions/{customFunctionId}则将其分离。 - 填充媒体库。
POST /v1/agents/{agentId}/media-library用于上传项目(JSON 包含base64Data、mimeType、title、description);GET列出智能体的项目,PATCH/DELETE在/{itemId}上用于更新或删除项目。 - 将其捕获为快照。
curl -X POST "https://api.dmchamp.com/v1/snapshots" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Master setup v1",
"agent_ids": ["AGENT_ID"],
"include_knowledge": true,
"include_tools": true,
"include_media": true
}'
此后便回到了上一节的内容:将其设为默认值,以便每个新客户端在创建时都具备该配置,或者按需应用它。管理工作也同步进行:PATCH /v1/snapshots/{snapshotId} 配合 { "name": "..." } 用于重命名快照,DELETE /v1/snapshots/{snapshotId} 用于删除快照(如果它是默认值,则会取消其默认状态),GET /v1/snapshots/apply-targets 列出您可以安装到的所有账户。
智能体、自定义函数和媒体端点都接受 sub_account_id,因此相同的调用也可以直接维护某个客户端账户内的智能体。快照调用始终作用于您的代理账户——模板存储在您这里。所有这些接口的完整请求和响应模式均可在 API 参考 中找到。
通过 API 管理您的定价层级
GET /v1/agency/pricing-tiers · POST /v1/agency/pricing-tiers · PATCH /v1/agency/pricing-tiers/{tierIndex} · DELETE /v1/agency/pricing-tiers/{tierIndex}
您在 SaaS 模式 → 定价层级 中销售的套餐可以通过代码进行读取和更改,因此您自己的管理面板或配置脚本可以在无需任何人打开仪表板的情况下添加套餐、调整价格或分发结账链接。像本页面上的其他所有调用一样,使用您的代理商 API 密钥进行身份验证;这些端点属于代理商级别,因此不需要 sub_account_id。每次写入操作都会运行与仪表板保存相同的验证和 Stripe 产品与价格同步,因此在此处创建的套餐与您手动设置的套餐没有区别。
列出您的层级
curl "https://api.dmchamp.com/v1/agency/pricing-tiers" \
-H "X-API-Key: YOUR_AGENCY_API_KEY"
响应
{
"success": true,
"data": {
"tiers": [
{
"tierIndex": 0,
"credits": 1000,
"price_cents": 2900,
"currency": "usd",
"label": "Starter",
"billing_interval": "month",
"trial_days": 14,
"trial_credits": 250,
"trial_card_required": false,
"trial_hard_expiry": true,
"stripe_price_id": "price_1PxAbC…",
"stripe_product_id": "prod_QxAbC…",
"checkout_url": "https://app.yourdomain.com/v1/checkout?id=YOUR_AGENCY_UID&tierIndex=0"
}
],
"count": 1,
"max_tiers": 20
}
}
每个层级返回时都会包含其 tierIndex(即它在您的套餐列表中的位置,这也是其他三个调用引用它的方式)以及一个可直接分享的 checkout_url,这与 付款 选项卡中提供的链接相同,且已指向销售该套餐的白标域名。
添加层级
请求主体是一个层级对象;它会被追加到您的列表末尾。
curl -X POST "https://api.dmchamp.com/v1/agency/pricing-tiers" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Starter",
"credits": 1000,
"price_cents": 2900,
"currency": "usd",
"billing_interval": "month",
"trial_days": 14,
"trial_credits": 250,
"trial_card_required": false,
"trial_hard_expiry": true,
"features": ["channels_3", "channel_whatsapp_web", "webhooks"]
}'
响应包含已创建的层级,包括它所处的 tierIndex 及其 checkout_url。
编辑层级
仅发送您想要更改的字段;套餐上的其他所有内容将保持不变。
curl -X PATCH "https://api.dmchamp.com/v1/agency/pricing-tiers/0" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "price_cents": 3900, "trial_hard_expiry": true }'
API 无法识别的字段会被拒绝而不是被忽略,并且错误信息会指出该字段名称——因此拼写错误永远不会悄悄写入一个看起来生效但实际上无效的设置。更改价格、额度、货币或计费周期会在您的 Stripe 中创建一个新价格;已经订阅的客户将保留在他们注册时的套餐中。
删除层级
curl -X DELETE "https://api.dmchamp.com/v1/agency/pricing-tiers/2" \
-H "X-API-Key: YOUR_AGENCY_API_KEY"
与仪表板规则相同:仍有活跃订阅者的套餐无法删除。请求会被拒绝,并告知您该套餐上有多少订阅者——请先取消或迁移他们。删除成功后,响应将返回您剩余的层级,并已重新编号。
层级上的字段
| 字段 | 说明 |
|---|---|
label / description |
套餐名称,以及结账页面上显示的选填行。 |
credits |
客户在月付或年付套餐中每月获得的额度,或在周付套餐中每个计费周期获得的额度。必须为至少 1 的整数,若套餐的 features 包含 byok,则可设为 0(客户使用自己的 API Key 运行 AI,因此套餐不授予额度,也不会从您的资源池中扣除)。 |
price_cents |
每个计费周期的价格,以最小货币单位计算(2900 = $29.00)。对于年付套餐,这是全年的价格。 |
currency |
小写 ISO 代码 — usd、eur、gbp 等。 |
billing_interval / billing_interval_count |
month(默认值)、year,或 week(需指定 1–52 的计数值,表示“每 N 周”)。 |
trial_days |
免费试用时长,0 到 90 天。0(或留空)表示无试用。 |
trial_credits |
客户开始试用时获得的初始额度。默认为套餐的 credits。 |
trial_card_required |
false 允许客户在不输入银行卡的情况下开始试用。默认为 true。 |
trial_hard_expiry |
true 会在试用结束且未升级时,将未使用的试用额度退回您的资源池并锁定客户账户。默认为 false — 详见 试用后的强制过期。 |
rollover_cap_months |
此套餐客户在续费时可结转的额度月份数 — 0 到 120 之间的数字,允许小数。0 表示不结转;null(默认值)表示无上限。详见 设置结转上限。 |
rollover_expiry_days |
未使用的额度在下次续费时失效的天数 — 1 到 3650 之间的整数。null(默认值)表示永不过期。 |
features / feature_settings |
此套餐客户可获得的功能 — 与 选择客户可连接的渠道类型 中的功能 ID 相同。 |
team_seats_limit |
套餐授予的团队席位:具体数字,0 表示无席位,-1 表示无限制。 |
allowed_ai_tiers |
此套餐客户可使用的 AI 模型,取自 standard (Pro)、economy、max、mini。在客户订阅时及每次续费时应用。null 或 [](默认值)表示套餐不管理模型。通过 PUT /v1/subaccounts/:uid/ai-tiers 手动设置的子账户锁定状态不会被套餐覆盖。 |
white_label_config |
此套餐销售时所使用的 白标域名。 |
试用相关字段仅在包含试用的方案中有效:如果保存方案时 trial_days: 0 为空,这些字段将被丢弃。方案的 Stripe 产品 ID 和价格 ID 由系统为您管理,无法手动设置。
需要注意的三点:
- 层级索引是位置,而非永久 ID。 删除一个计划会将该计划之后的所有计划向前移动一位,因此在进行任何更改后请重新获取列表——并重新复制您已发布的结账链接,这与您在仪表板中删除计划后的操作完全相同。
- 必须先设置 SaaS 模式。 这些端点需要一个已保存白标设置和 Stripe 密钥的代理账户;如果没有这些,计划的产品和价格将无法关联到任何 Stripe 账户。
- 上限为二十个计划,与仪表板中的限制相同。列表响应中的
max_tiers字段会告知您当前的限制。
完整的请求和响应模式位于 API 参考 的 Agency 部分下。
通过 API 设置您的每积分价格
GET /v1/agency/credit-price · PATCH /v1/agency/credit-price
客户为即时充值支付的价格(SaaS 模式 → 每积分定价)也可以通过代码进行读取和更改。此功能专为价格需要自动变动的情况而设计:例如,一家以一种货币销售积分但以另一种货币收费的代理机构,可以让定时任务根据汇率变化来调整价格,而不是每周由人工手动编辑。
读取当前价格
curl "https://api.dmchamp.com/v1/agency/credit-price" \
-H "X-API-Key: YOUR_AGENCY_API_KEY"
响应
{
"success": true,
"data": {
"price_per_credit_cents": 125,
"price_per_credit_currency": "brl",
"note": "USD 0.25 per credit at our reference rate",
"minimum_cents": 60
}
}
minimum_cents 是平台在该货币下允许的最低价格,因此任务可以在发送新价格之前对其进行检查。在设置价格之前,所有三个值均为 null。
更改价格
curl -X PATCH "https://api.dmchamp.com/v1/agency/credit-price" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "price_per_credit_cents": 130, "currency": "brl" }'
仅发送您想要更改的内容。price_per_credit_cents 是以最小货币单位表示的价格(130 = 1.30 雷亚尔);currency 是小写的 ISO 代码;note 是一个可选的文本行,最多 200 个字符,会直接显示在客户“账单”页面上每积分价格的下方——这对于显示另一种货币的参考价格非常方便,例如 “按我们的参考汇率,每积分 0.25 美元”。发送 "note": "" 即可将其移除。响应格式与上述读取操作相同,因此任务可以进行比较,并在没有变化时跳过写入操作。
适用规则与仪表板中的相同:价格不得低于该货币的平台最低限额,且账户需要启用白标功能。与定价层级端点不同,读取或更改此值不需要 Stripe 密钥。
为任务分配一个仅具备特定权限的密钥
将您的完整代理密钥放入调度程序中,其权限超出了价格更新所需的范围。相反,请创建一个仅限于 Agency Credit Price(代理额度价格)区域的作用域密钥:该密钥只能读取和更改每额度价格,不能执行其他任何操作——它无法访问子账户、计划、额度或您的 Stripe 连接。
curl -X POST "https://api.dmchamp.com/v1/api-keys" \
-H "X-API-Key: YOUR_AGENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "label": "FX price updater", "scopes": { "read_only": false, "tags": ["Agency Credit Price"] } }'
响应会在 api_key 中仅一次性携带新密钥——它之后不会再显示,因此请立即保存。如果密钥仅需读取价格,请设置 "read_only": true;如果您希望它在特定日期自动失效,请添加 "expires_at"(一个 ISO 日期)。只有账户所有者的密钥才能创建作用域密钥;请使用 GET /v1/api-keys 和 DELETE /v1/api-keys/{id} 来列出或撤销它们。
让子账户读取您的定价
GET /v1/subaccounts/agency-pricing
本页上的其他所有端点均使用您的代理密钥进行调用,并可通过 sub_account_id 选择性地指定目标客户。此端点则相反:它使用子账户自己的 API 密钥进行调用,且无需 sub_account_id,因此客户自己的充值页面(或您为他们构建的集成)可以显示您向他们收取的费用,而无需查看您的代理账户。
curl "https://api.dmchamp.com/v1/subaccounts/agency-pricing" \
-H "X-API-Key: THE_SUB_ACCOUNTS_OWN_API_KEY"
响应
{
"success": true,
"data": {
"tiers": [{ "credits": 1000, "price_cents": 2900, "currency": "usd" }],
"price_per_credit_cents": 125,
"price_per_credit_currency": "brl",
"price_per_credit_note": "USD 0.25 per credit at our reference rate",
"agency_display_name": "Client Co's Growth Partner"
}
}
这完全镜像了 GET /v1/agency/pricing-tiers 和 GET /v1/agency/credit-price 作为代理为您返回的内容,去除了客户无需查看的信息(Stripe ID、max_tiers 等)。它仅适用于实际上是带有关联代理的子账户的账户——从您自己的代理账户调用此接口会返回权限错误。
需要注意的事项
- 使用你的代理商密钥。 使用你代理商账户的 API 密钥对每个调用进行身份验证,而不是使用子账户的密钥。
sub_account_id参数用于重定向操作。 - 积分来自子账户。 购买和循环扣费会扣除目标子账户的积分余额,而不是你的余额。
404意味着“不是你的子账户”。 请仔细检查 id,并确认该账户是你管理的账户。- 该参数在所有接受它的地方都是可选的。 省略它,同一个端点就会作用于你的代理商账户,因此你可以将一个集成用于两者。