Your AI Connector Docs

Tin nhắn & Cuộc hội thoại

Messages API cho phép bạn gửi tin nhắn cho bất kỳ liên hệ nào, đọc lại cuộc trò chuyện, chỉnh sửa hoặc xóa tin nhắn đã gửi, phản hồi tin nhắn, lấy toàn bộ chuỗi hội thoại, xuất bản ghi và đánh dấu tin nhắn là đã đọc hoặc chưa đọc — tất cả đều không cần mở hộp thư đế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. Mọi yêu cầu đều cần khóa API của bạn — xem Xác thực để biết danh sách đầy đủ các cách gửi khóa. Các ví dụ bên dưới sử dụng tiêu đề X-API-Key, với một ví dụ cURL cũng hiển thị biểu mẫu truy vấn ?apiKey=.

Cách thức gửi hoạt động: Việc gửi tin nhắn không chờ đợi tin nhắn đến nơi. API chấp nhận tin nhắn của bạn, trả về ngay lập tức với ID tin nhắn, sau đó gửi tin nhắn đó trong nền trên kênh của liên hệ (WhatsApp, SMS, Instagram, v.v.). Để theo dõi xem tin nhắn đã thực sự được gửi hoặc đọc hay chưa, hãy lắng nghe các cập nhật trạng thái bằng Webhooks — đừng thực hiện thăm dò (poll). Phản hồi gửi chỉ xác nhận rằng tin nhắn đã được chấp nhận.


Gửi tin nhắn

Có hai cách để gửi. Hãy chọn cách phù hợp với cách bạn đã xác định liên hệ:

  • Gửi theo ID liên hệ — bạn đã biết ID của liên hệ (ví dụ: bạn đã tạo liên hệ thông qua API hoặc lấy từ webhook). Sử dụng POST /contacts/{contactId}/send-message.
  • Gửi theo định danh liên hệ — bạn biết số điện thoại, ID Instagram, v.v. của liên hệ, nhưng không biết ID nội bộ của họ. Sử dụng POST /contacts/send và để nền tảng tìm liên hệ phù hợp.

Cả hai đều xếp hàng tin nhắn theo cùng một cách và gửi tin nhắn đó trên bất kỳ kênh nào mà liên hệ đang sử dụng. Bạn không cần chọn phương thức vận chuyển — nền tảng sẽ định tuyến các liên hệ WhatsApp qua WhatsApp, liên hệ SMS qua SMS, v.v.

Cả hai cũng chỉ tìm thấy các liên hệ đã tồn tại. Không lệnh gọi nào tạo ra liên hệ mới: nếu ID hoặc danh tính không khớp, kết quả trả về sẽ là 404, nó không trở thành một liên hệ mới. Vì vậy, nếu bạn đang nhắn tin cho ai đó lần đầu tiên, hãy tạo liên hệ trước bằng POST /contacts, hoặc trên WhatsApp Web, hãy sử dụng Gửi trực tiếp đến một số điện thoại WhatsApp Web bên dưới, lệnh này sẽ tạo liên hệ ngay trong cùng một lệnh gọi.

Gửi theo ID liên hệ

POST /contacts/{contactId}/send-message

Trường Bắt buộc Mô tả
body Có Nội dung tin nhắn cần gửi, tối đa 65.536 ký tự. Nội dung dài hơn mức cho phép của kênh trong một tin nhắn (1.500 trên WhatsApp Business API và SMS, 1.000 trên Instagram, 2.000 trên Messenger, 4.096 trên Telegram và LinkedIn, 5.000 trên LINE, 6.000 trên TikTok, 7.000 trên Viber, 65.536 trên WhatsApp Web; không giới hạn trên email, tiện ích trò chuyện và các kênh tùy chỉnh) sẽ được gửi thành nhiều tin nhắn theo thứ tự, được ngắt tại các đoạn văn hoặc câu. Phản hồi sau đó sẽ chứa messageIds cho mỗi phần và autoSplit: true.
mediaUrl Không URL của tệp phương tiện (hình ảnh, âm thanh, video, tài liệu) cần đính kèm.
mediaContentType Không Loại MIME của phương tiện đính kèm, ví dụ: image/jpeg. Được xác định từ phần mở rộng tệp của URL khi bị bỏ qua (.mp3 → audio/mpeg, .pdf → application/pdf); hãy đặt giá trị này cho URL không có phần mở rộng.
sendAsVoiceNote Không Chỉ dành cho WhatsApp Web, chỉ âm thanh: gửi âm thanh dưới dạng tin nhắn thoại (bong bóng phát). Âm thanh không phải định dạng OGG/Opus sẽ được chuyển đổi tại thời điểm gửi. Mặc định là false.
pauseBot Không true tạm dừng AI cho liên hệ này khi tin nhắn được gửi — dành cho trường hợp con người tiếp quản. Xem Tạm dừng hoặc tiếp tục AI.
clearIncompleteReply Không true hủy bỏ phản hồi bot đang viết dở để nó không tiếp tục sau tin nhắn của bạn.
human_reply Không true đánh dấu tin nhắn là do một người trong nhóm của bạn viết thay vì do tích hợp. AI sau đó sẽ coi đó là phản hồi của đồng nghiệp trong cuộc trò chuyện, và phản hồi mà AI đã xếp hàng cho tin nhắn cuối cùng của liên hệ sẽ bị hủy để liên hệ không nhận được hai câu trả lời. Nó không tạm dừng AI; hãy sử dụng pauseBot cho việc đó. Mặc định là false.

Trên LinkedIn, tin nhắn bạn gửi theo cách này, hoặc từ hộp thư đến, sẽ được gửi đi ngay cả khi một người đang xử lý chuỗi hội thoại đó trên LinkedIn. Các phản hồi của AI và các tin nhắn tiếp theo của nó sẽ bị giữ lại trong chuỗi hội thoại như vậy. Một phản hồi bị giữ lại sẽ bị xóa khỏi cuộc trò chuyện thay vì hiển thị là thất bại, vì không có gì được gửi đi và không có tín dụng nào bị trừ. Phản hồi cuối cùng của AI trước khi nó chuyển chuỗi hội thoại cho một người vẫn sẽ được gửi đi.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi! Your appointment is confirmed for tomorrow at 10:00."
  }'

JavaScript

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

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."},
)
print(res.json()["messageId"])

Phản hồi (200 OK):

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

Gửi theo định danh liên hệ

POST /contacts/send

Sử dụng cách này khi bạn không có ID nội bộ của liên hệ. Cung cấp body tin nhắn cộng với hoặc là contact_id, hoặc là channel cùng với trường định danh khớp với kênh đó.

