Your AI Connector Docs

联系人 API

联系人是指您发送消息的个人——包括他们的姓名、电话号码、电子邮件、渠道、标签、自定义字段,以及他们所属的列表和营销活动。联系人 API 允许您创建、查找、更新、标记、批量导入和删除联系人,所有这些操作都无需使用仪表板。

此页面上的所有路径均相对于基础 URL:

https://api.youraiconnector.com/v1

因此 /contacts 意味着 https://api.youraiconnector.com/v1/contacts

API 新手? 请先阅读 API 访问 —— 它涵盖了如何生成 API 密钥、三种身份验证方式、速率限制以及错误格式。本页面上的所有内容都假设您已经拥有一个可用的 API 密钥。


关于联系人 ID

每个联系人都有一个唯一的 ID。您在创建联系人时(在 data.contactId 中)获得的 ID 与您在其他任何地方使用的 ID 相同——用于获取、更新、标记、发送消息或删除该联系人。保存一次即可重复使用。

您不必为了获取 ID 而创建联系人。您也可以通过电话号码或电子邮件查找 ID(请参阅 获取联系人),或者翻页查看所有联系人(请参阅 列出联系人)。这些操作返回的 ID 都是相同的。


创建联系人

POST /contacts

向您的账户添加一个新联系人。必须提供带有国家代码的电话号码——仅有电子邮件是不够的。其他所有字段均为可选。

您可以选择通过 listId(单个列表)或 listIds(数组)将新联系人直接放入一个或多个列表中。如果两者同时发送,则 listIds 优先。

您发送的任何字段,只要不是下表 创建联系人 字段(phoneNumberfirstNamelastNameemailchannelis_bot_activeis_privatelead_profilelistIdlistIdscustom_fields)中的标准字段,都会自动存储为 自定义字段 —— 因此,来自 Make 或 Zapier 等工具的扁平化有效载荷无需嵌套即可正常工作。您也可以显式传递一个 custom_fields 对象。

字段 必填 描述
phoneNumber 联系人的电话号码,包含国家代码(例如 +15551234567)。
firstName 名字。
lastName 姓氏。
email 电子邮件地址。
channel 消息渠道。可选 whatsappsmswhatsapp_web 之一。默认为 whatsapp
is_bot_active AI 助手是否回复此联系人。默认为 true
is_private 将联系人标记为私有。当为 true 时,AI 助手将为他们关闭。默认为 false
lead_profile 关于潜在客户的自由文本备注。
listId 要将联系人添加到的单个列表 ID。
listIds 要将联系人添加到的列表 ID 数组(优先级高于 listId)。
custom_fields 您自己的键/值字段对象。您也可以将这些作为顶级键传递。

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+15551234567",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane@example.com",
    "is_bot_active": true,
    "listIds": ["list123", "list456"]
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/contacts", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phoneNumber: "+15551234567",
    firstName: "Jane",
    lastName: "Smith",
    email: "jane@example.com",
    is_bot_active: true,
    listIds: ["list123", "list456"],
  }),
});
const data = await res.json();
console.log(data.data.contactId);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phoneNumber": "+15551234567",
        "firstName": "Jane",
        "lastName": "Smith",
        "email": "jane@example.com",
        "is_bot_active": True,
        "listIds": ["list123", "list456"],
    },
)
print(res.json()["data"]["contactId"])

响应

{
  "success": true,
  "data": {
    "message": "Successfully created new contact",
    "contactId": "contact_abc123",
    "listsAdded": ["list123", "list456"]
  }
}

新联系人的 ID 位于 data.contactId。它被添加到的列表会在 data.listsAdded 中返回。

不会创建重复项。 如果具有相同电话号码的联系人已存在,创建调用将不会创建或返回该联系人。响应将返回 HTTP 状态 200,并在正文中包含 error_code409 的内容,因此请根据 error_code 进行分支判断,而不是根据 HTTP 状态:

{ "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user." }

若要在 error_code409 后处理现有联系人,请使用 通过电话或电子邮件获取联系人 进行查找 —— GET /contacts?phoneNumber=... —— 并复用其返回的 ID。

等效的 WhatsApp 拼写方式被视为同一个号码。 某些国家/地区对于同一个移动线路有两种有效的拼写方式,而 WhatsApp 可能会报告其中任何一种:墨西哥(+52… 和旧版 +521…)、巴西(带或不带第九位数字)以及阿根廷(在 +54 之后带或不带 9)。创建时的重复检查和 GET /contacts?phoneNumber= 会在两种拼写方式之间进行匹配,因此无论您发送哪种格式,都会返回现有的联系人。存储在联系人上的 phone_number 永远不会被重写。


通过电话或电子邮件获取联系人

GET /contacts?phoneNumber=...GET /contacts?email=...

查找单个联系人并返回完整的、富化的联系人对象——包括解析为 { id, name } 对的列表、标签和营销活动,以及最后交换的消息。

传入 phoneNumber(国际格式) email。如果您两者都不传,此端点将切换为列出联系人模式。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?phoneNumber=%2B15551234567&apiKey=YOUR_API_KEY"

JavaScript

