API Liên hệ
Liên hệ là một cá nhân mà bạn nhắn tin — bao gồm tên, số điện thoại, email, kênh, thẻ, trường tùy chỉnh, cũng như các danh sách và chiến dịch mà họ thuộc về. API Liên hệ cho phép bạn tạo, tra cứu, cập nhật, gắn thẻ, nhập hàng loạt và xóa liên hệ mà không cần sử dụng bảng điều khiển.
Tất cả các đường dẫn trên trang này đều tương đối so với URL cơ sở:
https://api.youraiconnector.com/v1
Vì vậy /contacts có nghĩa là https://api.youraiconnector.com/v1/contacts.
Bạn mới sử dụng API? Hãy đọc Truy cập API trước — phần này bao gồm cách tạo khóa API, ba cách xác thực, giới hạn tốc độ và định dạng lỗi. Mọi nội dung trên trang này giả định rằng bạn đã có khóa API đang hoạt động.
Về ID liên hệ
Mỗi liên hệ có một ID duy nhất. ID bạn nhận được khi tạo một liên hệ (trong data.contactId) cũng chính là ID bạn sử dụng ở mọi nơi khác — để tìm nạp, cập nhật, gắn thẻ, gửi tin nhắn hoặc xóa liên hệ đó. Hãy lưu lại một lần và sử dụng lại.
Bạn không cần phải tạo liên hệ để lấy ID của nó. Bạn cũng có thể tra cứu theo số điện thoại hoặc email (xem Lấy thông tin liên hệ), hoặc duyệt qua tất cả các liên hệ của bạn (xem Liệt kê liên hệ). Mỗi phương thức đó đều trả về cùng một ID.
Tạo liên hệ
POST /contacts
Thêm một liên hệ mới vào tài khoản của bạn. Bắt buộc phải có số điện thoại kèm mã quốc gia — chỉ email là không đủ. Mọi thông tin khác đều là tùy chọn.
Bạn có thể tùy chọn đưa liên hệ mới trực tiếp vào một hoặc nhiều danh sách với listId (một danh sách đơn lẻ) hoặc listIds (một mảng). Nếu cả hai đều được gửi, listIds sẽ được ưu tiên.
Bất kỳ trường nào bạn gửi không nằm trong các trường tạo tiêu chuẩn được liệt kê trong bảng trường Tạo liên hệ bên dưới (phoneNumber, firstName, lastName, email, channel, is_bot_active, is_private, lead_profile, listId, listIds, custom_fields) sẽ tự động được lưu trữ dưới dạng trường tùy chỉnh — vì vậy một payload phẳng từ các công cụ như Make hoặc Zapier sẽ hoạt động mà không cần lồng ghép. Bạn cũng có thể truyền một đối tượng custom_fields tường minh.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
phoneNumber |
Có | Số điện thoại của liên hệ, kèm mã quốc gia (ví dụ: +15551234567). |
firstName |
Không | Tên. |
lastName |
Không | Họ. |
email |
Không | Địa chỉ email. |
channel |
Không | Kênh nhắn tin. Một trong các giá trị whatsapp, sms, whatsapp_web. Mặc định là whatsapp. |
is_bot_active |
Không | Liệu trợ lý AI có trả lời liên hệ này hay không. Mặc định là true. |
is_private |
Không | Đánh dấu liên hệ là riêng tư. Khi là true, trợ lý AI sẽ bị tắt đối với họ. Mặc định là false. |
lead_profile |
Không | Ghi chú văn bản tự do về khách hàng tiềm năng. |
listId |
Không | Một ID danh sách duy nhất để thêm liên hệ vào. |
listIds |
Không | Một mảng các ID danh sách để thêm liên hệ vào (ưu tiên hơn listId). |
custom_fields |
Không | Một đối tượng chứa các trường khóa/giá trị của riêng bạn. Bạn cũng có thể truyền các trường này dưới dạng khóa cấp cao nhất. Các trường có kiểu dữ liệu (ngày tháng, số, danh sách thả xuống, hộp kiểm) sẽ được xác thực — xem Các loại trường tùy chỉnh. |
Các tên thay thế phổ biến được chấp nhận khi thiếu tên chuẩn: phone hoặc phone_number cho số điện thoại, first_name và last_name cho tên, và full_name hoặc name, vốn được tách thành tên và họ. Do đó, lỗi Missing required fields: phoneNumber có nghĩa là không có giá trị số điện thoại nào được gửi đến, chứ không phải do khóa được viết khác đi.
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"])
Phản hồi
{
"success": true,
"data": {
"message": "Successfully created new contact",
"contactId": "contact_abc123",
"listsAdded": ["list123", "list456"]
}
}
ID của liên hệ mới nằm tại data.contactId. Các danh sách mà liên hệ đó được thêm vào sẽ được phản hồi lại trong data.listsAdded.
Các bản sao sẽ không được tạo. Nếu một liên hệ có cùng số điện thoại đã tồn tại trên kênh bạn đang tạo, lệnh gọi tạo sẽ không tạo thêm bản sao thứ hai. Phản hồi trả về với trạng thái HTTP
200vàerror_codelà409trong phần nội dung, vì vậy hãy phân nhánh dựa trênerror_codethay vì trạng thái HTTP. ID của liên hệ hiện có sẽ được trả về dưới dạngcontactId(vàdata.contactId), vì vậy bạn có thể tiếp tục sử dụng nó ngay lập tức:{ "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user.", "contactId": "abc123", "data": { "contactId": "abc123" } }Điều tương tự cũng áp dụng cho địa chỉ email trùng lặp trên kênh Email. Nếu vị trí trong nhóm của bạn chỉ có thể xem các liên hệ của riêng mình và liên hệ hiện có không nằm trong số đó, ID sẽ bị bỏ qua; thay vào đó, hãy tra cứu bằng Lấy liên hệ theo số điện thoại hoặc email.
Các cách viết số WhatsApp tương đương được tính là cùng một số. Một số quốc gia có hai cách viết hợp lệ cho cùng một đường dây di động và WhatsApp có thể báo cáo một trong hai cách: Mexico (
+52…và định dạng cũ+521…), Brazil (có hoặc không có chữ số thứ chín) và Argentina (có hoặc không có9sau+54). Kiểm tra trùng lặp khi tạo và khớpGET /contacts?phoneNumber=trên cả hai cách viết, vì vậy bạn sẽ nhận lại liên hệ hiện có bất kể bạn gửi dưới dạng nào.phone_numberđược lưu trữ trên liên hệ sẽ không bao giờ bị ghi đè.
Lấy thông tin liên hệ theo số điện thoại hoặc email
GET /contacts?phoneNumber=... hoặc GET /contacts?email=...
Tìm kiếm một liên hệ duy nhất và trả về đối tượng liên hệ đầy đủ, đã được làm giàu — bao gồm các danh sách, thẻ và chiến dịch của nó được phân giải thành các cặp { id, name }, cộng với tin nhắn cuối cùng đã trao đổi.
Truyền hoặc phoneNumber (theo định dạng quốc tế) hoặc email. Nếu bạn không truyền cả hai, điểm cuối này sẽ chuyển sang chế độ Liệt kê các liên hệ.
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"])
Phản hồi
{
"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"
},
"adAttribution": {
"visit_at": "2026-06-09T10:14:02.000Z",
"matched_at": "2026-06-09T10:14:20.000Z",
"match_method": "reference",
"reference": "4827",
"fbc": "fb.1.1749463000000.IwAR...",
"fbp": "fb.1.1749000000000.123456789",
"fbclid": "IwAR...",
"gclid": null,
"gbraid": null,
"wbraid": null,
"utm_source": "facebook",
"utm_medium": "paid",
"utm_campaign": "spring-promo",
"utm_content": null,
"utm_term": null,
"landing_url": "https://yoursite.com/quiz?utm_source=facebook&utm_campaign=spring-promo",
"referrer": "https://l.facebook.com/",
"client_ip": "203.0.113.7",
"user_agent": "Mozilla/5.0 (iPhone; ...)",
"site_key": "YOUR_SITE_KEY",
"visit_id": "visit_abc123"
}
}
}
adAttribution là lượt nhấp vào quảng cáo dẫn đến trang web của bạn, được khớp với liên hệ này bởi tập lệnh nhấp quảng cáo, hoặc null khi không có lượt nhấp nào. Các trường này được giải thích trong Gán lượt nhấp quảng cáo cho WhatsApp.
ID liên hệ được trả về ở cả cấp cao nhất (contactId) và bên trong đối tượng (contact.id). Nếu không có kết quả khớp, bạn sẽ nhận được 404 với { "success": false, "message": "Contact not found" }.
avatarUrllà ảnh hồ sơ của liên hệ, được lấy từ WhatsApp hoặc Meta khi họ nhắn tin cho bạn. Đây là trường chỉ đọc: bạn không thể thiết lập nó và nó sẽ lànullđối với các liên hệ không có ảnh hoặc liên hệ với bạn qua kênh không chia sẻ ảnh. Hãy coi liên kết này là tạm thời thay vì lưu trữ nó, vì một số liên kết ảnh này sẽ hết hạn và được làm mới tự động. (Trong điểm cuối danh sách bên dưới, giá trị tương tự được gọi làavatar_url.)
Số điện thoại trong URL. Dấu
+trong chuỗi truy vấn phải được mã hóa URL thành%2B, nếu không nó sẽ được đọc là một khoảng trắng. Các ví dụ trên đã thực hiện việc này cho bạn.
Các liên hệ bị ẩn số điện thoại
Một liên hệ trên WhatsApp Web có thể xuất hiện mà không có số điện thoại khi WhatsApp không cung cấp thông tin này cho thiết bị được liên kết (xem Các liên hệ bị ẩn số điện thoại). Mỗi liên hệ bạn đọc được sẽ mang hai trường bổ sung cho mục đích này: number_hidden (numberHidden trên cấu trúc liên hệ đơn lẻ) và whatsapp_lid (whatsappLid).
- Đối với một liên hệ bị ẩn số,
phone_numberlànull,number_hiddenlàtruevàwhatsapp_lidchứa ID nội bộ của WhatsApp, dưới dạng153055538446346@lid. Đây không phải là số điện thoại có thể gọi được. Hãy khớp liên hệ đó với ID từ hệ thống của riêng bạn và truyền nó dưới dạngphoneNumbervào tra cứu này để tìm lại liên hệ. - Đối với mọi liên hệ khác,
number_hiddenlàfalsevàwhatsapp_lidlà ID mà WhatsApp báo cáo cho liên hệ đó, hoặcnull.
Các webhook gửi đi và payload tự động hóa bao gồm liên hệ sẽ mang ba trường tương tự, và tệp CSV xuất liên hệ có các cột “Number Hidden” (Ẩn số) và “WhatsApp LID” bên cạnh “Phone Number” (Số điện thoại). Khi WhatsApp chia sẻ số điện thoại thực, liên hệ sẽ tự động cập nhật và phone_number sẽ được điền thông tin.
Lấy thông tin liên hệ theo ID
GET /contacts/{contactId}
Khi bạn đã có ID của một liên hệ, hãy truy xuất trực tiếp thông tin đó. Cấu trúc phản hồi giống hệt với thao tác tra cứu ở trên.
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"])
Một ID liên hệ không tồn tại trong tài khoản của bạn sẽ trả về 404.
Lấy thống kê liên hệ
GET /contacts/{contactId}/stats
Trả về thống kê tin nhắn tổng hợp cho một liên hệ: tổng số, số lượng phản hồi của AI so với con người, số tín dụng đã sử dụng và dấu thời gian của tin nhắn đầu tiên/cuối cùng.
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"])
Phản hồi
{
"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 là bộ đếm tin nhắn AI tương tự như nút “đặt lại” trong ứng dụng mà bạn dùng để đưa số liệu về không cho một liên hệ. creditsUsed là tổng số tín dụng đang chạy cho liên hệ này, không chỉ là các con số của phản hồi này. ID liên hệ không tồn tại trong tài khoản của bạn sẽ trả về 404.
Lấy chi phí liên hệ
GET /contacts/{contactId}/cost
Trả về số tín dụng mà một liên hệ đã sử dụng, được chia theo cuộc trò chuyện (phiên chat), theo loại hành động và chi phí trung bình của một cuộc trò chuyện do AI tự xử lý so với cuộc trò chuyện mà nhóm của bạn đã tham gia. Sử dụng tính năng này để cho khách hàng thấy chi phí của một cuộc trò chuyện.
cURL
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.total_credits, data.by_session.length);
Python
import requests
res = requests.get(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["total_credits"], data["summary"]["contained"]["avg_credits"])
Phản hồi
{
"success": true,
"contact_id": "contact_abc123",
"total_credits": 23,
"refunded_credits": 0,
"unattributed_credits": 0,
"by_session": [
{
"session_id": "hpWKxuTSXIKlylze5Ulx",
"start": "2026-09-21T00:00:00.000Z",
"end": "2026-09-24T17:41:52.052Z",
"status": "ChatSessionClosed",
"tag": null,
"credits": 7,
"actions": 7,
"outcome": "handed_off"
},
{
"session_id": "5kKnkI3DD4THIh2YVjey",
"start": "2026-09-09T00:00:00.000Z",
"end": "2026-09-11T22:42:34.056Z",
"status": "ChatSessionClosed",
"tag": null,
"credits": 13,
"actions": 14,
"outcome": "contained"
}
],
"by_type": [
{ "type": "AI Chat Conclude Evaluation", "credits": 8, "actions": 8 },
{ "type": "AI Tool Use", "credits": 4, "actions": 4 },
{ "type": "AI Message", "credits": 2, "actions": 2 }
],
"summary": {
"contained": { "sessions": 1, "credits": 13, "avg_credits": 13 },
"handed_off": { "sessions": 1, "credits": 7, "avg_credits": 7 },
"no_ai": { "sessions": 0, "credits": 0, "avg_credits": 0 }
},
"sessions_truncated": false
}
Ghi chú trường:
total_creditstính mọi khoản phí đối với liên hệ (phản hồi của AI, lệnh gọi công cụ, thẻ, phần tiếp theo, tóm tắt, các bước đánh giá nền, phí mẫu và phí gửi) với các khoản hoàn tiền cho liên hệ đã được trừ đi. Các khoản cấp tín dụng, nạp thêm và gia hạn không bao giờ thuộc về một liên hệ. Các lượt chạy thử nghiệm trong Playground bị loại trừ.- Một khoản phí sẽ được tính vào cuộc trò chuyện nằm trong phạm vi thời gian của nó. Một phạm vi thời gian chạy từ khi cuộc trò chuyện bắt đầu cho đến khi nó kết thúc hoặc cuộc trò chuyện tiếp theo bắt đầu, vì vậy không có khoản phí nào được tính hai lần. Các khoản phí nằm ngoài mọi phạm vi thời gian sẽ nằm trong
unattributed_credits(và trong tổng số). outcome:containednghĩa là AI đã phản hồi và không ai trong nhóm của bạn phải can thiệp;handed_offnghĩa là ai đó đã gửi tin nhắn sau khi AI đã phản hồi, hoặc AI đã cảnh báo một người;no_ainghĩa là AI không bao giờ phản hồi trong cuộc trò chuyện đó.- Tối đa 200 cuộc trò chuyện được liệt kê, mới nhất trước;
sessions_truncatedlàtruekhi có nhiều hơn. - Đối với khách hàng đại lý, hãy chuyển
sub_account_id; các con số được tính bằng tín dụng riêng của khách hàng đó. creditsUsedtrên Lấy số liệu thống kê liên hệ là một bộ đếm chạy liên tục được lưu trên liên hệ. Điểm cuối này xây dựng lại con số từ sổ cái tín dụng, vì vậy hai con số này có thể khác nhau một chút, chủ yếu ở các liên hệ cũ hơn.- Các thành viên trong nhóm cần có quyền thanh toán. Một liên hệ không có trong tài khoản của bạn sẽ trả về
404;503nghĩa là các con số không thể được tính toán ngay bây giờ, hãy thử lại sau một lát.
Liệt kê các liên hệ
GET /contacts
Gọi GET /contacts mà không kèm theo phoneNumber hoặc email để phân trang qua tất cả các liên hệ của bạn, hiển thị theo thứ tự mới nhất trước. Mỗi trang trả về các bản tóm tắt liên hệ rút gọn (danh sách, thẻ và chiến dịch được trả về dưới dạng mảng ID thay vì đối tượng đầy đủ) và một next_cursor.
| Tham số truy vấn | Mô tả |
|---|---|
limit |
Kích thước trang. Mặc định là 50, tối đa là 100. |
cursor |
Giá trị next_cursor từ trang trước. Bỏ qua tham số này ở trang đầu tiên. |
listId |
Tùy chọn. Chỉ trả về các liên hệ thuộc danh sách này. |
Để duyệt qua mọi trang: thực hiện cuộc gọi đầu tiên mà không cần con trỏ (cursor), sau đó tiếp tục truyền next_cursor nhận được vào cursor. Dừng lại khi next_cursor là null — điều đó có nghĩa là không còn kết quả nào nữa.
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
Phản hồi
{
"success": true,
"contacts": [
{
"id": "contact_abc123",
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"phone_number": "+15551234567",
"number_hidden": false,
"whatsapp_lid": null,
"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",
"ad_attribution": null
}
],
"next_cursor": "contact_abc123"
}
Mỗi liên hệ đều có ad_attribution: lượt nhấp vào quảng cáo dẫn đến trang web của bạn, được khớp với liên hệ, với các trường tương tự như adAttribution trên Lấy liên hệ theo ID, hoặc null khi không có lượt nhấp nào.
Lưu ý: Việc lọc theo listId không tồn tại trong tài khoản của bạn sẽ trả về 404. Một cursor không hợp lệ sẽ trả về 400.
Đếm liên hệ
GET /contacts/count
Trả về số lượng liên hệ khớp với bộ lọc, kèm theo phân tách theo từng kênh, mà không cần phân trang. Đây là lệnh gọi phù hợp cho bất kỳ câu hỏi “bao nhiêu” nào — một ô trên bảng điều khiển, một quy trình tự động hóa hoặc khi hỏi Champ. Tất cả các bộ lọc đều là tùy chọn và việc kết hợp nhiều bộ lọc sẽ thu hẹp kết quả đếm (một liên hệ phải khớp với mọi bộ lọc bạn gửi).
| Tham số truy vấn | Mô tả |
|---|---|
agentId |
Chỉ các liên hệ được chỉ định cho AI agent này. Truyền none cho các liên hệ không có agent được chỉ định (những liên hệ này được trả lời bởi agent mặc định của kênh). |
channel |
Chỉ các liên hệ trên kênh này, ví dụ: whatsapp, messenger, instagram, sms, email, chat_widget. |
tag |
Chỉ các liên hệ mang thẻ này, theo tên thẻ (không phân biệt chữ hoa/thường). Tên thẻ không tồn tại sẽ trả về 404. |
listId |
Chỉ các liên hệ trong danh sách này. |
botActive |
true hoặc false — chỉ các liên hệ có trợ lý AI đang bật hoặc tắt. |
status |
Chỉ các liên hệ có trạng thái này, ví dụ: Lead. |
rules |
Một đối tượng quy tắc JSON đã mã hóa URL, sử dụng cùng định dạng với danh sách thông minh (xem Định dạng smart_rules bên dưới). Không thể kết hợp với các bộ lọc khác. |
Không gửi bộ lọc nào và bạn sẽ nhận được tổng số liên hệ trong tài khoản của mình.
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"])
Phản hồi
{
"success": true,
"total": 3423,
"by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
"filters": { "agentId": "agent_xyz789" }
}
by_channel phân tách tổng số tương tự theo từng kênh; các liên hệ không nằm trên bất kỳ kênh nào sẽ được tính trong none. filters phản hồi lại các bộ lọc đã được áp dụng để bạn có thể kiểm tra xem lệnh gọi đã thực hiện đúng ý mình chưa.
Lưu ý: Gửi rules cùng với bất kỳ bộ lọc nào khác, hoặc giá trị rules không phải là JSON hợp lệ, sẽ trả về 400. Tên thẻ hoặc ID danh sách không tồn tại trong tài khoản của bạn sẽ trả về 404.
Cập nhật liên hệ
PUT /contacts/{contactId}
Cập nhật một liên hệ hiện có. Chỉ những trường bạn bao gồm mới bị thay đổi — hãy bỏ qua bất kỳ nội dung nào bạn không muốn chỉnh sửa. Bạn phải gửi ít nhất một trường, nếu không bạn sẽ nhận được 400 (“Không có trường nào để cập nhật”).
| Trường | Mô tả |
|---|---|
firstName |
Tên. |
lastName |
Họ. |
email |
Địa chỉ email. |
is_bot_active |
Liệu trợ lý AI có trả lời liên hệ này hay không. |
is_private |
Đánh dấu là riêng tư. Đặt giá trị này thành true cũng sẽ tắt trợ lý AI. |
do_not_disturb |
Tạm dừng tiếp cận tự động đối với liên hệ này. Đồng thời ngăn AI trả lời. |
follow_ups_disabled |
Dừng tất cả các theo dõi tự động cho liên hệ này (nhanh, chu kỳ và khách hàng tiềm năng lạnh) trong khi AI vẫn tiếp tục trả lời các tin nhắn họ gửi. Hữu ích khi ai đó đã mua hàng. Trạng thái này sẽ duy trì cho đến khi bạn đặt lại thành false. |
lead_profile |
Ghi chú văn bản tự do về khách hàng tiềm năng. |
custom_fields |
Một đối tượng chứa các trường tùy chỉnh. Được hợp nhất theo khóa — chỉ các khóa bạn gửi mới được ghi lại, các trường tùy chỉnh hiện có còn lại sẽ được giữ nguyên. Bạn cũng có thể truyền các khóa trường tùy chỉnh ở cấp cao nhất. Các trường có kiểu dữ liệu sẽ được xác thực và giá trị không hợp lệ sẽ khiến yêu cầu bị từ chối với field_errors — xem Các loại trường tùy chỉnh. |
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"])
Phản hồi
{
"success": true,
"message": "Contact updated successfully"
}
Các trường tùy chỉnh được hợp nhất, không phải thay thế. Việc gửi
{ "custom_fields": { "tier": "gold" } }chỉ thiết lậptier— bất kỳ trường tùy chỉnh nào khác trên liên hệ vẫn giữ nguyên như cũ. Để xóa hoàn toàn một trường tùy chỉnh trên tất cả các liên hệ, hãy sử dụng Xóa trường tùy chỉnh.
Thêm hoặc xóa thẻ
POST /contacts/{contactId}/tags
Thêm và/hoặc xóa thẻ trên một liên hệ duy nhất trong một lệnh gọi. Truyền ID thẻ vào addTagIds và removeTagIds. Ít nhất một trong hai phải không được để trống.
Các thẻ phải tồn tại trong tài khoản của bạn — hãy tạo chúng trước thông qua endpoint thẻ. Nếu liên hệ hoặc bất kỳ thẻ nào được tham chiếu không tồn tại, bạn sẽ nhận được 404.
| Trường | Mô tả |
|---|---|
addTagIds |
Mảng các ID thẻ cần thêm vào liên hệ. |
removeTagIds |
Mảng các ID thẻ cần xóa khỏi liên hệ. |
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"])
Phản hồi
{
"success": true,
"contact_id": "contact_abc123",
"added": 1,
"removed": 1
}
Quản lý thư viện thẻ của bạn
Các endpoint này quản lý chính thẻ đó — đổi tên hoặc xóa thẻ trong tài khoản của bạn — thay vì áp dụng hoặc xóa thẻ trên một liên hệ (xem Thêm hoặc xóa thẻ ở trên). Mỗi thẻ trong tài khoản của bạn đều có một ID (tagId): ID được hiển thị trong trình quản lý thẻ trên bảng điều khiển của bạn và ID được trả về dưới dạng tag_id ở cấp cao nhất của phản hồi khi bạn tạo thẻ bằng POST /tags và phần thân JSON là { "name": "..." } (không có phoneNumber, email hoặc contactId).
Cập nhật thẻ
PUT /tags/{tagId}
Chỉ gửi các trường bạn đang thay đổi.
| Trường | Mô tả |
|---|---|
name |
Tên của thẻ. |
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)" }'
Phản hồi
{ "success": true, "tag_id": "tagHotLead" }
Một tagId không tồn tại trong tài khoản của bạn sẽ trả về 404.
Xóa thẻ
DELETE /tags/{tagId}
Xóa một thẻ theo ID. Hành động này không thể hoàn tác — các liên hệ đang mang thẻ đó sẽ bị mất thẻ. Việc xóa một thẻ đã không còn tồn tại (hoặc chưa từng tồn tại) sẽ trả về 200 với deleted: 0 thay vì 404, vì không có gì để liệt kê.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"
Phản hồi
{ "success": true, "deleted": 1 }
Xóa nhiều thẻ cùng lúc
DELETE /tags
| Trường | Mô tả |
|---|---|
tagIds |
Mảng các ID thẻ cần xóa (tối đa 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"] }'
Phản hồi
{ "success": true, "deleted": 2 }
Các ID không tồn tại hoặc thuộc về tài khoản khác sẽ bị bỏ qua một cách âm thầm và không được tính vào deleted.
Thiết lập cờ hàng loạt
POST /contacts/bulk-flag
Thiết lập một cờ boolean trên nhiều liên hệ cùng lúc. Tối đa 500 ID liên hệ mỗi yêu cầu. Các ID không tồn tại trong tài khoản của bạn sẽ bị bỏ qua và được tính trong skipped.
| Trường | Mô tả |
|---|---|
contactIds |
Mảng các ID liên hệ cần cập nhật (tối đa 500). |
field |
Cờ cần thiết lập. Một trong các giá trị bot_active (bật/tắt trợ lý AI), dnd (tạm dừng tiếp cận tự động), spam, private. |
value |
Giá trị boolean để thiết lập cho cờ. |
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"])
Phản hồi
{
"success": true,
"updated": 2,
"skipped": 0
}
Nhập liên hệ hàng loạt
POST /contacts/import
Tạo tối đa 500 liên hệ trong một lệnh gọi từ một mảng JSON. Mỗi bản ghi cần có một phone_number ở định dạng quốc tế; mọi thông tin khác đều là tùy chọn. Các bản ghi có số điện thoại không hợp lệ hoặc kênh không được hỗ trợ sẽ bị bỏ qua (không được tạo), và mọi bản ghi bị bỏ qua sẽ được báo cáo kèm theo chỉ mục và lý do — để bạn có thể chỉ sửa các lỗi và thử lại.
Các số điện thoại đã tồn tại trong tài khoản của bạn sẽ bị bỏ qua dưới dạng duplicate theo mặc định — nhưng khi bạn gửi listId, liên hệ bạn đã có vẫn được thêm vào danh sách đó và được tính trong added_to_list, vì vậy việc nhập lại sẽ điền vào danh sách mà không thay đổi bất kỳ thông tin nào trên liên hệ. Hãy gửi updateExisting: true để cập nhật các liên hệ đó thay vì bỏ qua: các trường có trong bản ghi sẽ ghi đè lên thông tin của liên hệ (first_name, last_name, email, lead_profile và custom_fields được hợp nhất theo từng khóa), tags sẽ được thêm vào và liên hệ sẽ được thêm vào listId. Kênh, số điện thoại và cờ bot không bao giờ bị thay đổi trên một liên hệ hiện có.
Bạn có thể tùy chọn thêm mọi liên hệ đã nhập (hoặc cập nhật) vào một danh sách bằng listId, đặt defaultChannel cho các bản ghi không chỉ định, và gắn thẻ các bản ghi bằng tags (tên thẻ — các thẻ chưa tồn tại sẽ được tạo mới, các thẻ hiện có sẽ được khớp không phân biệt chữ hoa chữ thường).
Các trường cấp cao nhất
| Trường | Bắt buộc | Mô tả |
|---|---|---|
contacts |
Có | Mảng các bản ghi liên hệ (tối đa 500). |
listId |
Không | Danh sách để thêm mọi liên hệ trong yêu cầu này vào — bao gồm cả những liên hệ được tạo, cập nhật và những liên hệ bị bỏ qua do trùng lặp. Phải là một danh sách có sẵn trong tài khoản của bạn. |
defaultChannel |
Không | Kênh được áp dụng cho các bản ghi bỏ qua channel. Một trong các giá trị whatsapp, sms, whatsapp_web. Mặc định là whatsapp. |
updateExisting |
Không | true để cập nhật các liên hệ có số điện thoại đã tồn tại thay vì bỏ qua chúng dưới dạng duplicate. Mặc định là false. |
Các trường cho mỗi bản ghi
| Trường | Bắt buộc | Mô tả |
|---|---|---|
phone_number |
Có | Số điện thoại ở định dạng quốc tế (dấu + ở đầu sẽ được thêm vào nếu thiếu). |
first_name |
Không | Tên. |
last_name |
Không | Họ. |
email |
Không | Địa chỉ email. |
channel |
Không | Một trong các giá trị whatsapp, sms, whatsapp_web. Sẽ quay về defaultChannel nếu không được chỉ định. |
is_bot_active |
Không | Liệu trợ lý AI có trả lời hay không. Mặc định là true. |
is_private |
Không | Đánh dấu là riêng tư. Mặc định là false. |
lead_profile |
Không | Ghi chú về khách hàng tiềm năng dưới dạng văn bản tự do. |
custom_fields |
Không | Đối tượng chứa các khóa và giá trị của trường tùy chỉnh. |
tags |
Không | Mảng các tên thẻ (một chuỗi "a; b" đơn lẻ cũng hoạt động). Các thẻ chưa tồn tại sẽ được tạo mới; các thẻ hiện có sẽ được khớp không phân biệt chữ hoa chữ thường. Tối đa 25 thẻ mỗi bản ghi. |
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'])}")
Phản hồi
{
"success": true,
"imported": 2,
"contact_ids": ["contact_abc123", "contact_def456"],
"updated": 0,
"updated_contact_ids": [],
"added_to_list": 0,
"added_to_list_contact_ids": [],
"skipped": []
}
Nếu một số bản ghi không thể được tạo, chúng sẽ xuất hiện trong skipped kèm theo lý do (ở đây không có updateExisting, vì vậy số điện thoại hiện có sẽ bị bỏ qua):
{
"success": true,
"imported": 1,
"contact_ids": ["contact_abc123"],
"updated": 0,
"updated_contact_ids": [],
"added_to_list": 1,
"added_to_list_contact_ids": ["contact_def456"],
"skipped": [
{ "index": 1, "phone_number": "+12025551235", "reason": "duplicate" }
]
}
Hàng bị bỏ qua vẫn tham gia listId, đây là điều mà added_to_list đếm — không có thông tin nào khác trên liên hệ đó bị thay đổi. Với updateExisting: true, cùng một yêu cầu đó sẽ báo cáo liên hệ hiện có trong updated / updated_contact_ids thay vì bỏ qua.
Các lý do có thể bị bỏ qua: invalid_record, missing_phone_number, invalid_phone_number, invalid_channel, duplicate_in_request, duplicate, contact_limit_reached, create_failed.
Giới hạn gói. Nếu giới hạn liên hệ của gói dịch vụ không cho phép thêm số lượng liên hệ mới này, toàn bộ yêu cầu sẽ bị từ chối ngay từ đầu với mã
403. Nếu đạt đến giới hạn trong quá trình xử lý, các bản ghi còn lại sẽ được trả về dưới dạng bị bỏ qua với lý docontact_limit_reached.
Nhập danh bạ từ tệp CSV
Đối với các tệp nhập lớn hơn mức nhập hàng loạt hỗ trợ (lên đến khoảng 50.000 hàng), hãy xếp hàng một tác vụ nhập không đồng bộ đối với tệp CSV đã có sẵn trong bộ lưu trữ của tài khoản, sau đó thăm dò tác vụ đó cho đến khi hoàn tất.
Bắt đầu nhập
POST /contacts/import-csv
| Trường | Bắt buộc | Mô tả |
|---|---|---|
csvStoragePath |
Có | Đường dẫn lưu trữ của tệp CSV, nằm dưới users/{your account id}/imports/, kết thúc bằng .csv. |
listName |
Có | Tạo (hoặc sử dụng lại) một danh sách với tên này và thêm mọi liên hệ đã nhập vào đó. |
existingListRefs |
Không | Mảng các ID danh sách hiện có để thêm mọi liên hệ đã nhập vào đó. |
defaultChannel |
Không | Kênh được áp dụng cho các hàng không chỉ định kênh. |
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"]
Phản hồi (202 — tác vụ nhập đang được xếp hàng, chưa hoàn tất)
{
"success": true,
"job_id": "csvimp_abc123",
"status": "queued"
}
Đưa tệp vào bộ lưu trữ. Điểm cuối này bắt đầu và theo dõi tác vụ nhập; nó không tự chấp nhận tệp tải lên. Tệp CSV cần phải có sẵn tại
csvStoragePathtrước khi bạn gọi nó — trình nhập CSV của chính bảng điều khiển thực hiện việc này như bước đầu tiên.
Thăm dò tác vụ nhập
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"
Phản hồi
{
"success": true,
"job_id": "csvimp_abc123",
"status": "completed",
"imported": 812,
"updated": 0,
"skipped": 14,
"errors": [],
"error_message": null
}
status chuyển qua các trạng thái queued → processing → completed, hoặc failed với lý do trong error_message. Một jobId không tồn tại trong tài khoản của bạn sẽ trả về 404.
Xuất danh bạ
Khởi chạy một tác vụ xuất CSV không đồng bộ cho danh bạ của bạn và trả về một tác vụ để bạn thăm dò trạng thái hoàn thành.
Bắt đầu xuất dữ liệu
POST /contacts/export
| Trường | Bắt buộc | Mô tả |
|---|---|---|
listId |
Không | Chỉ xuất các liên hệ thuộc danh sách này. |
contactIds |
Không | Chỉ xuất các ID liên hệ cụ thể này. |
Nếu để trống cả hai, hệ thống sẽ xuất tất cả liên hệ trong tài khoản của bạn.
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"]
Phản hồi (202 — quá trình xuất đang chờ xử lý)
{
"success": true,
"job_id": "export_abc123",
"status": "queued"
}
Kiểm tra trạng thái công việc xuất dữ liệu
GET /contacts/export/{jobId}
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export/export_abc123?apiKey=YOUR_API_KEY"
Phản hồi
{
"success": true,
"job_id": "export_abc123",
"status": "completed",
"export_id": "exp_xyz789",
"contact_count": 812,
"error_message": null
}
Khi
statusở trạng thái"completed", bạn sẽ nhận đượcexport_idvàcontact_count. Việc tải xuống tệp CSV đã tạo được thực hiện từ trang Xuất dữ liệu trên bảng điều khiển của bạn.
Gửi tin nhắn cho một liên hệ
POST /contacts/{contactId}/send-message
Gửi tin nhắn đến một liên hệ hiện có trên bất kỳ kênh nào mà họ đang sử dụng. Tin nhắn sẽ được xếp hàng và gửi trong nền — phản hồi xác nhận rằng tin nhắn đã được chấp nhận, chứ không phải là đã được gửi đi.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
body |
Có | Nội dung văn bản của tin nhắn cần gửi. |
mediaUrl |
Không | URL của tệp phương tiện cần đính kèm. |
mediaContentType |
Không | Loại MIME của phương tiện đính kèm (ví dụ: 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"])
Phản hồi
{
"success": true,
"messageId": "aB3dE5fG7hI9jK1lM2nO",
"contactId": "contact_abc123",
"channel": "whatsapp",
"message": "Message created successfully. Delivery is being processed."
}
Không thể gửi ngay bây giờ? Nếu liên hệ đã bật chế độ không làm phiền hoặc chế độ riêng tư, hoặc không ở trên kênh có thể nhận tin nhắn gửi đi, yêu cầu sẽ bị từ chối kèm theo mã
422vàerrorgiải thích.
Để gửi bằng số điện thoại, ID Instagram hoặc định danh kênh khác thay vì ID liên hệ — và để biết thêm thông tin về việc nhắn tin nói chung — hãy xem Messages API.
Gửi tin nhắn tiếp theo bằng AI cho một liên hệ
POST /contacts/{contactId}/ai-follow-up
Yêu cầu một tác nhân AI viết một tin nhắn bằng giọng văn riêng của nó, dựa trên cuộc trò chuyện hiện tại và hướng dẫn bạn cung cấp, sau đó gửi tin nhắn đó trên kênh của liên hệ. Hành động này tương tự như bước tự động hóa Gửi tin nhắn tiếp theo bằng AI và tiêu tốn số tín dụng tương đương với một tin nhắn tiếp theo bằng AI.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
instruction |
Có | Nội dung tin nhắn cần thực hiện, bằng ngôn ngữ thông thường, tối đa 2.000 ký tự. Ví dụ: “Nhắc họ rằng liên kết đã đặt trước của họ sẽ hết hạn vào tối nay và hỏi xem họ có muốn chốt nó không”. |
agentId |
Không | Tác nhân viết tin nhắn. Để trống nếu muốn sử dụng tác nhân đang xử lý liên hệ đó. |
mustContain |
Không | Danh sách tối đa 5 cụm từ hoặc liên kết (mỗi mục tối đa 500 ký tự) mà tin nhắn phải bao gồm chính xác từng chữ. Nếu AI bỏ sót một mục, tin nhắn sẽ không được gửi và skipReason sẽ là text_check_failed. |
respectMessagingWindow |
Không | Mặc định là true. Trên WhatsApp Business API, Instagram và Messenger, hãy bỏ qua khi tin nhắn cuối cùng của liên hệ đã quá 24 giờ. |
skipWhenAiPaused |
Không | Mặc định là true. Bỏ qua khi AI bị tắt đối với liên hệ này. |
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/ai-follow-up" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"instruction": "Remind them their reserved link expires tonight and ask if they want to lock it in",
"mustContain": ["https://example.com/r/abc123"]
}'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/ai-follow-up", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
instruction: "Remind them their reserved link expires tonight and ask if they want to lock it in",
mustContain: ["https://example.com/r/abc123"],
}),
});
const data = await res.json();
if (!data.sent) console.log("Skipped:", data.skipReason);
Phản hồi khi tin nhắn đã được gửi:
{
"sent": true,
"messageId": "ai-follow-up-aB3dE5fG7hI9jK1l",
"text": "Hi Ada, quick reminder: your reserved spot is held until 20:00 tonight. Want to lock it in? https://example.com/r/abc123",
"agentId": "agent_abc123"
}
Phản hồi khi tin nhắn bị bỏ qua:
{
"sent": false,
"skipReason": "window_closed"
}
Cả hai đều trả về trạng thái 200. skipReason là một trong các giá trị no_agent (không có tác nhân nào xử lý liên hệ và không có tác nhân nào được chỉ định), dnd (không làm phiền), ai_paused, window_closed (ngoài cửa sổ 24 giờ hoặc liên hệ chưa bao giờ viết cho bạn trên kênh đó), no_credits, text_check_failed (thiếu mục mustContain), no_text (AI không viết được nội dung nào hữu ích) hoặc linkedin_gap (một khách hàng tiềm năng trên LinkedIn đã nhận được tin nhắn tự động cách đây chưa đầy 24 giờ; câu trả lời sau đó cũng mang theo nextAllowedAt, thời gian mà tin nhắn tiếp theo có thể được gửi đi). Việc bỏ qua là một câu trả lời bình thường, không phải lỗi, vì vậy hãy kiểm tra sent trước khi cho rằng tin nhắn đã được gửi đi. Một cuộc gọi bị bỏ qua sẽ không sử dụng tín dụng.
Phần thân bị thiếu instruction hoặc có trường sai loại sẽ nhận được 400. Một liên hệ hoặc tác nhân không có trong tài khoản của bạn sẽ nhận được 404. Các lỗi được trả về dưới dạng { "success": false, "error": "..." }. Khóa của thành viên trong nhóm cần có quyền chỉnh sửa liên hệ.
Gán một tác nhân AI cho một liên hệ
POST /contacts/{contactId}/assign-agent
Chuyển một cuộc hội thoại hiện có sang một AI agent khác, bắt đầu từ tin nhắn tiếp theo. Hành động này tương tự như Gán AI Agent trong menu của cuộc trò chuyện, và cũng là bước tương tự mà hành động Gán AI agent trong Tự động hóa (Automations) sử dụng.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
agentId |
Có | ID của tác nhân AI sẽ tiếp quản, hoặc null để xóa phân công để cuộc trò chuyện quay lại hộp thư đến của nhóm bạn. |
triggerAIResponse |
Không | true khiến tác nhân mới được chỉ định trả lời ngay các tin nhắn chưa được trả lời gần đây nhất của liên hệ. Mặc định là false. Khi liên hệ đã ở trên tác nhân này và tin nhắn cuối cùng của họ đã được trả lời, sẽ không có phản hồi nào được bắt đầu: phản hồi sẽ mang theo aiResponseTriggered: false và aiTriggerError giải thích lý do. |
Cẩn thận với
triggerAIResponse: true— nó gửi tin nhắn cho liên hệ ngay lập tức, vì vậy chỉ sử dụng khi bạn muốn họ nhận tin nhắn ngay bây giờ. Trên Messenger và Instagram, tin nhắn đó sẽ thất bại nếu liên hệ đã nhắn tin cho bạn cách đây hơn 24 giờ.
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"])
Phản hồi
{
"success": true,
"data": {
"contactId": "contact_abc123",
"agentId": "agent_xyz789",
"aiResponseTriggered": false
}
}
Tác nhân phải thuộc cùng một tài khoản với liên hệ; nếu không, yêu cầu sẽ bị từ chối với
404hoặc403. Tìm ID tác nhân trên trang Tác nhân AI (URL của mỗi tác nhân kết thúc bằng ID của nó).
Chỉ định AI agent cho nhiều liên hệ
POST /contacts/bulk-assign-agent
Di chuyển nhiều cuộc hội thoại sang một AI agent khác trong một lệnh gọi — hoặc xóa chỉ định cho tất cả chúng bằng null. Đây hoàn toàn là thay đổi về định tuyến: không có tin nhắn nào được gửi đi và agent không trả lời bất kỳ ai. Mỗi liên hệ sẽ đơn giản là nhận được agent mới vào lần tiếp theo họ nhắn tin. (Đó là lý do tại sao không có triggerAIResponse ở đây.)
| Trường | Bắt buộc | Mô tả |
|---|---|---|
agentId |
Có | AI agent sẽ tiếp quản, hoặc null để xóa chỉ định. |
contactIds |
Một trong ba | Tối đa 500 ID liên hệ để di chuyển. |
filter |
Một trong ba | Chọn các liên hệ trên máy chủ thay vì liệt kê chúng, ưu tiên liên hệ mới nhất. Sử dụng các khóa tương tự như bộ lọc của endpoint đếm: agentId (hoặc none), channel, tag, listId, botActive, status. |
rules |
Một trong ba | Một đối tượng quy tắc danh sách thông minh — xem Định dạng smart_rules. |
limit |
Không | Số lượng liên hệ cần di chuyển trong lệnh gọi này khi bạn chọn bằng filter hoặc rules. Từ 1 đến 500, mặc định là 500. |
Gửi chính xác một trong các tham số contactIds, filter hoặc rules.
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"])
Phản hồi
{
"success": true,
"agentId": "agent_xyz789",
"matched": 3415,
"updated": 500,
"skipped": 0,
"remaining": 2915,
"filters": { "agentId": "agent_abc123" }
}
matched là tổng số liên hệ mà lựa chọn tìm thấy, updated là số lượng đã được di chuyển bởi lệnh gọi này, skipped là số lượng ID bạn gửi không tìm thấy trong tài khoản của bạn, và remaining là số lượng vẫn còn khớp sau khi lệnh gọi này hoàn tất.
Di chuyển tất cả mọi người. Vì một lệnh gọi chỉ di chuyển tối đa 500 liên hệ, một nhóm lớn sẽ cần vài lệnh gọi. Hãy sử dụng một bộ lọc ngừng khớp với liên hệ sau khi nó đã được di chuyển — ví dụ filter: { "agentId": "agent_abc123" } trong khi chỉ định cho agent_xyz789 — và lặp lại chính xác lệnh gọi đó cho đến khi remaining trả về là 0. Khi bạn truyền contactIds thay thế, remaining luôn là 0.
Chỉ định liên hệ cho một phòng ban
POST /contacts/{contactId}/department
“Chỉ định khách hàng tiềm năng này cho bộ phận Kinh doanh” — lưu trữ liên hệ dưới một phòng ban được đặt tên và theo mặc định, sẽ chuyển liên hệ đó cho người nào trong phòng ban hiện đang có ít liên hệ nhất. Việc này tách biệt với chỉ định một tác nhân AI: phòng ban trả lời cho câu hỏi “nhóm nào sở hữu liên hệ này,” tác nhân trả lời cho câu hỏi “AI nào xử lý việc này,” và việc thiết lập một cái sẽ không bao giờ xóa cái kia.
| Trường | Bắt buộc | Mô tả |
|---|---|---|
department_id |
Có | Phòng ban để lưu trữ liên hệ. Truyền null để xóa thông tin này. |
hand_to_member |
Không | Đồng thời chuyển liên hệ cho người có ít việc nhất trong phòng ban đó. Mặc định là true. Không bao giờ gán lại liên hệ mà ai đó đã sở hữu. |
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"])
Phản hồi
{
"success": true,
"department_id": "dept_sales",
"assigned_to": "member_uid_123"
}
assigned_to là null khi liên hệ đã được sở hữu bởi một người nào đó, hoặc bạn đã truyền hand_to_member: false.
Liên kết liên hệ trên các kênh
“Tiếp tục trên WhatsApp” (hoặc SMS) sẽ tìm hoặc tạo liên hệ của người này trên một kênh dựa trên số điện thoại khác và liên kết hai kênh lại với nhau, để phần còn lại của ứng dụng nhận diện họ là cùng một người.
Liên kết tới một kênh khác
POST /contacts/{contactId}/link-channel
| Trường | Bắt buộc | Mô tả |
|---|---|---|
channel |
Có | Kênh cần liên kết tới. Một trong các giá trị whatsapp, whatsapp_web, sms. |
phoneNumber |
Không | Số điện thoại sẽ sử dụng trên kênh mới. Mặc định là số điện thoại của chính liên hệ nguồn. |
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" }'
Phản hồi
{
"success": true,
"data": {
"contact_id": "contact_def456",
"person_id": "person_xyz789",
"created": true
}
}
created cho bạn biết liệu một liên hệ mới đã được tạo cho kênh đích hay một liên hệ hiện có đã được tìm thấy và liên kết. Việc gọi hàm này lần thứ hai là an toàn — nó sẽ trả về cùng một contact_id với created: false thay vì tạo ra bản sao trùng lặp.
Một 422 có nghĩa là tài khoản không thể thực hiện liên kết này ngay bây giờ: liên hệ đã nằm trong nhóm kênh đó, không có số điện thoại để sử dụng hoặc không có người gửi được kết nối cho kênh đích. Một 409 có nghĩa là hai liên hệ đã được liên kết với hai người khác nhau — hãy hủy liên kết một trong hai trước.
Liệt kê các cuộc hội thoại được liên kết của một liên hệ
GET /contacts/{contactId}/linked
Trả về các cuộc hội thoại khác cùng là một người với liên hệ này. Một liên hệ chưa được liên kết sẽ trả về một mảng trống, không phải là 404 — “người này không có kênh nào khác” là một trạng thái bình thường.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/linked?apiKey=YOUR_API_KEY"
Phản hồi
{
"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"
}
}
]
}
Hủy liên kết một liên hệ
DELETE /contacts/{contactId}/link
Loại bỏ liên hệ này khỏi người của nó, theo một chiều — bất kỳ liên hệ nào khác vẫn được liên kết với người đó sẽ giữ nguyên liên kết của chúng, vì vậy việc hủy liên kết một trong ba liên hệ sẽ không làm tan rã nhóm.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link?apiKey=YOUR_API_KEY"
Phản hồi
{ "success": true }
Lấy ảnh đại diện của liên hệ
POST /contacts/{contactId}/profile-pic
Lấy (và lưu vào bộ nhớ đệm) ảnh hồ sơ WhatsApp hoặc Meta của liên hệ theo yêu cầu — cùng một ảnh được trả về dưới dạng avatarUrl trong Lấy thông tin liên hệ, đã được làm mới.
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/profile-pic?apiKey=YOUR_API_KEY"
Phản hồi
{
"success": true,
"avatar_url": "https://example.com/photo.jpg",
"cached": false
}
cached: true có nghĩa là URL đến từ một lần lấy dữ liệu gần đây thay vì tra cứu mới từ nhà cung cấp — ảnh được lưu vào bộ nhớ đệm trong 7 ngày, và một liên hệ mà nhà cung cấp báo cáo là không có ảnh khả dụng sẽ được lưu vào bộ nhớ đệm là không khả dụng trong 24 giờ. Khi không có ảnh để lấy, avatar_url sẽ bị lược bỏ và message sẽ giải thích lý do.
Tự động gắn thẻ liên hệ bằng AI
Chạy các quy tắc gắn thẻ của tài khoản bạn trên toàn bộ lịch sử hội thoại của một hoặc nhiều liên hệ và áp dụng (hoặc xóa) thẻ chính xác như cách gắn thẻ thời gian thực diễn ra trong cuộc trò chuyện trực tiếp — cùng quy tắc, cùng chi phí tín dụng cho mỗi thẻ.
Bắt đầu một lượt chạy
POST /contacts/auto-tag
| Trường | Bắt buộc | Mô tả |
|---|---|---|
scope |
Có | "contacts" để gắn thẻ các liên hệ cụ thể, hoặc "agent" để gắn thẻ mọi cuộc hội thoại hiện đang được xử lý bởi một tác nhân AI. |
contact_ids |
Bắt buộc khi scope là "contacts" |
Mảng các ID liên hệ, từ 1 đến 500. |
agent_id |
Bắt buộc khi scope là "agent" |
Tác nhân AI có các cuộc hội thoại cần gắn thẻ. Khi scope là "contacts", trường này là tùy chọn và chỉ thu hẹp phạm vi các quy tắc gắn thẻ của tác nhân được chạy. |
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"] }'
Một liên hệ duy nhất sẽ chạy nội tuyến và trả về kết quả ngay lập tức:
{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }
Hai liên hệ trở lên (hoặc scope: "agent") sẽ chạy dưới dạng tác vụ nền và trả về 202 ngay lập tức:
{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }
Kiểm tra trạng thái lượt chạy
GET /contacts/auto-tag/run
Trả về lượt chạy hiện tại (hoặc gần đây nhất) của tài khoản, để bạn có thể kiểm tra tiến độ mà không cần tự theo dõi run_id.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag/run?apiKey=YOUR_API_KEY"
Phản hồi
{
"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
}
}
run là null khi tài khoản chưa từng bắt đầu lượt chạy nào. status chuyển từ "running" sang "completed" hoặc "failed".
Mỗi tài khoản chỉ có thể thực hiện một lượt chạy hàng loạt tại một thời điểm — bắt đầu lượt chạy thứ hai khi lượt khác đang chạy sẽ trả về 409 cùng với error_code: "auto_tag_run_in_progress". Hết tín dụng khi chạy cho một liên hệ duy nhất sẽ trả về 402 cùng với error_code: "insufficient_credits"; lượt chạy hàng loạt thay vào đó sẽ tự dừng sớm và báo cáo tiến độ đã đạt được trong run.
Xóa liên hệ
DELETE /contacts/{contactId}
Xóa vĩnh viễn một liên hệ theo ID, cùng với lịch sử tin nhắn của liên hệ đó. Hành động này không thể hoàn tác. Để xóa nhiều liên hệ trong một lệnh gọi, hãy sử dụng Xóa liên hệ bên dưới.
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"])
Phản hồi
{
"success": true
}
Một ID liên hệ không tồn tại trong tài khoản của bạn, hoặc thuộc về một tài khoản khác, sẽ trả về 404.
Xóa liên hệ
DELETE /contacts
Xóa vĩnh viễn một hoặc nhiều liên hệ theo ID trong một lần gọi (tối đa 500 ID). Các ID không tồn tại trong tài khoản của bạn sẽ bị bỏ qua và được tính vào skipped. Hành động này không thể hoàn tác.
| Trường | Mô tả |
|---|---|
contactIds |
Mảng các ID liên hệ cần xóa (tối đa 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']}")
Phản hồi
{
"success": true,
"deleted": 2,
"skipped": 0
}
Liệt kê các trường tùy chỉnh
GET /users/me/custom-fields — trả về các khóa trường tùy chỉnh đã đăng ký trên tài khoản của bạn (các khóa được hiển thị dưới dạng cột và trong biểu mẫu liên hệ), để một tích hợp có thể cung cấp chúng dưới dạng bộ chọn thay vì phải đoán.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/users/me/custom-fields?apiKey=YOUR_API_KEY"
Phản hồi (200)
{ "success": true, "custom_fields": ["tier", "company", "birthday"] }
Thiết lập danh sách với PUT /users/me/custom-fields và cùng một cấu trúc mảng.
Xóa một trường tùy chỉnh
DELETE /contacts/custom-fields/{fieldKey}
Xóa một khóa trường tùy chỉnh khỏi mọi liên hệ trong tài khoản của bạn. Sử dụng tính năng này để dọn dẹp sau khi đổi tên hoặc ngừng sử dụng một trường tùy chỉnh. Khóa chỉ có thể chứa các chữ cái, số, dấu gạch dưới và dấu gạch nối. Trả về số lượng liên hệ đã được cập nhật. Thao tác này không thể hoàn tác.
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")
Phản hồi
{
"success": true,
"updated": 42
}
Lưu ý: Một khóa trường có các ký tự không được hỗ trợ sẽ trả về 400.
Các loại trường tùy chỉnh
Mỗi trường tùy chỉnh trên một tài khoản đều có một kiểu: text (mặc định), number, date, select (danh sách thả xuống với các tùy chọn cố định) hoặc boolean (hộp kiểm). Một trường có kiểu dữ liệu sẽ được xác thực mỗi khi ghi — tạo, cập nhật, nhập, công cụ tự động hóa và quá trình thu thập trường của chính AI — và giá trị của nó được lưu trữ theo một định dạng chuẩn, vì vậy các bộ lọc và điều kiện tự động hóa sẽ so sánh các giá trị tương đồng với nhau:
| Kiểu | Được lưu trữ dưới dạng | Chấp nhận đầu vào |
|---|---|---|
text |
Bất cứ thứ gì bạn gửi | Bất cứ thứ gì (hành vi không thay đổi) |
number |
Một số JSON | 42, "42", "19,99" |
date |
"YYYY-MM-DD" |
2026-02-01, một ngày-giờ ISO (phần ngày được giữ lại), 01/02/2026 (ngày trước hoặc tháng trước tùy theo định dạng ngày của tài khoản; một giá trị không gây nhầm lẫn như 13/02/2026 luôn được ưu tiên), February 1, 2026, 1 de febrero de 2026 |
select |
Một trong các tùy chọn của trường, theo cách viết của chính tùy chọn đó | Bất kỳ kết quả khớp nào không phân biệt chữ hoa chữ thường của một tùy chọn |
boolean |
true / false |
true/false, yes/no, 1/0, si/no, ja/nein … |
Gửi null hoặc một chuỗi trống sẽ xóa một trường có kiểu dữ liệu. Các khóa không được đăng ký trên tài khoản và các trường text sẽ được lưu trữ chính xác như khi gửi.
Đọc định nghĩa trường
GET /users/me/custom-fields
{
"success": true,
"custom_fields": ["company", "birthday", "plan", "vip"],
"definitions": [
{ "key": "company", "type": "text" },
{ "key": "birthday", "type": "date" },
{ "key": "plan", "type": "select", "options": ["Free", "Pro", "Enterprise"] },
{ "key": "vip", "type": "boolean" }
]
}
custom_fields là danh sách thuần túy các khóa (không thay đổi đối với các máy khách cũ); definitions chứa kiểu dữ liệu cho mỗi khóa.
Thiết lập định nghĩa trường
PUT /users/me/custom-fields
Thay thế toàn bộ danh sách. Mỗi mục nhập là một khóa đơn thuần (giữ nguyên kiểu dữ liệu mà trường đó đã có, text cho một trường mới) hoặc một đối tượng với key, type và, đối với select, options (1 đến 100 tùy chọn duy nhất, mỗi tùy chọn tối đa 64 ký tự). Tối đa 50 trường; các khóa sử dụng chữ cái thường, chữ số và dấu gạch dưới và bắt đầu bằng một chữ cái hoặc dấu gạch dưới.
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/users/me/custom-fields?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customFields": [
"company",
{ "key": "birthday", "type": "date" },
{ "key": "plan", "type": "select", "options": ["Free", "Pro", "Enterprise"] },
{ "key": "vip", "type": "boolean" }
]
}'
Việc thay đổi kiểu dữ liệu của một trường không ghi đè các giá trị đã lưu trữ trên các liên hệ; chúng sẽ được xác thực vào lần tiếp theo khi được ghi.
Lỗi xác thực
Một yêu cầu tạo hoặc cập nhật liên hệ có các giá trị trường tùy chỉnh không khớp với kiểu dữ liệu của chúng sẽ bị từ chối hoàn toàn với mã 400:
{
"success": false,
"error": "Invalid custom field value(s): birthday: \"birthday\" must be a date in YYYY-MM-DD format (for example 1990-02-01).",
"field_errors": [
{ "key": "birthday", "message": "\"birthday\" must be a date in YYYY-MM-DD format (for example 1990-02-01)." }
]
}
Khi nhập hàng loạt, bản ghi có giá trị không hợp lệ sẽ được báo cáo là thất bại với cùng một thông báo và phần còn lại của lô sẽ được xử lý.
Danh sách
Danh sách dùng để nhóm các liên hệ. Một danh sách có thể là tĩnh (bạn tự quyết định ai nằm trong đó) hoặc thông minh (thành viên được tính toán dựa trên các quy tắc và được cập nhật tự động — xem Tổ chức Danh sách & Liên hệ).
| Trường | Mô tả |
|---|---|
name |
Bắt buộc khi tạo. Tối đa 100 ký tự. |
status |
live (mặc định) hoặc draft. Chữ thường. |
contact_ids |
Mảng các ID liên hệ để đưa vào danh sách. Chỉ dành cho danh sách tĩnh. |
type |
static (mặc định) hoặc smart. |
smart_rules |
Bộ quy tắc — bắt buộc khi type là smart. Xem bên dưới. |
Tạo danh sách
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" } }
]
}
}'
Phản hồi
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 3, "removed": 0, "total": 3 }
}
Một danh sách thông minh được đánh giá trực tiếp (inline), trong cùng một yêu cầu, vì vậy evaluation cho bạn biết chính xác những ai đã được thêm vào danh sách đó. Đối với danh sách tĩnh, evaluation là null.
Cập nhật danh sách
PUT /lists/{listId}
Chỉ gửi các trường bạn muốn thay đổi. Việc thay đổi smart_rules sẽ đánh giá lại danh sách ngay lập tức và trả về cùng một đối tượng 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"] } ] } }'
Bạn có thể chuyển đổi danh sách giữa hai loại:
- Tĩnh → thông minh: gửi
{ "type": "smart", "smart_rules": { … } }. Các quy tắc sẽ được áp dụng ngay lập tức. - Thông minh → tĩnh: gửi
{ "type": "static" }. Các quy tắc sẽ bị loại bỏ và những người hiện có trong danh sách sẽ được giữ lại.
Cấu trúc 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" }
]
}
match—all(tất cả các điều kiện phải đúng) hoặcany(ít nhất một điều kiện đúng).conditions— 1 đến 20 điều kiện, mỗi điều kiện tối đa 100 giá trị, chuỗi tối đa 200 ký tự.
field |
op |
value |
|---|---|---|
tags |
has_any, has_all, has_none |
mảng các ID thẻ |
lists |
in_any, not_in_any |
mảng các ID danh sách (chỉ dành cho danh sách tĩnh — danh sách thông minh không thể được tạo từ một danh sách thông minh khác) |
channel |
is_any, is_none |
mảng các kênh |
status |
is_any, is_none |
mảng các trạng thái liên hệ |
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" } |
| các trường ngày tương tự | before, after |
ngày ISO ("2026-01-01", được so sánh theo ngày trọn vẹn) hoặc ngày-giờ ISO đầy đủ ("2026-01-01T14:30:00Z", được so sánh đến thời điểm chính xác) |
| các trường ngày tương tự | is_set, not_set |
— |
has_interacted_with_ai |
is |
true / false — true khớp với các liên hệ mà AI đã nhắn tin ít nhất một lần (từ trước đến nay) |
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 |
chuỗi cho các biểu mẫu contains |
current_campaign_id, assigned_agent |
is_any, is_none, is_set, not_set |
mảng các ID cho các biểu mẫu is_any / is_none |
custom_field (cộng với key) |
eq, neq, contains, not_contains, is_set, not_set |
chuỗi cho các biểu mẫu giá trị |
not_within_last cũng khớp với các liên hệ chưa từng được thiết lập ngày (“hơn N trước đây, hoặc chưa bao giờ”), và các so sánh văn bản sẽ bỏ qua phân biệt chữ hoa/thường.
Tương tác AI. has_interacted_with_ai là cờ trọn đời: true cho mọi liên hệ mà AI của bạn đã gửi ít nhất một tin nhắn, false cho tất cả những người khác (bao gồm cả các liên hệ mà chỉ nhóm của bạn từng phản hồi). Nó được đóng dấu vào tin nhắn đầu tiên của AI gửi cho một liên hệ và không bao giờ bị xóa, vì vậy việc tắt tính năng trả lời của AI cho liên hệ đó hoặc chuyển họ sang chiến dịch khác sẽ không đặt lại nó. Đối với một khoảng thời gian — “các liên hệ mà AI của tôi đã xử lý trong tháng này”, câu hỏi thanh toán thông thường — hãy sử dụng phạm vi qua last_ai_interaction_at thay thế:
{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }
Đừng nhầm lẫn cả hai với is_bot_active (AI được phép trả lời, không phải là nó đã trả lời) hoặc has_ever_responded (liên hệ đã viết lại, cho bất kỳ ai). Hai dấu tương tự được trả về trên mỗi liên hệ dưới dạng first_ai_interaction_at / last_ai_interaction_at, và toàn bộ tập hợp quy tắc cũng hoạt động trên GET /contacts?rules=, vì vậy bạn có thể đếm các kết quả khớp mà không cần tạo danh sách.
Xem trước một bộ quy tắc
POST /lists/preview
Đếm và lấy mẫu các liên hệ mà một bộ quy tắc sẽ khớp, mà không tạo hoặc thay đổi bất kỳ điều gì. Hãy sử dụng tính năng này để kiểm tra tính hợp lệ của các quy tắc trước khi bạn lưu chúng.
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"] } ] } }'
Phản hồi
{
"success": true,
"count": 3,
"sample": [
{
"id": "contact_abc123",
"first_name": "Sofia",
"last_name": "Martinez",
"phone_number": "+31600000000",
"email": "sofia@example.com",
"channel": "whatsapp"
}
]
}
sample chứa tối đa 10 liên hệ, ưu tiên các liên hệ hoạt động gần đây nhất.
Chạy lại danh sách thông minh ngay bây giờ
POST /lists/{listId}/evaluate
Buộc đánh giá lại ngay lập tức (tương tự như hành động Làm mới ngay trong bảng điều khiển). Các danh sách thông minh đã tự động cập nhật khi một liên hệ thay đổi và cứ sau 15 phút đối với các quy tắc dựa trên thời gian, vì vậy hành động này chỉ cần thiết khi bạn muốn có kết quả ngay lập tức.
Phản hồi
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 2, "removed": 1, "total": 4 }
}
evaluation.skipped: true có nghĩa là một quá trình đánh giá khác của cùng danh sách đó đang chạy và lệnh gọi này không thực hiện bất kỳ thay đổi nào.
Danh sách thông minh từ chối các thành viên được chọn thủ công
Các điểm cuối thành viên trả về 409 với "This is a smart list — its members are computed from its rules. Edit the rules instead." khi danh sách mục tiêu là danh sách thông minh. Điều này bao gồm POST /contacts/lists, DELETE /contacts/lists, POST /contacts/lists/batch, contact_ids trên POST /lists và PUT /lists/{listId}, cũng như việc chọn một danh sách thông minh làm đích nhập CSV. Hãy thay đổi các quy tắc thay vì làm vậy.
Việc gọi POST /lists/{listId}/evaluate trên một danh sách tĩnh cũng là một 409 — vì danh sách đó không có quy tắc nào để chạy.
Các lỗi API liên hệ
Các điểm cuối (endpoint) liên hệ trả về phong bì lỗi tiêu chuẩn:
{
"success": false,
"error": "Contact not found"
}
Một số endpoint cũng bao gồm error_code, thường khớp với trạng thái HTTP — ngoại lệ duy nhất là trường hợp liên hệ trùng lặp bên dưới, nơi trạng thái HTTP là 200 và chỉ có error_code mang giá trị 409. Các mã cụ thể cho các endpoint liên hệ:
| Mã | Khi nào nó xảy ra trên một endpoint liên hệ |
|---|---|
400 |
Yêu cầu không hợp lệ — thiếu/sai trường, nội dung trống, con trỏ (cursor) không hợp lệ, hoặc vượt quá 500 ID trong một lô. |
402 |
Không đủ tín dụng để hoàn tất quá trình gắn thẻ AI cho một liên hệ (error_code: "insufficient_credits"). |
404 |
Liên hệ, danh sách hoặc thẻ không được tìm thấy trong tài khoản của bạn. |
409 |
Một liên hệ với số điện thoại đó đã tồn tại (khi tạo mới). Được trả về dưới dạng error_code trong phần nội dung với trạng thái HTTP là 200, vì vậy hãy phân nhánh dựa trên error_code tại đây. Cũng được trả về khi quá trình tự động gắn thẻ hàng loạt đang diễn ra (error_code: "auto_tag_run_in_progress"), hoặc khi việc liên kết một liên hệ với một kênh khác sẽ hợp nhất hai liên hệ vốn đã được liên kết với hai người khác nhau. |
422 |
Liên hệ hiện không thể nhận tin nhắn (do chế độ không làm phiền, riêng tư hoặc kênh không được hỗ trợ). Trên endpoint liên kết kênh, lỗi này cũng bao gồm trường hợp không có số điện thoại, ghép nối kênh không được hỗ trợ, hoặc không có người gửi được kết nối cho kênh mục tiêu. |
Mã 403 trên một endpoint liên hệ cũng có thể có nghĩa là vấn đề về giới hạn liên hệ hoặc quyền danh sách thay vì quyền truy cập gói. Các mã dùng chung mà mọi endpoint có thể trả về — 401, 403 (gói của bạn không bao gồm quyền truy cập API), 429 (giới hạn tốc độ) và 500 — được liệt kê cùng với hướng dẫn thử lại trong phần Lỗi & Phân trang.
Các bước tiếp theo
- API Tin nhắn — gửi tin nhắn theo danh tính kênh và quản lý các cuộc hội thoại.
- Tham chiếu API — danh sách đầy đủ các điểm cuối, bao gồm thẻ và danh sách.
- Truy cập API — xác thực, giới hạn tốc độ và xử lý lỗi.