Trường Bắt buộc Mô tả
body Có Nội dung tin nhắn cần gửi, tối đa 65.536 ký tự. Nếu nội dung dài hơn giới hạn của kênh trong một tin nhắn (1.500 trên WhatsApp Business API và SMS, 1.000 trên Instagram, 2.000 trên Messenger, 4.096 trên Telegram và LinkedIn, 5.000 trên LINE, 6.000 trên TikTok, 7.000 trên Viber, 65.536 trên WhatsApp Web; không giới hạn trên email, tiện ích trò chuyện và các kênh tùy chỉnh), tin nhắn sẽ được gửi thành nhiều phần theo thứ tự, được ngắt tại các dấu ngắt đoạn hoặc câu. Phản hồi sau đó sẽ chứa messageIds cho mỗi phần và autoSplit: true.
contact_id Không ID của một liên hệ hiện có. Khi được đặt, các trường định danh bên dưới là không cần thiết.
channel Không Kênh để gửi tin nhắn. Bắt buộc khi contact_id không được cung cấp. Một trong 14 kênh có thể gửi đi: whatsapp, whatsapp_web, sms, instagram, instagram_private, messenger, telegram, chat-widget, custom, email, line, imessage, linkedin, viber.
phone_number Không Số điện thoại của liên hệ theo định dạng quốc tế. Được sử dụng với whatsapp, whatsapp_web, và sms.
instagram_id Không ID người dùng Instagram của liên hệ. Được sử dụng với instagram.
messenger_id Không ID người dùng Messenger của liên hệ. Được sử dụng với messenger.
telegram_user_id Không ID người dùng Telegram của liên hệ. Được sử dụng với telegram.
media_url Không URL của tệp phương tiện cần đính kèm.
media_content_type Không Loại MIME của phương tiện đính kèm, ví dụ: image/jpeg.

Các kênh có thể được phân giải theo định danh. Chỉ sáu trong số 14 kênh chấp nhận trường định danh thay vì contact_id: whatsapp, whatsapp_web và sms được tra cứu theo phone_number, instagram theo instagram_id, messenger theo messenger_id, và telegram theo telegram_user_id. Tám kênh còn lại — instagram_private, chat-widget, custom, email, line, imessage, linkedin và viber — không có định danh công khai để tra cứu, vì vậy việc gửi trên các kênh đó yêu cầu contact_id; chỉ truyền channel sẽ trả về 400 thông báo cho bạn biết rằng contact_id là bắt buộc.

cURL (sử dụng biểu mẫu truy vấn ?apiKey=)

curl -X POST "https://api.youraiconnector.com/v1/contacts/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "phone_number": "+31612345678",
    "body": "Hi! Your appointment is confirmed."
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/contacts/send", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    channel: "whatsapp",
    phone_number: "+31612345678",
    body: "Hi! Your appointment is confirmed.",
  }),
});
const data = await res.json();
console.log(data.message_id, data.channel);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/send",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "channel": "whatsapp",
        "phone_number": "+31612345678",
        "body": "Hi! Your appointment is confirmed.",
    },
)
data = res.json()
print(data["message_id"], data["channel"])

Phản hồi (201 Created):

{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp"
}

Lý do tin nhắn có thể bị từ chối: Một liên hệ đang bật chế độ không làm phiền hoặc chế độ riêng tư không thể nhận tin nhắn gửi đi — yêu cầu sẽ thất bại với mã 422. Nếu không có liên hệ nào khớp với ID hoặc định danh bạn đã cung cấp, bạn sẽ nhận được mã 404.

Gửi tin nhắn trên WhatsApp Web: các biến thể và bảo vệ chống gửi hàng loạt

Hai điều sau đây áp dụng cho body khi liên hệ đang sử dụng WhatsApp Web.

Các dấu ngoặc Spintax được mở rộng cho mỗi lần gửi. Một body dạng {Hi|Hello|Hey} there, quick question sẽ được gửi đi dưới dạng một trong ba lời chào, được chọn cho lần gửi đó — các dấu ngoặc sẽ không bao giờ hiển thị với người nhận. Hãy sử dụng tính năng này để gửi cho mỗi liên hệ một lời chào khác nhau từ cùng một mã tích hợp. Văn bản không có dấu ngoặc sẽ được gửi chính xác như những gì đã viết.

Các tin nhắn mở đầu giống hệt nhau gửi đi hàng loạt sẽ bị từ chối. Nếu mười tin nhắn mở đầu gần như giống hệt nhau được gửi đi từ một số WhatsApp Web trong vòng một giờ tới những liên hệ chưa từng nhắn tin cho bạn, các tin nhắn tiếp theo sẽ không được gửi: lệnh gửi vẫn được chấp nhận như bình thường (bạn vẫn nhận được messageId), nhưng tin nhắn sau đó sẽ ở trạng thái status: "failed" và error_code: "opener_burst", kèm theo lý do mà khách hàng có thể đọc được. Việc thử lại cùng một nội dung văn bản sẽ không có tác dụng — hãy thay đổi nội dung, đợi một giờ và gửi lại. Các tin nhắn trả lời trong các cuộc hội thoại hiện có sẽ không bao giờ bị ảnh hưởng. Lý do chi tiết nằm trong mục Các tin nhắn mở đầu giống hệt nhau khiến số điện thoại bị hạn chế.

Gửi trực tiếp đến một số điện thoại WhatsApp Web

POST /whatsapp-web/send

Gửi tin nhắn đến một số điện thoại trên WhatsApp Web mà không cần tra cứu liên hệ trước. Nếu số đó chưa phải là liên hệ, liên hệ sẽ được tạo trong cùng một lệnh gọi, với AI được tắt cho liên hệ đó, vì vậy tin nhắn sẽ hiển thị như thể bạn tự gửi và không có trợ lý nào tiếp quản cuộc trò chuyện sau đó. Một liên hệ hiện có sẽ được sử dụng lại như cũ.

Trường Bắt buộc Mô tả
phoneNumber Có Số điện thoại cần nhắn tin, theo định dạng quốc tế (+31612345678).
message Không Văn bản cần gửi. Phải có message hoặc mediaUrl.
mediaUrl Không URL công khai của tệp cần gửi. Phải có message hoặc mediaUrl.
mediaContentType Không Loại MIME của tệp đó, ví dụ: image/jpeg. Sẽ được tự động xác định từ URL nếu bạn bỏ trống.
sendAsVoiceNote Không true gửi tệp âm thanh dưới dạng tin nhắn thoại thay vì tệp đính kèm.
fromPhoneNumber Không Số WhatsApp Web đã kết nối nào của bạn sẽ được dùng để gửi, theo định dạng quốc tế. Mặc định là số mà liên hệ đó đã thuộc về.
campaignId Không Sử dụng giờ hoạt động từ Tác nhân (Agent) này thay vì mặc định của tài khoản. Phải là một Tác nhân trên cùng tài khoản.
ignoreActiveHours Không true gửi ngay lập tức, bất kể giờ hoạt động quy định thế nào.
sub_account_id Không Dành cho các đại lý: gửi thay mặt cho một trong các tài khoản khách hàng của bạn.
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-web/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+31612345678",
    "message": "Hi Alex, your quote is ready."
  }'

Một lệnh gọi thành công sẽ trả về 202:

{ "success": true, "queued": true, "contactId": "abc123" }