const phone = encodeURIComponent("+15551234567");
const res = await fetch(`https://api.youraiconnector.com/v1/contacts?phoneNumber=${phone}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"phoneNumber": "+15551234567"},
)
print(res.json()["contact"])

响应

{
  "success": true,
  "contactId": "contact_abc123",
  "contact": {
    "id": "contact_abc123",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane@example.com",
    "phoneNumber": "+15551234567",
    "channel": "whatsapp",
    "isBotActive": true,
    "isPrivate": false,
    "doNotDisturb": false,
    "lead_profile": null,
    "avatarUrl": "https://example.com/photo.jpg",
    "customFields": {},
    "lists": [{ "id": "list123", "name": "VIP customers" }],
    "tags": [{ "id": "tagHotLead", "name": "Hot lead" }],
    "campaigns": [{ "id": "campaign789", "name": "Spring promo" }],
    "currentCampaign": { "id": "campaign789", "name": "Spring promo" },
    "lastMessage": {
      "direction": "inbound",
      "body": "Sounds good, thanks!",
      "status": "received",
      "timestamp": "2026-06-09T10:21:00.000Z"
    }
  }
}

联系人 ID 会在顶层 (contactId) 和对象内部 (contact.id) 同时返回。如果没有匹配项,您将收到一个带有 { "success": false, "message": "Contact not found" }404

avatarUrl 是联系人的个人资料照片,取自 WhatsApp 或 Meta(当他们给您发消息时)。它是只读的:您无法设置它,并且对于没有照片或通过不共享照片的渠道联系您的联系人,该字段为 null。请将此链接视为临时的,不要存储它,因为其中一些照片链接会自动过期并刷新。(在下方的列表端点中,相同的值被称为 avatar_url。)

URL 中的电话号码。 查询字符串中的 + 符号必须进行 URL 编码为 %2B,否则它会被读取为空格。上面的示例已为您处理了这一点。


通过 ID 获取联系人

GET /contacts/{contactId}

当您已经拥有联系人的 ID 时,可以直接获取它。响应格式与上面的查找相同。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["contact"])

如果联系人 ID 在您的账户中不存在,则会返回 404


获取联系人统计信息

GET /contacts/{contactId}/stats

返回单个联系人的汇总消息统计信息:总数、AI 与人工回复对比、已消耗额度以及首次/最后一次消息的时间戳。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.totalMessages, data.creditsUsed);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["totalMessages"], data["creditsUsed"])

响应

{
  "success": true,
  "totalMessages": 48,
  "sent": 21,
  "received": 27,
  "aiReplies": 18,
  "humanReplies": 3,
  "creditsUsed": 34,
  "botMessageCount": 18,
  "firstMessageAt": "2026-05-01T09:00:00.000Z",
  "lastMessageAt": "2026-06-09T10:21:00.000Z"
}

botMessageCount 是应用内联系人“重置”按钮所清零的同一个 AI 消息计数器。creditsUsed 是该联系人的累计额度总数,而非仅本次响应的数值。如果您的账户中不存在该联系人 ID,则会返回 404


列出联系人

GET /contacts

调用 GET /contacts不带 phoneNumberemail,即可翻阅您的所有联系人,按最新顺序排列。每一页都会返回精简的联系人摘要(列表、标签和营销活动将以 ID 数组而非完整对象的形式返回)以及一个 next_cursor

查询参数 描述
limit 每页条数。默认为 50,最大为 100。
cursor 上一页的 next_cursor 值。第一页请省略此项。
listId 可选。仅返回属于此列表的联系人。

要遍历每一页:首先在不带游标的情况下进行第一次调用,然后持续将返回的 next_cursor 作为 cursor 传回。next_cursornull 时停止——这意味着没有更多结果了。

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&apiKey=YOUR_API_KEY"

# next page:
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&cursor=contact_abc123&apiKey=YOUR_API_KEY"

JavaScript

async function listAllContacts() {
  const all = [];
  let cursor = null;
  do {
    const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts");
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);
    const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
    const data = await res.json();
    all.push(...data.contacts);
    cursor = data.next_cursor;
  } while (cursor);
  return all;
}

Python

import requests

def list_all_contacts():
    all_contacts = []
    cursor = None
    while True:
        params = {"limit": 100}
        if cursor:
            params["cursor"] = cursor
        res = requests.get(
            "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
            headers={"X-API-Key": "YOUR_API_KEY"},
            params=params,
        )
        data = res.json()
        all_contacts.extend(data["contacts"])
        cursor = data["next_cursor"]
        if not cursor:
            break
    return all_contacts

响应

{
  "success": true,
  "contacts": [
    {
      "id": "contact_abc123",
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane@example.com",
      "phone_number": "+15551234567",
      "channel": "whatsapp",
      "is_bot_active": true,
      "is_private": false,
      "do_not_disturb": false,
      "avatar_url": "https://example.com/photo.jpg",
      "custom_fields": {},
      "created_at": "2026-06-01T09:00:00.000Z",
      "list_ids": ["list123"],
      "tag_ids": ["tagHotLead"],
      "campaign_ids": ["campaign789"],
      "current_campaign_id": "campaign789"
    }
  ],
  "next_cursor": "contact_abc123"
}

注意: 按账户中不存在的 listId 进行筛选会返回 404。无效的 cursor 会返回 400


统计联系人

GET /contacts/count

返回符合过滤条件的联系人数量,以及按渠道划分的统计结果,无需进行分页。这是处理任何“有多少”问题的正确调用方式——无论是仪表板磁贴、自动化流程,还是向 Champ 提问。所有过滤器均为可选,组合使用多个过滤器会缩小统计范围(联系人必须匹配您发送的每一个条件)。

查询参数 描述
agentId 仅限分配给此 AI 代理的联系人。传入 none 可获取未分配代理的联系人(这些联系人由渠道的默认代理回复)。
channel 仅限此渠道上的联系人,例如 whatsappmessengerinstagramsmsemailchat_widget
tag 仅限带有此标签的联系人,按标签名称匹配(不区分大小写)。如果标签名称不存在,则返回 404
listId 仅限此列表中的联系人。
botActive truefalse —— 仅限 AI 助手处于开启或关闭状态的联系人。
status 仅限具有此状态的联系人,例如 Lead
rules 一个 URL 编码的 JSON 规则对象,使用与智能列表相同的格式(请参阅下文的 The smart_rules shape)。不能与其他过滤器组合使用。

如果不发送任何过滤器,您将获得账户中联系人的总数。

cURL

# everything
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?apiKey=YOUR_API_KEY"

# only the contacts one agent handles on Messenger
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?agentId=agent_xyz789&channel=messenger&apiKey=YOUR_API_KEY"

JavaScript

const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count");
url.searchParams.set("agentId", "agent_xyz789");
url.searchParams.set("channel", "messenger");

const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
const data = await res.json();
console.log(data.total);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"agentId": "agent_xyz789", "channel": "messenger"},
)
data = res.json()
print(data["total"])

响应

{
  "success": true,
  "total": 3423,
  "by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
  "filters": { "agentId": "agent_xyz789" }
}

by_channel 会按渠道拆分相同的总数;未在任何渠道上的联系人将计入 nonefilters 会回显所应用的过滤器,以便您检查调用是否达到了预期效果。

注意:rules 与任何其他过滤器一起发送,或发送非有效 JSON 的 rules 值,将返回 400。如果账户中不存在某个标签名称或列表 ID,则返回 404


更新联系人

PUT /contacts/{contactId}

更新现有联系人。仅更改您包含的字段——不想改动的字段请留空。您必须至少发送一个字段,否则会收到 400(“没有要更新的字段”)。

字段 描述
firstName 名字。
lastName 姓氏。
email 电子邮件地址。
is_bot_active AI 助手是否回复此联系人。
is_private 标记为私有。将其设置为 true 也会关闭 AI 助手。
do_not_disturb 暂停对此联系人的自动外联。同时也会停止 AI 回复。
follow_ups_disabled 停止此联系人的所有自动跟进(快速、周期和冷线索),同时 AI 继续回复他们发送的消息。在某人购买后非常有用。保持关闭状态,直到您将其改回 false
lead_profile 自由文本线索备注。
custom_fields 自定义字段对象。按键合并 — 仅写入您发送的键,其余现有自定义字段将保留。您也可以在顶层传递自定义字段键。

cURL

curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "firstName": "Jane", "do_not_disturb": true }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ firstName: "Jane", do_not_disturb: true }),
});
const data = await res.json();
console.log(data.message);

Python

import requests

res = requests.put(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"firstName": "Jane", "do_not_disturb": True},
)
print(res.json()["message"])

响应

{
  "success": true,
  "message": "Contact updated successfully"
}

自定义字段是合并而非替换。 发送 { "custom_fields": { "tier": "gold" } } 仅会设置 tier——联系人上的任何其他自定义字段将保持原样。若要从所有联系人中彻底删除某个自定义字段,请使用 删除自定义字段


添加或移除标签

POST /contacts/{contactId}/tags

在一次调用中为单个联系人添加和/或移除标签。请在 addTagIdsremoveTagIds 中传递标签 ID。两者中至少有一个必须非空。

这些标签必须已存在于您的账户中 — 请先通过 标签端点 创建它们。如果联系人或任何引用的标签不存在,您将收到 404

字段 描述
addTagIds 要添加到联系人的标签 ID 数组。
removeTagIds 要从联系人中移除的标签 ID 数组。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"] }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    addTagIds: ["tagHotLead"],
    removeTagIds: ["tagColdLead"],
  }),
});
const data = await res.json();
console.log(data.added, data.removed);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"]},
)
data = res.json()
print(data["added"], data["removed"])

响应

{
  "success": true,
  "contact_id": "contact_abc123",
  "added": 1,
  "removed": 1
}

管理您的标签库

这些端点用于管理标签本身(即在您的账户中重命名或删除标签),而不是为单个联系人添加或移除标签(请参阅上方的 添加或移除标签)。您账户中的每个标签都有一个 ID (tagId):即仪表板标签管理器中显示的 ID,也是您使用 POST /tags 并发送 JSON 正文 { "name": "..." }(不包含 phoneNumberemailcontactId)创建标签时返回的 data.tag_id

更新标签

PUT /tags/{tagId}

仅发送您需要更改的字段。

字段 描述
name 标签名称。
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagHotLead?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Hot lead (Q3)" }'

响应

{ "success": true, "tag_id": "tagHotLead" }

如果您的账户中不存在 tagId,则会返回 404

删除标签

DELETE /tags/{tagId}

按 ID 删除一个标签。此操作无法撤销——带有该标签的联系人将直接失去此标签。删除一个已不存在(或从未存在过)的标签会返回 200deleted: 0,而不是 404,因为没有内容可供枚举。

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"

响应

{ "success": true, "deleted": 1 }

同时删除多个标签

DELETE /tags

字段 描述
tagIds 要删除的标签 ID 数组(最多 1000 个)。
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tagIds": ["tagColdLead", "tagUnsubscribed"] }'

响应

{ "success": true, "deleted": 2 }

不存在或属于其他账户的 ID 将被静默跳过,且不会计入 deleted


批量设置标志

POST /contacts/bulk-flag

一次性为多个联系人设置一个布尔标志。每个请求最多支持 500 个联系人 ID。账户中不存在的 ID 将被跳过,并计入 skipped

字段 描述
contactIds 要更新的联系人 ID 数组(最多 500 个)。
field 要设置的标志。可选值:bot_active(AI 助手开启/关闭)、dnd(暂停自动外呼)、spamprivate
value 要设置的布尔值。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contactIds": ["contactId1", "contactId2"],
    "field": "bot_active",
    "value": false
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contactIds: ["contactId1", "contactId2"],
    field: "bot_active",
    value: false,
  }),
});
const data = await res.json();
console.log(data.updated, data.skipped);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contactIds": ["contactId1", "contactId2"],
        "field": "bot_active",
        "value": False,
    },
)
data = res.json()
print(data["updated"], data["skipped"])

响应

{
  "success": true,
  "updated": 2,
  "skipped": 0
}

批量导入联系人

POST /contacts/import

通过一个 JSON 数组在单次调用中最多创建 500 个联系人。每条记录都需要一个国际格式的 phone_number;其他所有字段均为可选。电话号码无效或渠道不受支持的记录将被跳过(不创建),且每条被跳过的记录都会报告其索引和原因——这样您只需修复失败的记录并重试即可。

默认情况下,账户中已存在的电话号码会作为 duplicate 被跳过。发送 updateExisting: true更新这些联系人:记录中存在的字段将覆盖联系人的原有信息(first_namelast_nameemaillead_profilecustom_fields 会按键合并),tags 会被添加,且联系人会被加入到 listId 中。现有联系人的渠道、电话号码和机器人标志永远不会被更改。

您可以选择将每个导入(或更新)的联系人通过 listId 添加到列表中,为未指定渠道的记录设置 defaultChannel,并使用 tags 为记录添加标签(标签名称——缺失的标签会被创建,现有的标签匹配时不区分大小写)。

顶级字段

字段 必填 说明
contacts 联系人记录数组(最多 500 个)。
listId 将每个导入(及更新)的联系人添加到的列表。必须是您账户中已有的列表。
defaultChannel 应用于省略了 channel 的记录的渠道。可选 whatsappsmswhatsapp_web 之一。默认为 whatsapp
updateExisting true 用于更新电话号码已存在的联系人,而不是将其作为 duplicate 跳过。默认为 false

单条记录字段

字段 必填 说明
phone_number 国际格式的电话号码(如果缺少,会自动添加前导 +)。
first_name 名字。
last_name 姓氏。
email 电子邮件地址。
channel 可选 whatsappsmswhatsapp_web 之一。回退至 defaultChannel
is_bot_active AI 助手是否回复。默认为 true
is_private 标记为私有。默认为 false
lead_profile 自由文本形式的潜在客户备注。
custom_fields 自定义字段键值对对象。
tags 标签名称数组(单个 "a; b" 字符串也适用)。不存在的标签会被创建;现有的标签匹配时不区分大小写。每条记录最多 25 个。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      { "phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"] },
      { "phone_number": "+12025551235", "first_name": "Bob" }
    ],
    "listId": "list123",
    "defaultChannel": "whatsapp_web",
    "updateExisting": true
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contacts: [
      { phone_number: "+12025551234", first_name: "Ann", last_name: "Lee", tags: ["vip", "newsletter"] },
      { phone_number: "+12025551235", first_name: "Bob" },
    ],
    listId: "list123",
    defaultChannel: "whatsapp_web",
    updateExisting: true,
  }),
});
const data = await res.json();
console.log(`Imported ${data.imported}, updated ${data.updated}, skipped ${data.skipped.length}`);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contacts": [
            {"phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"]},
            {"phone_number": "+12025551235", "first_name": "Bob"},
        ],
        "listId": "list123",
        "defaultChannel": "whatsapp_web",
        "updateExisting": True,
    },
)
data = res.json()
print(f"Imported {data['imported']}, updated {data['updated']}, skipped {len(data['skipped'])}")

响应

{
  "success": true,
  "imported": 2,
  "contact_ids": ["contact_abc123", "contact_def456"],
  "updated": 0,
  "updated_contact_ids": [],
  "skipped": []
}

如果某些记录无法创建,它们会出现在 skipped 中并附带原因(此处未设置 updateExisting,因此现有的号码被跳过):

{
  "success": true,
  "imported": 1,
  "contact_ids": ["contact_abc123"],
  "updated": 0,
  "updated_contact_ids": [],
  "skipped": [
    { "index": 1, "phone_number": "+12025551235", "reason": "duplicate" }
  ]
}

使用 updateExisting: true 时,相同的请求会将现有的联系人报告在 updated / updated_contact_ids 下。

可能的跳过原因:invalid_recordmissing_phone_numberinvalid_phone_numberinvalid_channelduplicate_in_requestduplicatecontact_limit_reachedcreate_failed

套餐限制。 如果您套餐的联系人上限不允许新增这么多联系人,整个请求会预先被拒绝并返回 403。如果是在处理过程中达到上限,剩余的记录将作为跳过项返回,原因为 contact_limit_reached


从 CSV 文件导入联系人

对于超过 批量导入 支持规模(最多约 50,000 行)的导入任务,请针对已存储在您账户中的 CSV 文件排队执行异步导入作业,然后轮询该作业直至完成。

开始导入

POST /contacts/import-csv

字段 必填 描述
csvStoragePath CSV 文件的存储路径,位于 users/{your account id}/imports/ 下,以 .csv 结尾。
listName 创建(或复用)一个具有此名称的列表,并将每个导入的联系人添加到其中。
existingListRefs 同时将每个导入的联系人添加到其中的现有列表 ID 数组。
defaultChannel 应用于未指定渠道的行的渠道。
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "csvStoragePath": "users/abc123/imports/leads.csv",
    "listName": "Webinar signups"
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    csvStoragePath: "users/abc123/imports/leads.csv",
    listName: "Webinar signups",
  }),
});
const data = await res.json();
console.log(data.job_id);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "csvStoragePath": "users/abc123/imports/leads.csv",
        "listName": "Webinar signups",
    },
)
job_id = res.json()["job_id"]

响应 (202 — 导入已排队,尚未完成)

{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "queued"
}

将文件存入存储。 此端点用于启动和跟踪导入作业;它本身不接受上传。在调用此端点之前,CSV 文件必须已位于 csvStoragePath — 控制台自带的 CSV 导入器会将此作为第一步操作。

轮询导入任务

GET /contacts/import-csv/{jobId}

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv/csvimp_abc123?apiKey=YOUR_API_KEY"

响应

{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "completed",
  "imported": 812,
  "updated": 0,
  "skipped": 14,
  "errors": [],
  "error_message": null
}

status 会经历 queuedprocessingcompleted,或者以 error_message 中的原因进入 failed 状态。如果账户中不存在 jobId,则返回 404


导出联系人

启动联系人的异步 CSV 导出任务,并返回一个可供轮询完成状态的作业。

开始导出

POST /contacts/export

字段 必填 说明
listId 仅导出属于此列表的联系人。
contactIds 仅导出这些特定的联系人 ID。

如果两者都不填,则导出您账户中的所有联系人。

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "listId": "list123" }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ listId: "list123" }),
});
const data = await res.json();
console.log(data.job_id);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"listId": "list123"},
)
job_id = res.json()["job_id"]

响应 (202 — 导出任务已加入队列)

{
  "success": true,
  "job_id": "export_abc123",
  "status": "queued"
}

轮询导出任务

GET /contacts/export/{jobId}

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export/export_abc123?apiKey=YOUR_API_KEY"

响应

{
  "success": true,
  "job_id": "export_abc123",
  "status": "completed",
  "export_id": "exp_xyz789",
  "contact_count": 812,
  "error_message": null
}

一旦 status 变为 "completed",您将收到 export_idcontact_count。生成的 CSV 文件可在您仪表板的“导出”页面下载。


向联系人发送消息

POST /contacts/{contactId}/send-message

向现有联系人发送消息,发送渠道为其当前所在的渠道。消息会被加入队列并在后台发送——响应仅确认消息已被接收,并不代表消息已送达。

字段 必填 说明
body 要发送的消息文本。
mediaUrl 要附加的媒体文件的 URL。
mediaContentType 附加媒体的 MIME 类型(例如 image/jpeg)。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Hi! Your appointment is confirmed." }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ body: "Hi! Your appointment is confirmed." }),
});
const data = await res.json();
console.log(data.messageId);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"body": "Hi! Your appointment is confirmed."},
)
print(res.json()["messageId"])

响应

{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact_abc123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}

无法立即发送? 如果联系人启用了“请勿打扰”或“私有模式”,或者不在支持接收外发消息的渠道上,请求会被拒绝并返回 422 以及解释性 error

如需通过电话号码、Instagram ID 或其他渠道标识(而非联系人 ID)进行发送,以及了解更多关于消息传递的信息,请参阅 消息 API


将 AI 代理分配给联系人

POST /contacts/{contactId}/assign-agent

将现有对话从下一条消息开始转移给不同的 AI 代理。这与聊天菜单中的 分配 AI 代理 功能相同,也是自动化流程中 分配 AI 代理或营销活动 操作所使用的步骤。

字段 必填 描述
agentId 应接管对话的 AI 代理 ID,或使用 null 清除分配,使对话返回到您的团队收件箱。
triggerAIResponse true 会让新分配的代理立即回复联系人最新未答复的消息。默认为 false

使用 triggerAIResponse: true 时请小心 —— 它会立即向联系人发送消息,因此仅在您希望立即联系他们时使用。在 Messenger 和 Instagram 上,如果联系人上次给您发消息是在 24 小时前,则该消息会发送失败。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "agent_xyz789" }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ agentId: "agent_xyz789" }),
});
const data = await res.json();
console.log(data.data.agentId);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"agentId": "agent_xyz789"},
)
print(res.json()["data"]["agentId"])

响应

{
  "success": true,
  "data": {
    "contactId": "contact_abc123",
    "agentId": "agent_xyz789",
    "aiResponseTriggered": false
  }
}

该代理必须与联系人属于同一个账户;否则请求将被拒绝,并返回 404403。您可以在“AI 代理”页面找到代理 ID(每个代理的 URL 末尾即为其 ID)。


为多个联系人分配 AI 代理

POST /contacts/bulk-assign-agent

通过一次调用将多个会话移动到不同的 AI 代理,或者使用 null 清除所有会话的分配。这纯粹是路由更改:不会发送任何消息,代理也不会回复任何人。每个联系人只需在下次发送消息时获得新代理即可。(这就是为什么这里没有 triggerAIResponse 的原因。)

字段 必填 描述
agentId 应接管的 AI 代理,或使用 null 清除分配。
contactIds 三选一 最多 500 个要移动的联系人 ID。
filter 三选一 在服务器上选择联系人而不是列出它们,按最新时间排序。使用与计数端点过滤器相同的键:agentId(或 none)、channeltaglistIdbotActivestatus
rules 三选一 智能列表规则对象 —— 请参阅 The smart_rules shape
limit 当您使用 filterrules 进行选择时,本次调用要移动的联系人数量。范围为 1 到 500,默认为 500。

发送 contactIdsfilterrules 中的恰好一个。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agent_xyz789",
    "filter": { "agentId": "agent_abc123", "channel": "messenger" }
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    agentId: "agent_xyz789",
    filter: { agentId: "agent_abc123", channel: "messenger" },
  }),
});
const data = await res.json();
console.log(data.updated, data.remaining);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "agentId": "agent_xyz789",
        "filter": {"agentId": "agent_abc123", "channel": "messenger"},
    },
)
data = res.json()
print(data["updated"], data["remaining"])

响应

{
  "success": true,
  "agentId": "agent_xyz789",
  "matched": 3415,
  "updated": 500,
  "skipped": 0,
  "remaining": 2915,
  "filters": { "agentId": "agent_abc123" }
}

matched 是选择找到的联系人总数,updated 是本次调用移动的联系人数量,skipped 是您发送的 ID 中在账户中未找到的数量,remaining 是调用完成后仍匹配条件的联系人数量。

移动所有人。 由于一次调用最多移动 500 个联系人,因此处理大型群体需要多次调用。使用一个在联系人移动后即停止匹配的过滤器(例如在分配给 agent_xyz789 时使用 filter: { "agentId": "agent_abc123" }),并重复执行完全相同的调用,直到 remaining 返回 0。当您改为传递 contactIds 时,remaining 始终为 0


将联系人分配给部门

POST /contacts/{contactId}/department

“将此潜在客户分配给销售部” — 将联系人归档到指定的部门下,并默认将其分配给该部门当前联系人最少的人员。这与分配 AI 代理是分开的:部门回答的是“哪个团队拥有此联系人”,而代理回答的是“哪个 AI 处理此联系人”,设置其中一个永远不会清除另一个。

字段 必填 说明
department_id 要将联系人归档到的部门。传入 null 可清除该设置。
hand_to_member 同时将联系人分配给该部门中负载最轻的人员。默认为 true。不会重新分配已有负责人拥有的联系人。

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "department_id": "dept_sales" }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ department_id: "dept_sales" }),
});
const data = await res.json();
console.log(data.assigned_to);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"department_id": "dept_sales"},
)
print(res.json()["assigned_to"])

响应

{
  "success": true,
  "department_id": "dept_sales",
  "assigned_to": "member_uid_123"
}

当联系人已有负责人,或者您传入了 hand_to_member: false 时,assigned_tonull


跨渠道关联联系人

“在 WhatsApp 上继续”(或短信)会查找或创建此人在另一个基于电话的渠道上的联系人,并将两者关联起来,以便应用程序的其他部分将其识别为同一个人。

链接到另一个渠道

POST /contacts/{contactId}/link-channel

字段 必填 描述
channel 要链接到的渠道。可以是 whatsappwhatsapp_websms 之一。
phoneNumber 在新渠道上使用的电话号码。默认为源联系人自己的号码。
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link-channel?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "sms" }'

响应

{
  "success": true,
  "data": {
    "contact_id": "contact_def456",
    "person_id": "person_xyz789",
    "created": true
  }
}

created 会告知您是为目标渠道铸造了新联系人,还是找到了现有的联系人并进行了关联。第二次调用此方法是安全的——它会返回相同的 contact_id 以及 created: false,而不会创建重复项。

422 表示账户目前无法执行此链接操作:联系人已在该渠道系列中、没有可用的电话号码,或者目标渠道没有已连接的发送方。409 表示这两个联系人已经链接到了两个不同的人——请先解除其中一个的链接。

列出联系人的已链接对话

GET /contacts/{contactId}/linked

返回与此联系人为同一人的其他对话。未链接的联系人会返回一个空数组,而不是 404——“此人没有其他渠道”是一种正常状态。

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/linked?apiKey=YOUR_API_KEY"

响应

{
  "success": true,
  "data": [
    {
      "contact_id": "contact_def456",
      "channel": "sms",
      "custom_channel": null,
      "first_name": "Jane",
      "last_name": "Smith",
      "phone_number": "+15551234567",
      "last_message": "Sounds good, thanks!",
      "last_message_timestamp": "2026-06-09T10:21:00.000Z",
      "linked_from": {
        "contact_id": "contact_abc123",
        "channel": "whatsapp",
        "linked_at": "2026-06-01T09:00:00.000Z",
        "reason": "continue_on_channel"
      }
    }
  ]
}

解除联系人链接

DELETE /contacts/{contactId}/link

单方面将此联系人从其所属的人员组中移除——仍链接到该人员的其他联系人将保留其链接,因此解除三个联系人中的一个并不会解散该组。

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link?apiKey=YOUR_API_KEY"

响应

{ "success": true }

获取联系人的头像

POST /contacts/{contactId}/profile-pic

按需获取(并缓存)联系人的 WhatsApp 或 Meta 头像——与 获取联系人 中返回的 avatarUrl 相同,但会进行刷新。

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/profile-pic?apiKey=YOUR_API_KEY"

响应

{
  "success": true,
  "avatar_url": "https://example.com/photo.jpg",
  "cached": false
}

cached: true 表示该 URL 来自最近的获取记录,而不是直接从提供商处查询——图片会缓存 7 天,如果提供商报告联系人没有可获取的头像,则会将其缓存为“不可用”状态,有效期为 24 小时。当没有图片可获取时,avatar_url 会被省略,并由 message 说明原因。


使用 AI 自动标记联系人

对一个或多个联系人的完整对话历史记录运行您账户的标签规则,并像实时聊天期间运行的实时标记一样应用(或移除)标签——规则相同,每个标签的积分成本也相同。

开始运行

POST /contacts/auto-tag

字段 必填 说明
scope 使用 "contacts" 标记特定联系人,或使用 "agent" 标记当前由一个 AI 代理处理的所有对话。
contact_ids scope"contacts" 时必填 联系人 ID 数组,1 到 500 个。
agent_id scope"agent" 时必填 要标记其对话的 AI 代理。当 scope"contacts" 时,此项可选,仅用于缩小运行该代理的哪些标签规则的范围。
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scope": "contacts", "contact_ids": ["contact_abc123", "contact_def456"] }'

单个联系人会内联运行并立即返回结果:

{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }

两个或更多联系人(或 scope: "agent")将作为后台作业运行,并立即返回 202

{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }

轮询运行状态

GET /contacts/auto-tag/run

返回账户当前(或最近一次)的运行状态,以便您可以轮询进度,而无需自行跟踪 run_id

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag/run?apiKey=YOUR_API_KEY"

响应

{
  "success": true,
  "run": {
    "run_id": "m1x2y3-a1b2c3d4",
    "status": "running",
    "total": 214,
    "processed": 58,
    "tagged_contacts": 12,
    "tags_applied": 15,
    "tags_removed": 2,
    "credits_charged": 15
  }
}

当账户从未启动过运行时,runnullstatus 会从 "running" 变为 "completed""failed"

每个账户一次只能进行一个批量运行——在另一个运行的同时启动第二个运行会返回 409error_code: "auto_tag_run_in_progress"。在单个联系人运行中积分用尽会返回 402error_code: "insufficient_credits";而批量运行则会提前停止,并在 run 中报告其完成进度。


删除联系人

DELETE /contacts/{contactId}

通过 ID 永久删除一个联系人及其消息历史记录。此操作无法撤销。 若要通过单个调用删除多个联系人,请使用下方的 删除联系人

cURL

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])

响应

{
  "success": true
}

如果联系人 ID 在您的账户中不存在,或属于其他账户,则会返回 404


删除联系人

DELETE /contacts

通过 ID 在单次调用中永久删除一个或多个联系人(最多 500 个 ID)。账户中不存在的 ID 会被跳过并计入 skipped此操作不可撤销。

字段 描述
contactIds 要删除的联系人 ID 数组(最多 500 个)。

cURL

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contactId1", "contactId2"] }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts", {
  method: "DELETE",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ contactIds: ["contactId1", "contactId2"] }),
});
const data = await res.json();
console.log(`Deleted ${data.deleted}, skipped ${data.skipped}`);

Python

import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contactId1", "contactId2"]},
)
data = res.json()
print(f"Deleted {data['deleted']}, skipped {data['skipped']}")

响应

{
  "success": true,
  "deleted": 2,
  "skipped": 0
}

删除自定义字段

DELETE /contacts/custom-fields/{fieldKey}

从您账户中的每个联系人中移除一个自定义字段键。在重命名或停用自定义字段后,请使用此功能进行清理。该键只能包含字母、数字、下划线和连字符。返回已更新的联系人数量。此操作无法撤销。

cURL

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(`Removed from ${data.updated} contacts`);

Python

import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(f"Removed from {res.json()['updated']} contacts")

响应

{
  "success": true,
  "updated": 42
}

注意: 包含不支持字符的字段键会返回 400


列表

列表用于对联系人进行分组。列表可以是静态的(由您决定谁在列表中)或智能的(成员资格根据规则计算并自动保持最新 — 请参阅 组织列表与联系人)。

字段 描述
name 创建时必填。最多 100 个字符。
status live(默认)或 draft。小写。
contact_ids 要放入列表的联系人 ID 数组。仅限静态列表。
type static(默认)或 smart
smart_rules 规则集 — 当 typesmart 时必填。详见下文。

创建列表

POST /lists

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Hot leads (active)",
        "type": "smart",
        "smart_rules": {
          "match": "all",
          "conditions": [
            { "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
            { "field": "last_activity_at", "op": "within_last", "value": { "amount": 90, "unit": "days" } }
          ]
        }
      }'

响应

{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 3, "removed": 0, "total": 3 }
}

智能列表会在同一请求中进行内联评估,因此 evaluation 会准确告诉您最终谁在列表中。对于静态列表,evaluationnull

更新列表

PUT /lists/{listId}

仅发送您要更改的字段。更改 smart_rules 会立即重新评估列表并返回相同的 evaluation 对象。

curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/list_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "smart_rules": { "match": "any", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead", "tagWebinar"] } ] } }'

您可以在两种列表类型之间进行切换:

  • 静态 → 智能:发送 { "type": "smart", "smart_rules": { … } }。规则会立即生效。
  • 智能 → 静态:发送 { "type": "static" }。规则将被删除,当前列表中的成员将保持不变。

smart_rules 的结构

{
  "match": "all",
  "conditions": [
    { "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
    { "field": "channel", "op": "is_any", "value": ["whatsapp", "sms"] },
    { "field": "last_incoming_message_at", "op": "not_within_last", "value": { "amount": 7, "unit": "days" } },
    { "field": "created_at", "op": "after", "value": "2026-01-01" },
    { "field": "is_bot_active", "op": "is", "value": true },
    { "field": "email", "op": "is_set" },
    { "field": "custom_field", "key": "Plan", "op": "eq", "value": "pro" }
  ]
}
  • matchall(所有条件必须为真)或 any(至少满足一个)。
  • conditions — 1 到 20 个条件,每个条件最多 100 个值,字符串最多 200 个字符。
field op value
tags has_any, has_all, has_none 标签 ID 数组
lists in_any, not_in_any 列表 ID 数组(仅限静态列表 — 智能列表不能由另一个智能列表构建)
channel is_any, is_none 渠道数组
status is_any, is_none 联系人状态数组
created_at, last_activity_at, last_incoming_message_at, last_outgoing_message_at, first_ai_interaction_at, last_ai_interaction_at within_last, not_within_last { "amount": 1–3650, "unit": "hours" | "days" }
相同日期字段 before, after ISO 日期("2026-01-01",按整天比较)或完整 ISO 日期时间("2026-01-01T14:30:00Z",按精确时刻比较)
相同日期字段 is_set, not_set
has_interacted_with_ai is true / falsetrue 匹配 AI 至少发送过一次消息(任何时候)的联系人
is_bot_active, do_not_disturb, is_private, has_ever_responded is true / false
email, phone_number, first_name, last_name is_set, not_set, contains, not_contains 用于 contains 表单的字符串
current_campaign_id, assigned_agent is_any, is_none, is_set, not_set 用于 is_any / is_none 表单的 ID 数组
custom_field(外加一个 key eq, neq, contains, not_contains, is_set, not_set 用于值表单的字符串

not_within_last 也会匹配从未设置过日期的联系人(“超过 N 天前,或从未设置”),并且文本比较会忽略大小写。

AI 互动。 has_interacted_with_ai 是生命周期标志:true 表示您的 AI 至少向其发送过一条消息的每位联系人,false 表示其他人(包括仅由您的团队回复过的联系人)。它会在 AI 向联系人发送第一条消息时打上标记,且永远不会清除,因此关闭联系人的 AI 回复或将其移动到另一个营销活动不会重置该标记。对于周期——即“我的 AI 本月处理的联系人”,这是常见的计费问题——请改用 last_ai_interaction_at 范围:

{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }

不要将两者与 is_bot_active(AI 被允许回复,并不代表它已经回复)或 has_ever_responded联系人回复了任何人)混淆。这两个相同的标记会作为 first_ai_interaction_at / last_ai_interaction_at 返回到每个联系人上,并且整套规则也适用于 GET /contacts?rules=,因此您无需创建列表即可计算匹配项。

预览规则集

POST /lists/preview

统计并采样规则集将匹配的联系人,而无需创建或更改任何内容。在保存规则之前,请使用此功能进行健全性检查。

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/preview?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "smart_rules": { "match": "all", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead"] } ] } }'

响应

{
  "success": true,
  "count": 3,
  "sample": [
    {
      "id": "contact_abc123",
      "first_name": "Sofia",
      "last_name": "Martinez",
      "phone_number": "+31600000000",
      "email": "sofia@example.com",
      "channel": "whatsapp"
    }
  ]
}

sample 最多可容纳 10 个联系人,按最近活跃时间排序。

立即重新运行智能列表

POST /lists/{listId}/evaluate

强制立即进行重新评估(与仪表板中的 立即刷新 功能相同)。智能列表在联系人发生更改时会自动更新,并且每 15 分钟会对基于时间的规则进行一次更新,因此仅在您需要“立即”获取结果时才需要此操作。

响应

{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 2, "removed": 1, "total": 4 }
}

evaluation.skipped: true 表示该列表的另一次评估已经在运行,因此本次调用未执行任何操作。

智能列表拒绝手动添加的成员

当目标列表为智能列表时,成员资格端点会返回 409 以及 "This is a smart list — its members are computed from its rules. Edit the rules instead."。这涵盖了 POST /contacts/listsDELETE /contacts/listsPOST /contacts/lists/batchcontact_idsPOST /listsPUT /lists/{listId} 上的操作,以及选择智能列表作为 CSV 导入目标的情况。请改为更改规则。

静态 列表上调用 POST /lists/{listId}/evaluate 也是 409 —— 因为它没有可运行的规则。


联系人 API 错误

联系人端点返回标准的错误信封:

{
  "success": false,
  "error": "Contact not found"
}

某些端点还包含 error_code,它通常与 HTTP 状态匹配 —— 唯一的例外是下文提到的重复联系人情况,此时 HTTP 状态为 200,且仅 error_code 携带 409。联系人端点特有的代码如下:

代码 在联系人端点发生的情况
400 错误请求 — 缺少/无效字段、空正文、错误的游标,或批量处理超过 500 个 ID。
402 积分不足,无法对单个联系人执行 AI 标记运行 (error_code: "insufficient_credits")。
404 在您的账户中未找到该联系人、列表或标签。
409 具有该电话号码的联系人已存在(创建时)。在正文中以 error_code 返回,HTTP 状态码为 200,因此请在此处根据 error_code 进行分支处理。当批量自动标记运行已在进行中 (error_code: "auto_tag_run_in_progress"),或者将联系人链接到另一个渠道会导致将已链接到两个不同人员的两个联系人合并时,也会返回此错误。
422 联系人目前无法接收消息(请勿打扰、私密或不支持的渠道)。在渠道链接端点上,也涵盖了无电话号码、不支持的渠道配对或目标渠道没有已连接的发送者的情况。

联系人端点上的 403 也可能意味着联系人限制或列表权限问题,而非计划访问权限问题。每个端点都可能返回的共享代码 —— 401403(您的计划不包含 API 访问权限)、429(速率限制)和 500 —— 及其重试指南列在 错误与分页 中。


后续步骤

  • 消息 API — 通过渠道身份发送消息并管理对话。
  • API 参考 — 完整的端点列表,包括标签和列表。
  • API 访问 — 身份验证、速率限制和错误处理。