202 có nghĩa là đã chấp nhận, chưa được gửi đi. Ngoài giờ hoạt động, tin nhắn sẽ được giữ lại và gửi đi trong khung giờ cho phép tiếp theo, trừ khi bạn đã truyền ignoreActiveHours. Đọc trạng thái của tin nhắn bằng cách Liệt kê tin nhắn của liên hệ sử dụng contactId mà bạn nhận được ở đây.

Khi tin nhắn không được gửi đi:

Trạng thái Mã Điều gì đã xảy ra
400 INVALID_PHONE_FORMAT Số điện thoại không đúng định dạng quốc tế, hoặc thiếu phoneNumber, hoặc thiếu cả message và mediaUrl.
400 CONTACT_DND Liên hệ đó đang ở chế độ Không làm phiền, vì vậy không có tin nhắn gửi đi nào được gửi đến họ.
400 CONTACT_PRIVATE Liên hệ đó được đánh dấu là riêng tư.
404 CAMPAIGN_NOT_FOUND Không có Tác nhân nào khớp với campaignId mà bạn đã truyền.
403 CAMPAIGN_FORBIDDEN Tác nhân đó thuộc về một tài khoản khác.
402 Tài khoản đã hết tín dụng hoặc chưa có số WhatsApp Web nào được kết nối.

Lệnh gọi thứ hai cho cùng một liên hệ trong khi một tin nhắn đang chờ gửi sẽ trả về 409, vì vậy hàng đợi sẽ không bao giờ tích tụ phía sau một người.


Ghi chú vào một cuộc hội thoại

POST /contacts/notes

Thêm một dòng vào cuộc hội thoại của liên hệ mà không gửi đi. Hãy sử dụng tính năng này cho các ngữ cảnh mà nhóm của bạn và AI cần biết nhưng liên hệ không bao giờ được phép thấy: tóm tắt một cuộc gọi điện thoại mà tổng đài viên của bạn vừa thực hiện, nhận xét từ CRM của bạn hoặc ghi chú từ đồng nghiệp. Tính năng này hoạt động trên mọi kênh (WhatsApp, SMS, Instagram, Messenger, Telegram, tiện ích trò chuyện, các kênh tùy chỉnh, v.v.).

Điều gì xảy ra với một ghi chú:

  • Nó hiển thị trong cuộc trò chuyện ở hộp thư đến dưới dạng thẻ Ghi chú màu vàng, kèm theo tên tác giả nếu bạn có gửi kèm.
  • AI đọc nó như một phần của lịch sử hội thoại, được đánh dấu là ghi chú nội bộ, vì vậy câu trả lời tiếp theo của nó sẽ tính đến thông tin này.
  • Nó không bao giờ được gửi đến liên hệ, không tốn tín dụng tin nhắn và không kích hoạt bất cứ điều gì: không có phản hồi từ AI, không có tự động hóa, không có webhook, không có thông báo, không có huy hiệu chưa đọc. Nó không tạm dừng AI và không được tính là một phản hồi từ nhóm của bạn.

Tìm liên hệ theo cách tương tự như Gửi theo định danh liên hệ: sử dụng ID của liên hệ hoặc channel kèm theo định danh khớp. Ghi chú chỉ được gửi đến một liên hệ đã tồn tại; nếu không có gì khớp, đó là một 404.

Trường Bắt buộc Mô tả
contact_id Một trong hai ID của liên hệ.
channel + identifier Một trong hai channel cộng với phone_number (WhatsApp, WhatsApp Web, SMS), instagram_id, messenger_id hoặc telegram_user_id, như trong Gửi theo danh tính liên hệ.
body Có Nội dung ghi chú, tối đa 4.000 ký tự. Các ngắt dòng được giữ nguyên.
author Không Ai hoặc cái gì đã viết ghi chú đó, tối đa 80 ký tự, ví dụ Voice agent hoặc Sarah (sales). Được hiển thị trên thẻ và cho AI.
timestamp Không Thời điểm xảy ra, tính bằng mili giây epoch. Mặc định là thời điểm hiện tại. Hãy sử dụng thời gian kết thúc cuộc gọi để ghi chú nằm đúng vị trí trong luồng hội thoại. Thời gian này không được quá 5 phút trong tương lai; thời gian muộn hơn sẽ bị từ chối với mã 400.
external_id Không ID của riêng bạn cho ghi chú này, tối đa 200 ký tự, ví dụ như ID cuộc gọi. Việc gửi lại cùng một external_id cho cùng một liên hệ sẽ không thêm ghi chú thứ hai; phản hồi sau đó sẽ chứa duplicate: true. Hãy sử dụng nó để webhook được thử lại không thể ghi nhật ký cùng một cuộc gọi hai lần.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/notes" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "phone_number": "+31612345678",
    "author": "Voice agent",
    "body": "Voice call, 3:12. Asked about knee surgery waiting times, prefers a call back on Tuesday morning.",
    "external_id": "call_8f2k1"
  }'

Phản hồi (201, hoặc 200 với duplicate: true khi external_id đã được ghi lại)

{
  "success": true,
  "messageId": "note_4c1f0e...",
  "contactId": "contact123"
}

Một ghi chú xuất hiện trong Liệt kê tin nhắn của liên hệ với type: "note".

Tạo bản nháp trả lời bằng AI

POST /contacts/{contactId}/draft-reply

Yêu cầu tác nhân AI xử lý cuộc hội thoại viết câu trả lời tiếp theo và trả về văn bản cho bạn. Không có gì được gửi đi. Đây chính là bản nháp mà nút Tạo trả lời trong hộp thư đến thực hiện: tác nhân sử dụng thiết lập, cơ sở kiến thức và nội dung cuộc hội thoại cho đến thời điểm hiện tại để trả lời bằng ngôn ngữ của người liên hệ. Hãy sử dụng tính năng này để đặt một con người (hoặc ứng dụng của riêng bạn) vào giữa AI và người liên hệ: lấy bản nháp, hiển thị để phê duyệt, sau đó gửi đi bằng Gửi theo ID liên hệ, dù đã thay đổi hay giữ nguyên.

  • Bản nháp được viết bởi tác nhân được chỉ định cho người liên hệ. Một người liên hệ chưa có tác nhân sẽ nhận được tác nhân sẽ trả lời tin nhắn tiếp theo của họ.
  • Trong khi soạn thảo, tác nhân không chạy bất kỳ công cụ hoặc hàm nào, vì vậy không có hành động đặt chỗ, gắn thẻ, chuyển giao hoặc hành động nào khác xảy ra.
  • Không có gì được lưu trữ trong cuộc hội thoại và người liên hệ không thấy bất cứ điều gì.
  • Một bản nháp tốn số tín dụng tương đương với một lần trả lời của AI từ tác nhân đó trong cuộc hội thoại này, và không tốn phí khi khóa AI của riêng bạn được kết nối.
  • Cuộc hội thoại cần có ít nhất một tin nhắn.

Tất cả các trường nội dung đều là tùy chọn; một nội dung trống (hoặc không có nội dung) sẽ soạn thảo câu trả lời tiếp theo.

Trường Bắt buộc Mô tả
instruction Không Một chỉ dẫn dùng một lần cho bản nháp này, tối đa 2.000 ký tự, giống như việc nhấn giữ Tạo trả lời trong hộp thư đến. Ví dụ: Offer Tuesday at 3pm hoặc Ask for their email address.
campaign_id Không Soạn thảo theo chiến dịch này thay vì tác nhân của người liên hệ.
purpose Không chat_reply (mặc định) viết tin nhắn cho người liên hệ. faq_answer viết câu trả lời ngắn gọn cho câu hỏi của người liên hệ, có thể hoạt động độc lập, dùng cho FAQ cơ sở kiến thức.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/draft-reply" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "instruction": "Offer Tuesday at 3pm for the consultation" }'

Phản hồi (200)

{
  "success": true,
  "contact_id": "contact123",
  "draft": "Hi Sara, Tuesday at 3pm works for the consultation. Shall I put you down for it?"
}

400 có nghĩa là cuộc hội thoại chưa có tin nhắn nào, tín dụng của bạn đã hết hoặc người liên hệ không có tác nhân hay chiến dịch nào để soạn thảo (error cho biết lý do). 404 có nghĩa là người liên hệ không tồn tại hoặc khóa của thành viên trong nhóm bị giới hạn đối với các liên hệ mà họ không thể xem. Khóa hoặc thành viên nhóm cần có quyền chỉnh sửa tin nhắn.

Sử dụng ứng dụng khách AI qua MCP? Hành động tương tự cũng có sẵn dưới dạng công cụ generate_reply_draft.

Liệt kê tin nhắn của một liên hệ

GET /contacts/{contactId}/messages

Trả về các tin nhắn của một liên hệ, tin nhắn mới nhất hiển thị trước, hỗ trợ phân trang dựa trên con trỏ.

Tham số truy vấn Bắt buộc Mô tả
limit Không Kích thước trang. Mặc định là 50, tối đa là 100.
cursor Không Giá trị next_cursor từ phản hồi trước đó. Trả về các tin nhắn cũ hơn con trỏ này.
filter Không Lọc theo loại nội dung: all (mặc định), text, media hoặc tool_use.
direction Không Lọc theo hướng: all (mặc định), inbound (nhận từ liên hệ) hoặc outbound (gửi bởi bạn).

Lưu ý về lọc và phân trang: Các bộ lọc filter và direction được áp dụng cho từng trang sau khi trang đó được đọc, vì vậy một trang đã lọc có thể chứa ít mục hơn limit. Con trỏ next_cursor vẫn tiến triển qua toàn bộ cuộc hội thoại, vì vậy hãy tiếp tục phân trang cho đến khi next_cursor là null.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&direction=inbound" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ limit: "50", direction: "inbound" });
const res = await fetch(
  `https://api.youraiconnector.com/v1/contacts/contact123/messages?${params}`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.messages, data.next_cursor);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"limit": 50, "direction": "inbound"},
)
data = res.json()
print(data["messages"], data["next_cursor"])

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T10:00:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ],
  "next_cursor": "cD4eF6gH8iJ0kL2mN3oP"
}

Các trường tin nhắn

Trường Mô tả
id ID duy nhất của tin nhắn.
body Nội dung văn bản của tin nhắn. Đối với tin nhắn có tệp đính kèm, body bắt đầu bằng một ghi chú trong ngoặc về những gì đã nhận được, theo sau là bất kỳ chú thích nào, ví dụ [THE CONTACT UPLOADED AN IMAGE] Here is my CV hoặc [THE CONTACT UPLOADED A VOICE NOTE] - [TRANSCRIPTION: ...]. Ghi chú thoại và video bao gồm cả bản ghi âm.
direction inbound (nhận từ liên hệ) hoặc outbound (được gửi bởi tài khoản của bạn).
channel Kênh mà tin nhắn được gửi hoặc nhận (ví dụ: whatsapp, sms, instagram).
status Trạng thái gửi hiện tại, ví dụ: Created, sent, delivered, read, failed.
type Loại tin nhắn. Tin nhắn văn bản thuần túy có loại null; hoạt động công cụ trợ lý tự động được đánh dấu tool_use.
timestamp Thời gian ISO 8601 khi tin nhắn được tạo.
media_url URL của tệp phương tiện đính kèm, nếu có. Liên kết này sẽ ngừng hoạt động 7 ngày sau khi tin nhắn đến, trên mọi kênh (WhatsApp Business API, WhatsApp Web, Instagram, Messenger, Telegram, tiện ích trò chuyện và các kênh khác). Lấy liên kết mới với Tải xuống tệp đính kèm của tin nhắn.
media_content_type Loại MIME của phương tiện đính kèm, nếu có.
bot_reply true khi tin nhắn được tạo bởi trợ lý AI.
score Đánh giá của bạn về tin nhắn: 1 ngón tay cái lên, -1 ngón tay cái xuống, 0 khi chưa được đánh giá. Xem Đánh giá hoặc gắn sao tin nhắn.
is_important true khi tin nhắn đã được gắn sao.
is_deleted true khi tin nhắn đã bị xóa. Tin nhắn đã xóa vẫn nằm trong danh sách nhưng body và media_url của chúng sẽ trống.
reactions Các phản ứng biểu tượng cảm xúc trên tin nhắn, từ cả hai phía. Luôn là một mảng — trống khi không có phản ứng nào. Mỗi mục có emoji, from_phone_number, from_me (true khi phản ứng là của bạn) và reacted_at.
faq_ids_used ID của các câu hỏi thường gặp (FAQ) trong Cơ sở kiến thức mà AI đã có trước mặt khi viết câu trả lời này: những câu được chọn cho tin nhắn mới nhất cộng với những câu được giữ lại từ trước đó trong cuộc hội thoại. Danh sách tương tự nằm trên mọi tin nhắn của một câu trả lời được gửi thành nhiều phần. Luôn là một mảng, trống đối với tin nhắn đến, tin nhắn do con người gửi, tin nhắn theo dõi tự động và các phản hồi AI được gửi trước ngày 25 tháng 9 năm 2026.
faqs_used Các FAQ tương tự cùng với câu hỏi của chúng: mỗi mục có id và question. question là null khi FAQ đã bị xóa kể từ đó.

Tải xuống tệp đính kèm của tin nhắn

POST /chat-exports/media/download-url

Cung cấp cho bạn một liên kết tải xuống mới cho tệp đính kèm trong tin nhắn: hình ảnh, ghi chú thoại, video hoặc tài liệu. Liên kết có hiệu lực trong 1 giờ. Hãy sử dụng tính năng này khi bạn muốn lưu tệp đính kèm ở nơi khác (ví dụ: lưu trữ CV hoặc ghi chú thoại mà liên hệ đã gửi), hoặc khi media_url trên một tin nhắn hoặc Webhook tin nhắn mới không còn mở được nữa.

Để tìm các tin nhắn có tệp đính kèm, hãy liệt kê các tin nhắn của liên hệ bằng filter=media. id của mỗi tin nhắn và ID của liên hệ tạo thành messagePath.

Trường nội dung Bắt buộc Mô tả
messagePath Có Tin nhắn nào, ở định dạng contacts/{contactId}/messages/{messageId}.

cURL

curl -X POST "https://api.youraiconnector.com/v1/chat-exports/media/download-url" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"}'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/chat-exports/media/download-url", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ messagePath: "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO" }),
});
const { data } = await res.json();
console.log(data.url); // download the file within the hour

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/chat-exports/media/download-url",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"},
)
file_url = res.json()["data"]["url"]

Phản hồi (200 OK):

{
  "success": true,
  "data": {
    "url": "https://storage.googleapis.com/...",
    "expiresInMs": 3600000
  }
}
Trường Mô tả
data.url Liên kết tải xuống. Lấy tệp trực tiếp từ liên kết này, không cần khóa API.
data.expiresInMs Thời gian liên kết có hiệu lực, tính bằng mili giây (3600000 = 1 giờ). Hãy gọi lại điểm cuối để nhận liên kết mới.
Trạng thái Khi nào
400 messagePath bị thiếu hoặc không ở định dạng contacts/{contactId}/messages/{messageId}, hoặc tin nhắn không có tệp đính kèm nào có thể tải xuống theo cách này. Một số tệp đính kèm cũ hơn được lưu trữ tại nhà cung cấp kênh và không thể cấp lại, đồng thời một bài đăng hoặc thước phim Instagram được chia sẻ là liên kết đến Instagram thay vì là một tệp tin.
403 Liên hệ không thuộc về tài khoản của bạn.
404 Không có tin nhắn nào với ID đó tồn tại trên liên hệ đó.

Sử dụng ứng dụng khách AI qua MCP? Hành động tương tự cũng có sẵn dưới dạng công cụ get_chat_media_download_url.


Liệt kê các phiên trò chuyện

Một phiên trò chuyện là một cửa sổ hội thoại với một liên hệ. Phiên này mở ra khi có tin nhắn đến đầu tiên trong trường hợp chưa có phiên nào đang mở, và tự động đóng sau 48 giờ kể từ tin nhắn đến cuối cùng của liên hệ (mỗi tin nhắn đến mới sẽ gia hạn thời gian đóng thêm 48 giờ nữa). Việc AI kết thúc trò chuyện không đóng phiên; nó chỉ kích hoạt webhook Chat Concluded. Các phiên là cách để bạn phân trang lịch sử dài thành các cuộc hội thoại dễ đọc thay vì một danh sách vô tận.

Các phiên gần đây trên tất cả liên hệ

GET /chat-sessions/recent

Trả về các phiên bắt đầu trong X giờ qua, mới nhất trước, trên tất cả liên hệ trong tài khoản.

Tham số truy vấn Bắt buộc Mô tả
hours Có Xem lại bao nhiêu giờ trước. Phải là một số nguyên dương.
status Không Chỉ trả về các phiên có trạng thái này: ChatSessionOpened hoặc ChatSessionClosed.
limit Không Số lượng phiên tối đa cần trả về. Mặc định 100, tối đa 100.
includeMessages Không true thêm một mảng messages vào mỗi phiên. Mặc định tắt vì nó làm cho phản hồi lớn hơn nhiều.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/recent?hours=24&status=ChatSessionClosed" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ hours: "24", status: "ChatSessionClosed" });
const res = await fetch(`https://api.youraiconnector.com/v1/chat-sessions/recent?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data.total_sessions, data.data.sessions);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-sessions/recent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"hours": 24, "status": "ChatSessionClosed"},
)
data = res.json()["data"]
print(data["total_sessions"], data["sessions"])

Phản hồi (200 OK):

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_sessions": 2,
    "sessions": [
      {
        "session_id": "session456",
        "contact_id": "contact123",
        "contact_name": "Jane Doe",
        "contact_phone": "+31612345678",
        "contact_email": "jane@example.com",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Tất cả các phiên cho một liên hệ

GET /chat-sessions/{contactId}

Trả về mọi phiên trò chuyện cho một liên hệ duy nhất. Các tham số status, limit và includeMessages giống như trên — hours không áp dụng ở đây.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
  -H "X-API-Key: YOUR_API_KEY"

Phản hồi (200 OK):

{
  "success": true,
  "data": {
    "contact_id": "contact123",
    "contact_name": "Jane Doe",
    "total_sessions": 2,
    "sessions": [
      {
        "id": "session456",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Tên trường ID phiên khác nhau giữa hai điểm cuối. Danh sách phiên gần đây gọi nó là session_id (nó cũng chứa chi tiết của liên hệ, vì các phiên đến từ nhiều liên hệ); danh sách theo liên hệ gọi nó là id. Giá trị nào cũng là thứ bạn truyền dưới dạng {sessionId} khi lấy toàn bộ chuỗi hội thoại bên dưới.

Khi includeMessages=true, mỗi phiên sẽ có thêm một mảng messages mà các mục của nó chứa id, body, direction, timestamp, type, channel và status.


Lấy luồng phiên trò chuyện

GET /contacts/{contactId}/chat-sessions/{sessionId}/messages

Một phiên trò chuyện nhóm các tin nhắn của một liên hệ vào một cửa sổ hội thoại. Điểm cuối này trả về toàn bộ chuỗi của một phiên duy nhất, theo thứ tự cũ nhất trước, cùng với siêu dữ liệu của phiên đó. Bạn có thể tìm thấy ID phiên cho một liên hệ thông qua các điểm cuối phiên trò chuyện.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.session, data.messages);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["session"], data["messages"])

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "session": {
    "id": "session456",
    "status": "ChatSessionClosed",
    "start_date_time": "2026-06-01T09:55:00.000Z",
    "end_date_time": "2026-06-01T10:20:00.000Z",
    "tag": "Booking enquiry"
  },
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T09:55:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ]
}

Đối tượng session báo cáo status (ChatSessionOpened khi đang hoạt động, ChatSessionClosed sau khi kết thúc), start_date_time, end_date_time và một tag dễ đọc. Mảng messages sử dụng cùng các trường tin nhắn như điểm cuối danh sách.


Chỉnh sửa, xóa và phản hồi tin nhắn

Các điểm cuối này thay đổi tin nhắn sau khi nó đã được gửi. Hai trong số đó tiếp cận kênh của liên hệ cũng như bản sao của riêng bạn, vì vậy hãy đọc phần giới thiệu trước khi kết nối chúng — những gì có thể thực hiện phụ thuộc hoàn toàn vào kênh mà cuộc trò chuyện đang diễn ra.

Mỗi kênh cho phép những gì

Hành động Các kênh có thể thay đổi bản sao của liên hệ Giới hạn thời gian
Chỉnh sửa tin nhắn đã gửi Tiện ích trò chuyện, WhatsApp Web (chỉ tin nhắn văn bản), Telegram, LinkedIn Không giới hạn trên tiện ích trò chuyện, 15 phút trên WhatsApp Web, 48 giờ trên Telegram, 60 phút trên LinkedIn
Xóa cho mọi người Tiện ích trò chuyện, WhatsApp Web, Telegram, LinkedIn 60 phút trên LinkedIn; các kênh khác không có giới hạn được công bố
Phản ứng bằng biểu tượng cảm xúc WhatsApp Web, Telegram Không có

Trên mọi kênh khác — WhatsApp Business API, SMS, Instagram, Messenger, email, LINE, các kênh tùy chỉnh — việc xóa vẫn loại bỏ tin nhắn khỏi hộp thư đến của bạn, nhưng liên hệ vẫn giữ bản sao của họ, và việc chỉnh sửa hoặc phản ứng hoàn toàn không thể thực hiện được.

Chỉnh sửa tin nhắn

POST /contacts/{contactId}/messages/{messageId}/edit

Viết lại tin nhắn bạn đã gửi, trên thiết bị của liên hệ và trong bản sao của bạn.

Trường Bắt buộc Mô tả
body Có Nội dung tin nhắn mới. Không được để trống và không được dài hơn giới hạn của kênh trong một tin nhắn (giới hạn mỗi kênh tương tự như Gửi theo ID liên hệ; 4.096 khi tin nhắn không có kênh).

Không giống như việc xóa, hành động này sẽ thông báo lỗi rõ ràng khi kênh từ chối: bạn sẽ nhận được 409 và bản sao của bạn vẫn giữ nguyên như những gì liên hệ đang có, vì việc hiển thị một chỉnh sửa mà họ chưa bao giờ nhận được sẽ khiến hai bên không đồng bộ với nhau. Trường edit_reason cho bạn biết lý do — cửa sổ chỉnh sửa của kênh đã đóng, kênh đã bị ngắt kết nối, tin nhắn có tệp đính kèm mà kênh không thể chỉnh sửa (media_not_editable: trên WhatsApp Web chỉ có thể chỉnh sửa tin nhắn văn bản, không thể chỉnh sửa văn bản dưới ảnh, video hoặc tệp), hoặc có lỗi khác xảy ra.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Sorry - I meant Thursday at 3pm." }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ body: "Sorry - I meant Thursday at 3pm." }),
  }
);
const data = await res.json();
console.log(data.edited, data.edit_reason);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Sorry - I meant Thursday at 3pm."},
)
data = res.json()
print(data.get("edited"), data.get("edit_reason"))

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "edited": true,
  "edit_reason": "edit_dispatched"
}

Nếu kênh không chấp nhận chỉnh sửa, bạn sẽ nhận được 409 thay vào đó và không có gì thay đổi:

{
  "success": false,
  "error": "The message could not be edited",
  "edit_reason": "channel_disconnected"
}

Một tin nhắn đã bị xóa, một kênh không thể chỉnh sửa và một tin nhắn quá cũ so với kênh của nó đều trả về 400 — yêu cầu không bao giờ đến được kênh.

Xóa một tin nhắn

DELETE /contacts/{contactId}/messages/{messageId}

Xóa tin nhắn khỏi cuộc trò chuyện của bạn và, nếu kênh cho phép, sẽ thu hồi cả bản sao của liên hệ. Không có phần thân yêu cầu.

Hành động này luôn trả về 200 khi tin nhắn tồn tại, ngay cả khi bản sao của liên hệ không thể thu hồi — bản sao của bạn đã bị xóa, vì vậy một lỗi sẽ gây hiểu lầm. Hãy đọc ba trường trong phản hồi để thông báo cho người dùng những gì thực sự đã xảy ra:

Trường Mô tả
revoke_supported Liệu kênh này có thể thu hồi tin nhắn hay không.
revoked Liệu bản sao trên thiết bị của liên hệ đã bị xóa hay chưa.
revoke_reason Lý do tại sao nó không bị xóa, khi revoked là false — ví dụ revoke_window_closed hoặc already_deleted.

cURL

curl -X DELETE "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.revoked, data.revoke_reason);

Python

import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["revoked"], data["revoke_reason"])

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "revoke_supported": true,
  "revoked": true,
  "revoke_reason": "revoke_dispatched"
}

Các tin nhắn đã xóa không bị loại bỏ khỏi lịch sử cuộc trò chuyện. Chúng vẫn nằm trong GET /contacts/{contactId}/messages với is_deleted: true cùng một body và media_url trống.

Xóa nhiều tin nhắn cùng lúc

POST /contacts/{contactId}/messages/bulk-delete

Xóa một loạt tin nhắn chỉ từ phía bạn. Nội dung và tệp đính kèm sẽ bị xóa sạch, nhưng không có gì bị thu hồi trên thiết bị của người liên hệ — để thu hồi tin nhắn, hãy xóa từng tin một bằng điểm cuối tin nhắn đơn lẻ ở trên.

Trường Bắt buộc Mô tả
message_ids Có Một mảng không trống chứa các ID tin nhắn, tối đa 500 ID mỗi yêu cầu. messageIds được chấp nhận như một bí danh.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message_ids": ["msg_1", "msg_2"] }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ message_ids: ["msg_1", "msg_2"] }),
  }
);
console.log((await res.json()).deleted);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["msg_1", "msg_2"]},
)
print(res.json()["deleted"])

Phản hồi (200 OK):

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

Phản ứng với một tin nhắn

POST /contacts/{contactId}/messages/{messageId}/react

Đặt phản ứng bằng biểu tượng cảm xúc của riêng bạn lên một tin nhắn, hoặc thu hồi lại bằng cách gửi một chuỗi trống. Các phản ứng của người liên hệ sẽ không bao giờ bị ảnh hưởng.

Trường Bắt buộc Mô tả
emoji Có Biểu tượng cảm xúc để phản ứng, hoặc "" để xóa phản ứng của bạn. Phải là một chuỗi đơn không có khoảng trắng, tối đa 16 ký tự.

Giống như việc chỉnh sửa, thao tác này sẽ thất bại thay vì hiển thị một phản ứng mà người liên hệ chưa bao giờ nhận được, và thông báo lỗi sẽ cho bạn biết liệu có nên thử lại hay không:

  • 422 — không bao giờ có thể gửi được trong cuộc trò chuyện này: kênh không hỗ trợ phản ứng, tin nhắn không có ID phía kênh, hoặc biểu tượng cảm xúc nằm ngoài tập hợp mà kênh cho phép.
  • 409 — kênh tạm thời không thể truy cập được. Thử lại có thể sẽ thành công.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "emoji": "👍" }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ emoji: "👍" }),
  }
);
const data = await res.json();
console.log(data.reactions);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"emoji": "👍"},
)
print(res.json()["reactions"])

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "reaction_supported": true,
  "reaction_reason": "reaction_dispatched",
  "reactions": [
    {
      "emoji": "👍",
      "from_phone_number": "+31612345678",
      "from_me": true,
      "reacted_at": "2026-06-01T10:05:00.000Z"
    }
  ]
}

Mảng reactions là tập hợp đầy đủ các phản ứng hiện có trên tin nhắn, bao gồm cả của bạn và của người liên hệ. Trên 409 hoặc 422, nó được trả về nguyên trạng, vì vậy ứng dụng khách hiển thị trực tiếp từ đó sẽ không bao giờ hiển thị một phản ứng chưa được gửi đi.

Đánh giá hoặc gắn sao cho tin nhắn

PATCH /contacts/{contactId}/messages/{messageId}

Đánh giá tin nhắn bằng ngón tay cái hướng lên hoặc hướng xuống và/hoặc gắn sao cho tin nhắn đó là quan trọng. Đây chỉ là việc ghi chép ở phía bạn — không có gì được gửi đến người liên hệ.

Trường Bắt buộc Mô tả
score Không 1 thích, -1 không thích, 0 xóa đánh giá.
is_important Không true gắn sao tin nhắn, false bỏ gắn sao. Phải là giá trị boolean thực, không phải chuỗi "true".

Hãy gửi ít nhất một trong hai, nếu không bạn sẽ nhận được 400. Chỉ những gì bạn gửi mới được ghi lại, vì vậy việc gắn sao tin nhắn sẽ không bao giờ xóa đánh giá của nó và ngược lại — và phản hồi chỉ trả về các trường bạn đã gửi.

cURL

curl -X PATCH "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "score": 1, "is_important": true }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1", {
  method: "PATCH",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ score: 1, is_important: true }),
});

Python

import requests

requests.patch(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"score": 1, "is_important": True},
)

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "score": 1,
  "is_important": true
}

Đánh dấu tin nhắn là đã đọc

Bạn có thể xóa trạng thái chưa đọc cho các tin nhắn cụ thể hoặc cho toàn bộ cuộc hội thoại.

Đánh dấu các tin nhắn cụ thể là đã đọc

POST /contacts/{contactId}/messages/mark-read

Chuyển các ID của tin nhắn cần đánh dấu là đã đọc.

Trường Bắt buộc Mô tả
message_ids Có Một mảng không trống chứa các ID tin nhắn (tối đa 500 ID mỗi yêu cầu).

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message_ids: ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"],
    }),
  }
);
const data = await res.json();
console.log(data.marked_read);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]},
)
print(res.json()["marked_read"])

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "marked_read": 2
}

Đánh dấu toàn bộ cuộc trò chuyện là đã đọc

POST /contacts/{contactId}/mark-read

Xóa huy hiệu chưa đọc cho toàn bộ cuộc hội thoại của liên hệ trong hộp thư đến. Không yêu cầu phần thân yêu cầu.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-read" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123"
}

Đánh dấu toàn bộ cuộc trò chuyện là chưa đọc

POST /contacts/{contactId}/mark-unread

Đặt lại huy hiệu chưa đọc vào cuộc trò chuyện — hữu ích khi ai đó trong nhóm của bạn đã mở cuộc trò chuyện nhưng đang bàn giao lại. Không yêu cầu nội dung yêu cầu (request body).

Đây là cờ chỉ dành cho hộp thư đến: nó không thay đổi thời điểm cuộc trò chuyện được đọc lần cuối, vì vậy không có biên nhận đã đọc nào được gửi đến liên hệ trên các kênh hỗ trợ tính năng này.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
  -H "X-API-Key: YOUR_API_KEY"

Phản hồi (200 OK):

{
  "success": true,
  "contact_id": "contact123"
}

Xuất cuộc trò chuyện

Việc xuất dữ liệu cung cấp cho bạn toàn bộ cuộc trò chuyện dưới dạng bản ghi có thể đọc được, thay vì phải lật qua từng tin nhắn. Mọi điểm cuối xuất dữ liệu đều chấp nhận filter là all (mặc định), text, media hoặc tool_use, khớp với bộ lọc trên danh sách tin nhắn.

Xuất cuộc trò chuyện của một liên hệ

GET /chat-exports/{contactId}

Tham số truy vấn Bắt buộc Mô tả
format Không txt (mặc định) trả về liên kết tải xuống bản ghi văn bản thuần túy. json trả về các tin nhắn dưới dạng dữ liệu có cấu trúc trong phản hồi.
filter Không all (mặc định), text, media hoặc tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/contact123?format=json" \
  -H "X-API-Key: YOUR_API_KEY"

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-exports/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"format": "json"},
)
print(res.json()["data"]["messages"])

Phản hồi với format=json (200 OK):

{
  "success": true,
  "data": {
    "contact": {
      "id": "contact123",
      "name": "Jane Doe",
      "phone": "+31612345678",
      "email": "jane@example.com"
    },
    "messages": [
      {
        "body": "Hi! I have a question about my order.",
        "direction": "inbound",
        "timestamp": "2026-06-01T09:55:00.000Z",
        "type": "text",
        "media_url": null,
        "media_content_type": null,
        "name": null,
        "args": null
      }
    ]
  }
}

Với format=txt (mặc định), data thay vào đó là liên kết tải xuống tệp bản ghi đã tạo:

{
  "success": true,
  "data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}

Liên kết tải xuống có thời hạn ngắn. Hãy tải tệp ngay khi bạn nhận được liên kết thay vì lưu trữ nó — hãy yêu cầu xuất mới khi bạn cần lại bản ghi.

Xuất mọi cuộc trò chuyện gần đây

GET /chat-exports/recent

Xuất các cuộc hội thoại của tất cả các liên hệ đã hoạt động trong X giờ qua, chỉ trong một lệnh gọi.

Tham số truy vấn Bắt buộc Mô tả
hours Có Số giờ hoạt động cần xem xét lại. Phải là một số nguyên dương.
format Không json (mặc định) trả về một mục cho mỗi liên hệ. txt trả về một tệp văn bản duy nhất có thể tải xuống chứa mọi cuộc hội thoại.
limit Không Số lượng liên hệ tối đa để xuất. Mặc định là 50, tối đa là 100.
filter Không all (mặc định), text, media hoặc tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
  -H "X-API-Key: YOUR_API_KEY"

Phản hồi (200 OK):

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_contacts": 2,
    "exports": [
      {
        "contactId": "contact123",
        "contactName": "Jane Doe",
        "phoneNumber": "+31612345678",
        "email": "jane@example.com",
        "messageCount": 12,
        "chatExport": "Acme Export - Jane Doe\nPhone: +31612345678\n..."
      }
    ]
  }
}

Với format=txt, phản hồi sẽ là chính tệp văn bản đó, được gửi dưới dạng tệp tải xuống thay vì JSON.

Lệnh gọi này lấy toàn bộ lịch sử của mọi liên hệ khớp, vì vậy hãy giữ hours và limit ở mức vừa phải trên các tài khoản bận rộn.

Gửi bản ghi cuộc hội thoại qua email cho liên hệ

POST /chat-exports/{contactId}/email

Gửi cho liên hệ bản ghi cuộc hội thoại của chính họ qua email — quy trình “gửi cho tôi cuộc trò chuyện này qua email”, được điều khiển từ hệ thống của riêng bạn.

Trường Bắt buộc Mô tả
recipient_email Không Nơi gửi email. Mặc định là địa chỉ email đã lưu của liên hệ.
via Không auto (mặc định) chọn lộ trình tốt nhất, transactional gửi dưới dạng email hệ thống, email_channel gửi từ kênh email đã kết nối của bạn.
note Không Một dòng ngắn từ bạn hiển thị phía trên bản ghi cuộc hội thoại. Tối đa 1000 ký tự.

cURL

curl -X POST "https://api.youraiconnector.com/v1/chat-exports/contact123/email" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Here is a copy of our chat, as promised." }'

Phản hồi (200 OK):

{
  "success": true,
  "data": {
    "via": "transactional",
    "recipientEmail": "jane@example.com",
    "messageCount": 42,
    "omittedCount": 0
  }
}

omittedCount cho bạn biết có bao nhiêu tin nhắn cũ nhất đã bị lược bỏ để giữ cho email có độ dài hợp lý. 200 có nghĩa là bản ghi cuộc hội thoại đã được tạo và đưa vào hàng đợi để gửi, không có nghĩa là nó đã đến hộp thư đến.


Tạm dừng hoặc tiếp tục AI cho một liên hệ

PUT /contacts/{contactId}

Đặt is_bot_active thành false để ngăn AI trả lời một liên hệ và đặt lại thành true để bàn giao lại cuộc trò chuyện. Đây là công tắc tiếp quản bạn cần khi một người thật tham gia vào cuộc trò chuyện: các tin nhắn gửi đi mà bạn gửi bằng API vẫn được chuyển đi trong khi bot đang bị tạm dừng.

cURL

curl -X PUT "https://api.youraiconnector.com/v1/contacts/contact123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_bot_active": false }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ is_bot_active: false }),
});

Python

import requests

requests.put(
    "https://api.youraiconnector.com/v1/contacts/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"is_bot_active": False},
)

Phản hồi

{
  "success": true,
  "contact_id": "contact123"
}

Tạm dừng như một phần của phản hồi

Nếu con người đang tiếp quản bằng cách gửi phản hồi, bạn có thể tạm dừng bot trong cùng một yêu cầu thay vì thực hiện cuộc gọi thứ hai. POST /contacts/{contactId}/send-message chấp nhận các cờ tùy chọn sau:

Trường Mô tả
pauseBot true tạm dừng AI cho liên hệ này khi tin nhắn được gửi.
clearIncompleteReply true hủy bỏ phản hồi bot đang viết dở để nó không tiếp tục sau đó.
human_reply true đánh dấu tin nhắn là phản hồi của đồng nghiệp và hủy bỏ phản hồi mà AI đã xếp hàng. Việc tạm dừng vẫn cần pauseBot.
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi, Sarah here - taking over from the assistant.",
    "pauseBot": true,
    "clearIncompleteReply": true,
    "human_reply": true
  }'

Phản hồi bao gồm "botPaused": true khi lệnh tạm dừng đã được áp dụng.

Đánh dấu một liên hệ là riêng tư với POST /contacts/bulk-flag cũng sẽ tạm dừng bot đối với họ. Xem Liên hệ để biết danh sách đầy đủ các trường.


Xây dựng hộp thư đến của riêng bạn

Mọi thứ mà một hộp thư đến cần đều có trên trang này và trong Liên hệ:

Những gì bạn cần Điểm cuối
Liệt kê các cuộc hội thoại GET /contacts
Đọc một cuộc hội thoại GET /contacts/{contactId}/messages
Liệt kê các phiên trò chuyện của liên hệ GET /chat-sessions/{contactId}
Xem những gì đã nhận gần đây GET /chat-sessions/recent
Đọc một phiên trò chuyện GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Gửi trả lời thủ công POST /contacts/{contactId}/send-message
Chỉnh sửa câu trả lời bạn vừa gửi POST /contacts/{contactId}/messages/{messageId}/edit
Xóa một tin nhắn DELETE /contacts/{contactId}/messages/{messageId}
Xóa nhiều tin nhắn POST /contacts/{contactId}/messages/bulk-delete
Phản ứng bằng biểu tượng cảm xúc POST /contacts/{contactId}/messages/{messageId}/react
Đánh giá hoặc gắn sao một tin nhắn PATCH /contacts/{contactId}/messages/{messageId}
Đánh dấu là đã đọc POST /contacts/{contactId}/mark-read
Chuyển lại cuộc trò chuyện cho nhóm POST /contacts/{contactId}/mark-unread
Xuất bản ghi cuộc hội thoại GET /chat-exports/{contactId}
Tạm dừng hoặc tiếp tục AI PUT /contacts/{contactId} với is_bot_active

Để nhận cập nhật trực tiếp, hãy đăng ký các sự kiện New Message, Replies, Human Alerted và Chat Concluded bằng Webhooks thay vì thăm dò API này theo bộ hẹn giờ.


Các lỗi của Messages API

Các điểm cuối (endpoint) tin nhắn trả về phong bì lỗi tiêu chuẩn:

{
  "success": false,
  "error": "Contact not found"
}
Trạng thái Khi nào nó xảy ra trên điểm cuối tin nhắn
400 Thiếu trường bắt buộc hoặc tham số không hợp lệ (limit, hours, filter, direction, status sai, mảng message_ids trống hoặc trên 500, cursor không hợp lệ, chỉnh sửa body trống hoặc quá dài, score nằm ngoài -1/0/1, hoặc biểu tượng cảm xúc có dấu cách hoặc trên 16 ký tự). Cũng được trả về khi tin nhắn không thể chỉnh sửa được — tin nhắn đã bị xóa, kênh của nó không hỗ trợ chỉnh sửa, hoặc đã quá thời hạn chỉnh sửa của kênh đó.
404 Không tìm thấy liên hệ, phiên trò chuyện hoặc một trong các ID tin nhắn được cung cấp.
409 Kênh không chấp nhận thay đổi vào lúc này. Không có gì được ghi lại: khi chỉnh sửa, edit_reason cho biết lý do; khi phản ứng, kênh tạm thời không thể truy cập được và việc thử lại có thể hiệu quả.
422 Liên hệ không thể nhận tin nhắn gửi đi (không làm phiền, riêng tư hoặc kênh không được hỗ trợ), hoặc phản ứng không bao giờ có thể được gửi trong cuộc hội thoại này (reaction_reason cho biết lý do).

Các mã chung mà mọi điểm cuối 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 Lỗi & Phân trang.


Các bước tiếp theo

  • Webhooks — nhận cập nhật trạng thái gửi tin nhắn được đẩy tới thay vì phải thăm dò (polling).
  • Liên hệ — tạo và tra cứu các liên hệ mà bạn nhắn tin.
  • Cuộc hẹn — đặt và quản lý cuộc hẹn cho các liên hệ của bạn.