
# API AI Agent

Một **AI Agent** (Tác nhân AI) là bộ não đằng sau bot của bạn: bao gồm các hướng dẫn, tính cách, ngôn ngữ, kiến thức và công cụ của nó. Bạn xây dựng một Agent một lần và sau đó điều hướng lưu lượng truy cập đến nó. Hướng dẫn này bao gồm mọi thứ bạn có thể thực hiện với một Agent thông qua API — tạo, cấu hình, cung cấp kiến thức và công cụ, xem xét các bản nháp và điều hướng các cuộc hội thoại đến nó.

- **URL cơ sở** — `https://api.youraiconnector.com/v1`
- **Xác thực** — khóa API của bạn (xem [Xác thực](authentication.md))
- **Lỗi & phân trang** — xem [Lỗi & Phân trang](errors-and-pagination.md)

Tất cả các ví dụ dưới đây đều hiển thị dạng truy vấn `?apiKey=` trong cURL và tiêu đề `X-API-Key` trong JavaScript và Python — cả hai đều hoạt động trên mọi endpoint.

Nếu bạn mới làm quen với khái niệm Agent, hãy đọc [AI Agents](../ai-agents/ai-agents.md) trước.


---

## Cách thức hoạt động của một Agent

Có bốn thành phần được quản lý riêng biệt, và việc hiểu rõ từng thành phần trước khi bắt đầu sẽ giúp ích cho bạn:

| Thành phần | Nó là gì | Nơi thiết lập |
|---|---|---|
| **Cấu hình** | Hướng dẫn, quy tắc, mục tiêu, tính cách, ngôn ngữ, cấp độ AI, hành vi đặt lịch và theo dõi | `PUT /agents/{agentId}` hoặc `PUT /agents/{agentId}/bot-config` cụ thể hơn |
| **Kiến thức** | FAQ và các nguồn kiến thức (các trang và tài liệu mà nền tảng đã đọc cho bạn) | [API FAQ](faqs.md) và `POST /agents/{agentId}/kb-sources` |
| **Công cụ** | Các hàm tùy chỉnh và máy chủ MCP mà Agent có thể gọi trong khi hội thoại | `POST /agents/{agentId}/custom-functions` và `POST /agents/{agentId}/mcp-servers` |
| **Điều hướng** | Các kênh và cuộc hội thoại nào thực sự tiếp cận Agent này | Điểm truy cập (Entry Points) — `PUT /entry-points/channel-defaults` và `POST /agents/{agentId}/entry-points` |

> **Một Agent mới sẽ không trả lời bất kỳ ai cho đến khi bạn điều hướng đến nó.** Việc tạo một Agent không tự động đưa nó vào một kênh. Đây là bước mà hầu hết các tích hợp thường bỏ lỡ — xem [Điều hướng cuộc hội thoại đến một Agent](#routing-conversations-to-an-agent) ở cuối trang này.

---

## Đối tượng Agent

Một tài liệu Agent đầy đủ thường rất lớn — vài trăm kilobyte, chủ yếu là danh sách FAQ, các nguồn kiến thức và bất kỳ nội dung trang nào được đọc từ trang web của bạn. Do đó, khi bạn yêu cầu liệt kê, hệ thống sẽ trả về một **dòng tóm tắt** ngắn gọn cho mỗi Agent:

```json
{
  "id": "ag7HkQ2ZpLxR3mNb",
  "name": "Listing assistant",
  "active": true,
  "language": "en",
  "goal": "Book a viewing",
  "tags": [],
  "anthropic_model": "standard",
  "ai_speed": "balanced",
  "enable_bookings": false,
  "enable_follow_ups": true,
  "faq_refs_count": 42,
  "kb_source_refs_count": 3,
  "created_at": 1700000000000,
  "last_modified_at": 1700000000000
}
```

| Trường | Kiểu dữ liệu | Mô tả |
|---|---|---|
| `id` | string | Mã định danh duy nhất của Agent. |
| `name` | string \| null | Tên của Agent, như hiển thị trên bảng điều khiển. |
| `active` | boolean \| null | Liệu Agent hiện có được phép trả lời hay không. |
| `language` | string \| null | Ngôn ngữ mà Agent sử dụng để trả lời. |
| `goal` | string \| null | Mục tiêu hoạt động của Agent, được rút gọn còn 200 ký tự đầu tiên (dấu ba chấm ở cuối nghĩa là nội dung đã bị rút gọn). |
| `tags` | array \| null | Các quy tắc gắn thẻ của Agent. |
| `anthropic_model` | string \| null | Cấp độ chất lượng AI: `standard`, `economy`, `max` hoặc `mini`. |
| `ai_speed` | string \| null | Mức độ suy luận mà Agent áp dụng trước khi trả lời: `fast`, `fast_thinker`, `balanced` hoặc `thorough`. |
| `enable_bookings` | boolean \| null | Liệu Agent có thể đặt lịch hẹn hay không. |
| `enable_follow_ups` | boolean \| null | Liệu Agent có gửi tin nhắn theo dõi hay không. |
| `faq_refs_count` | integer | Số lượng FAQ có trong cơ sở kiến thức của Agent này. |
| `kb_source_refs_count` | integer | Số lượng nguồn kiến thức được liên kết với nó. |
| `created_at` | integer \| null | Thời gian tạo, tính bằng mili giây epoch. |
| `last_modified_at` | integer \| null | Thay đổi lần cuối, tính bằng mili giây epoch. |

Tài liệu đầy đủ sẽ bao gồm mọi thứ khác: `instructions`, `rules`, `personality`, `availability`, `follow_up_config`, danh sách FAQ và nguồn kiến thức được liên kết, các khối văn bản được tạo và bất kỳ trạng thái chạy nào (`tag_generation`, `optimize_run`).

> Một số phản hồi cũng chứa `substrate_campaign_id`. Đây là bản ghi nội bộ được lưu giữ trên các tài khoản cũ; bạn không bao giờ cần phải thao tác với nó, và trên các tài khoản mới hơn, nó là `null` hoặc không tồn tại.

---

## Liệt kê các Agent

`GET /agents` — mọi Agent trên tài khoản, hiển thị theo thứ tự mới nhất trước.

Điểm cuối này **không được phân trang**. Theo mặc định, mỗi Agent sẽ trả về cấu hình đầy đủ, vốn rất nặng: một Agent đơn lẻ có thể đạt 580 KB và tài khoản 64-Agent có thể vượt quá 3 MB. Hãy truyền `view=summary` để nhận hàng ngắn gọn cho mỗi Agent, sau đó đọc thông tin bạn muốn bằng [Lấy một Agent](#get-an-agent).

**Các tham số truy vấn**

| Tham số | Mô tả |
|---|---|
| `view` | Đặt thành `summary` để nhận các hàng ngắn gọn. Bất kỳ giá trị nào khác sẽ trả về `400`. Bỏ qua để nhận tài liệu đầy đủ. |
| `fields` | Chỉ áp dụng cùng với `view=summary`. Các khóa tóm tắt được phân tách bằng dấu phẩy cần giữ lại, ví dụ: `id,name,active`. `id` luôn được bao gồm; các tên không xác định sẽ bị bỏ qua. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/agents?apiKey=YOUR_API_KEY&view=summary&fields=id,name,active"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents?view=summary", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { agents } = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/agents",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"view": "summary"},
)
agents = res.json()["agents"]
```

**Phản hồi** (`200`)

```json
{
  "success": true,
  "agents": [
    { "id": "ag7HkQ2ZpLxR3mNb", "name": "Listing assistant", "active": true }
  ]
}
```

---

## Tạo một Agent

`POST /agents` — chỉ thực sự cần `name`; hãy gửi bất kỳ cấu hình nào bạn đã biết kèm theo đó. Một Agent mới sẽ được kích hoạt theo mặc định.

**Các trường yêu cầu** (tất cả đều tùy chọn ngoại trừ `name`)

| Trường | Loại | Mô tả |
|---|---|---|
| `name` | string | Tên Agent. |
| `active` | boolean | Liệu nó có thể trả lời ngay lập tức hay không. Mặc định là `true`. |
| `language` | string | Ngôn ngữ mà Agent sử dụng để trả lời. |
| `instructions` | string | Các hướng dẫn chính điều hướng cách nó trò chuyện với khách hàng. |
| `rules` | string | Các quy tắc cứng nhắc mà nó phải luôn tuân thủ. |
| `goal` | string | Kết quả mà nó cần hướng tới. |
| `personality` | string | Giọng điệu và tính cách. |
| `availability` | object | Giờ hoạt động mỗi ngày trong tuần — xem [Thiết lập giờ hoạt động](#set-active-hours). |
| `ai_speed` | string | `fast`, `fast_thinker`, `balanced` hoặc `thorough`. |
| `anthropic_model` | string | `standard`, `economy`, `max` hoặc `mini`. |
| `scrape_urls` | string[] | Các trang cần đọc để xây dựng hướng dẫn cho Agent. |

**Xây dựng Agent từ trang web của bạn.** Hãy bao gồm `scrape_urls` và nền tảng sẽ đọc các trang đó rồi tự động viết hướng dẫn cho bạn. Phản hồi sẽ cho bạn biết quá trình tạo đó đã bắt đầu hay chưa, để bạn biết liệu có cần kiểm tra tiến độ của Agent hay không.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Listing assistant",
    "language": "en",
    "instructions": "Answer questions about our listings and book viewings.",
    "goal": "Book a viewing"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Listing assistant",
    scrape_urls: ["https://example.com", "https://example.com/faq"],
  }),
});
const data = await res.json();
console.log(data.agent_id);
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/agents",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"name": "Listing assistant", "scrape_urls": ["https://example.com"]},
)
print(res.json()["agent_id"])
```

**Phản hồi** (`201`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "substrate_campaign_id": null,
  "agent_generation_queued": true
}
```

`agent_generation_queued` là `true` khi nền tảng bắt đầu ghi các hướng dẫn từ các trang bạn đã cung cấp.

`400` có nghĩa là phần thân không phải là một đối tượng JSON, một trường bị từ chối hoặc Agent vượt quá kích thước cấu hình mà gói của bạn cho phép. `403` có nghĩa là tài khoản không được phép sử dụng một trong các cài đặt bạn đã gửi — ví dụ như một cấp độ AI mà nhà cung cấp tài khoản chưa cấp quyền.

---

## Lấy một Agent

`GET /agents/{agentId}`

Truyền `fields` với một danh sách được phân tách bằng dấu phẩy để chỉ nhận lại những gì bạn cần, ví dụ `fields=name,active,goal`. `id` luôn được bao gồm và các tên không tồn tại trên Agent sẽ bị bỏ qua thay vì bị từ chối. Hãy bỏ qua nó để nhận toàn bộ tài liệu.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY&fields=name,active,goal"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?fields=name,active", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { agent } = await res.json();
```

**Python**

```python
res = requests.get(
    "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"fields": "name,active"},
)
agent = res.json()["agent"]
```

Một Agent không tồn tại trong tài khoản của bạn sẽ trả về `404`.

---

## Cập nhật một Agent

`PUT /agents/{agentId}` — chỉ gửi các trường bạn muốn thay đổi; mọi thứ khác sẽ được giữ nguyên.

Các cài đặt lồng nhau có thể được xử lý từng phần tử một bằng khóa có dấu chấm, vì vậy `"availability.monday"` chỉ thay đổi Thứ Hai và giữ nguyên các ngày còn lại trong tuần.

**Lưu ý**

- Để thay đổi loại sự kiện có thể đặt chỗ mà Tác nhân (Agent) sẽ đặt, hãy gửi `event_id` (id của sự kiện, hoặc `null` để xóa nó). Gửi `event_ids` kèm một mảng để liên kết nhiều loại cùng lúc — loại đầu tiên sẽ trở thành loại chính và `[]` sẽ hủy liên kết tất cả. `event_id` và `event_ids` loại trừ lẫn nhau, và bản thân trường `event` không thể được ghi trực tiếp.
- `enable_bookings` phải là giá trị boolean thực, và `booking_provider` phải là một trong các giá trị `default`, `zenchef`, `formitable`.
- Các trường quyền sở hữu và danh tính sẽ bị bỏ qua, cũng như trạng thái chạy nội bộ (tiến trình tạo và tối ưu hóa).
- **Định tuyến không được thiết lập tại đây.** Sử dụng `PUT /entry-points/channel-defaults` để đặt Tác nhân làm người trả lời cho một kênh, `POST /agents/{agentId}/entry-points` cho các quy tắc từ khóa và bình luận, và `PATCH /agents/{agentId}/active` để tạm dừng hoặc tiếp tục hoạt động của nó.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Answer questions about our listings and always offer a viewing.",
    "anthropic_model": "standard"
  }'
```

**JavaScript**

```javascript
await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb", {
  method: "PUT",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ "availability.monday": { start_time: "09:00", end_time: "17:00" } }),
});
```

**Python**

```python
requests.put(
    "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"goal": "Book a viewing within three messages"},
)
```

**Phản hồi** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Phần thân trống sẽ trả về `400` kèm theo `"No fields to update"`.

---

## Cập nhật cài đặt bot

`PUT /agents/{agentId}/bot-config` — cách thức cụ thể để chỉ thay đổi các cài đặt hội thoại.

Một Tác nhân không có phần bot riêng biệt: các cài đặt của nó nằm trực tiếp trên Tác nhân, vì vậy tên các trường ở đây giống với tên bạn sẽ gửi tới `PUT /agents/{agentId}`. Điểm cuối này tồn tại như một cách an toàn và tập trung để thay đổi một vài trong số đó. Yêu cầu phải có ít nhất một trường.

| Trường | Mô tả |
|---|---|
| `instructions` | Các hướng dẫn chính điều hướng cách Tác nhân trò chuyện với các liên hệ. |
| `rules` | Các quy tắc cứng mà nó phải luôn tuân theo. |
| `goal` | Kết quả mà nó cần hướng tới trong mỗi cuộc hội thoại. |
| `personality` | Mô tả về giọng điệu và tính cách. |
| `language` | Ngôn ngữ mà Tác nhân sử dụng để trả lời. |
| `ai_speed` | `fast`, `fast_thinker`, `balanced` hoặc `thorough`. |
| `anthropic_model` | `standard`, `economy`, `max` hoặc `mini`. |
| `max_messages` | Số lượng tin nhắn tối đa của Tác nhân trong mỗi cuộc hội thoại. |
| `alert_human_when` | Khi nào Tác nhân nên cảnh báo cho một thành viên trong nhóm là con người. |
| `ai_transparency` | Liệu Tác nhân có tiết lộ rằng nó là AI hay không. |

> **Tên trường ở đây phải là tên thuần túy** — chữ cái, số, dấu gạch dưới và dấu gạch ngang. Các đường dẫn có dấu chấm không được chấp nhận tại điểm cuối này (không giống như `PUT /agents/{agentId}`), vì vậy `bot.goal` sẽ bị từ chối với mã `400`.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/bot-config?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "goal": "Book a viewing within three messages", "ai_speed": "thorough" }'
```

Văn bản dài sẽ được tính vào kích thước cấu hình mà gói dịch vụ của bạn cho phép, vì vậy một tập hợp hướng dẫn quá lớn có thể bị từ chối với mã `400`.

---

## Thiết lập giờ hoạt động

`PUT /agents/{agentId}/active-hours` — khoảng thời gian mà Tác nhân tự động trả lời. Ngoài các khung giờ đó, nó sẽ giữ im lặng.

Gửi một đối tượng `availability` với khóa là ngày trong tuần (từ `monday` đến `sunday`). Mỗi ngày nhận một khung thời gian duy nhất hoặc một danh sách các khung thời gian, theo định dạng `HH:MM` 24 giờ. Những ngày bạn bỏ qua sẽ giữ nguyên cài đặt cũ, và bất kỳ khóa nào không phải là ngày trong tuần đều sẽ bị từ chối — vì vậy lỗi đánh máy sẽ không dẫn đến việc không thực hiện gì cả.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active-hours?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "availability": {
      "monday": { "start_time": "09:00", "end_time": "17:00" },
      "tuesday": [
        { "start_time": "09:00", "end_time": "12:00" },
        { "start_time": "13:00", "end_time": "17:00" }
      ]
    }
  }'
```

**Phản hồi** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Khóa ngày trong tuần không hợp lệ sẽ trả về `400`: `"Invalid availability keys: funday. Allowed keys: monday through sunday."`

---

## Tạm dừng hoặc tiếp tục Tác nhân

`PATCH /agents/{agentId}/active` — bật hoặc tắt Agent. Một Agent bị tạm dừng sẽ giữ nguyên mọi cấu hình nhưng ngừng phản hồi ngay lập tức; việc tiếp tục hoạt động sẽ có hiệu lực ngay lập tức.

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "active": false }'
```

```javascript
await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active", {
  method: "PATCH",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ active: false }),
});
```

**Phản hồi** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "active": false }
```

`active` phải là một giá trị boolean thực — bất kỳ giá trị nào khác sẽ trả về `400` kèm theo `"active (boolean) is required"`.

---

## Sao chép một Agent

`POST /agents/{agentId}/duplicate` — tạo một bản sao với cấu hình được giữ nguyên. Bản sao sẽ không gửi bất kỳ nội dung nào cho đến khi bạn trỏ một kênh hoặc một Điểm truy cập (Entry Point) vào nó.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/duplicate?apiKey=YOUR_API_KEY"
```

**Phản hồi** (`201`)

```json
{ "success": true, "agent_id": "ag9WsX3cRfV6tGyH", "source_agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Một bản sao được tính vào hạn mức Agent trong gói của bạn giống hệt như khi tạo mới từ đầu, vì vậy yêu cầu sẽ bị từ chối với `403` khi tài khoản đã đạt giới hạn.

---

## Xóa một Agent

`DELETE /agents/{agentId}`

Việc xóa sẽ bị từ chối khi Agent vẫn đang được gắn với một thành phần nào đó mà nếu thiếu nó sẽ ngừng hoạt động — ví dụ như một chương trình phát sóng, một Điểm truy cập, hoặc (trên các tài khoản cũ) một chiến dịch. Phản hồi sẽ liệt kê những gì đang giữ Agent đó để bạn có thể tách chúng ra trước rồi thử lại.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY"
```

**Phản hồi** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

**Đã chặn** (`409`)

```json
{
  "success": false,
  "error": "Agent is still attached to one or more broadcast(s). Detach it first.",
  "blocking_campaign_ids": [],
  "blocking_broadcast_ids": ["bc5TgYhUj8IkOlPm"],
  "blocking_entry_point_ids": []
}
```

---

## Bản nháp: xem lại các thay đổi trước khi chúng được áp dụng

Các chỉnh sửa được thực hiện trong trình soạn thảo và bất kỳ nội dung viết lại nào được tạo bởi [Tối ưu hóa bằng AI](#optimize-an-agent-with-ai) sẽ được lưu dưới dạng **bản nháp chưa xuất bản** cho đến khi bạn xuất bản chúng. Agent đang hoạt động sẽ tiếp tục phản hồi với cấu hình hiện tại của nó cho đến lúc đó.

### Xuất bản bản nháp

`POST /agents/{agentId}/publish-draft` — chuyển bản nháp sang cấu hình đang hoạt động và xóa bản nháp trong cùng một bước.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/publish-draft?apiKey=YOUR_API_KEY"
```

**Phản hồi** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "published_keys": ["instructions", "goal"] }
```

`published_keys` liệt kê các cài đặt đã được chuyển từ bản nháp sang Agent đang hoạt động, để bạn có thể hiển thị những gì đã thay đổi.

> **Hãy kiểm tra xem bản nháp có tồn tại hay không trước khi gọi lệnh này.** Việc xuất bản một Agent không có bản nháp là một lệnh gọi không được hỗ trợ và hiện tại sẽ trả về `500` với một thông báo chung, không phải thông báo cụ thể. Để hủy bỏ bản nháp thay vì xuất bản, hãy sử dụng lệnh loại bỏ (discard) bên dưới.

### Hủy bản nháp

`POST /agents/{agentId}/discard-draft` — loại bỏ bản nháp và giữ nguyên cấu hình hiện tại. Có thể gọi an toàn khi không có bản nháp nào; sẽ không có gì xảy ra.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/discard-draft?apiKey=YOUR_API_KEY"
```

---

## Tối ưu hóa Tác nhân bằng AI

`POST /agents/{agentId}/optimize` — viết lại cấu hình của Tác nhân dựa trên phản hồi của bạn ("nó cứ đưa ra các ưu đãi", "câu trả lời quá dài") và lưu bản viết lại **dưới dạng bản nháp** thay vì áp dụng trực tiếp.

Gửi `user_feedback` (một chỉ dẫn đơn giản) hoặc, khi phản hồi về một câu trả lời không tốt cụ thể, hãy gửi `thumbs_down_feedback` cùng với `thumbs_down_message` gây ra vấn đề đó. Ít nhất một trong hai phải chứa văn bản.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/optimize?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "user_feedback": "Keep replies under three sentences." }'
```

**Phản hồi** (`202`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Công việc chạy trong nền và lệnh gọi sẽ trả về ngay lập tức. Đọc Tác nhân bằng `GET /agents/{agentId}` và theo dõi `optimize_run.status`; khi trạng thái trở về `Draft`, bản viết lại sẽ nằm trong phần bản nháp của Tác nhân. Hãy xem xét nó, sau đó xuất bản hoặc hủy bỏ.

Mỗi Tác nhân chỉ được thực hiện một lần chạy tại một thời điểm — lệnh gọi thứ hai trong khi lệnh thứ nhất đang chạy sẽ trả về `409`. Việc này sử dụng tín dụng AI.

---

## Quy tắc gắn thẻ

Quy tắc gắn thẻ bao gồm một thẻ và mô tả về thời điểm áp dụng thẻ đó. Trong cuộc trò chuyện, Tác nhân sẽ đọc mô tả đó và gắn thẻ cho liên hệ khi phù hợp, đây là cách các quy trình tự động dựa trên thẻ được kích hoạt.

**Đối tượng quy tắc**

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `name` | Có | Thẻ cần áp dụng, ví dụ `hot-lead`. |
| `description` | Không | Thời điểm Tác nhân nên áp dụng thẻ, được viết dưới dạng chỉ dẫn mà nó tuân theo. |
| `webhook` | Không | URL được gọi khi Tác nhân áp dụng thẻ này. |
| `ai_can_remove` | Không | Liệu Tác nhân có thể gỡ thẻ đó ra hay không. Mặc định là `false`. |
| `tag_id` | Không | Id của thẻ hiện có trên tài khoản của bạn để liên kết quy tắc. Nếu không có, quy tắc sẽ liên kết với thẻ có cùng tên, tạo mới nếu chưa tồn tại — vì vậy mọi quy tắc đều có thể được truy cập bằng id thẻ sau đó. |

### Thêm quy tắc gắn thẻ

`POST /agents/{agentId}/tags`

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tag": {
      "name": "hot-lead",
      "description": "Apply when the contact asks about pricing or wants to book a call.",
      "ai_can_remove": false
    }
  }'
```

**Phản hồi** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "tag": { "name": "hot-lead", "...": "..." } }
```

### Thay thế quy tắc gắn thẻ

`PUT /agents/{agentId}/tags/{tagId}` — quy tắc được tìm thấy theo id thẻ trong đường dẫn và **được thay thế toàn bộ**, không phải hợp nhất, vì vậy hãy gửi toàn bộ quy tắc thay vì chỉ phần bạn đang thay đổi. Thẻ mà nó trỏ tới vẫn được giữ nguyên ngay cả khi bạn bỏ qua `tag_id`, vì vậy một chỉnh sửa không thể tách quy tắc khỏi thẻ của nó.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/tg8YuIoP2aSdF3gH?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tag": { "name": "hot-lead", "description": "Apply only when the contact asks to book a call." } }'
```

### Xóa quy tắc gắn thẻ

`DELETE /agents/{agentId}/tags/{tagId}` — Tác nhân ngừng áp dụng thẻ đó. Bản thân thẻ và bất kỳ liên hệ nào đã mang thẻ đó đều không bị ảnh hưởng.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/tg8YuIoP2aSdF3gH?apiKey=YOUR_API_KEY"
```

Cả hai điểm cuối đều trả về `404` khi Tác nhân không tồn tại **hoặc** khi nó không có quy tắc nào cho thẻ đó.

### Tạo tập hợp thẻ bằng AI

`POST /agents/{agentId}/tags/generate` — thiết kế toàn bộ tập hợp các quy tắc (tên thẻ và cách diễn đạt "áp dụng khi…" đằng sau mỗi quy tắc) bằng cách đọc các hướng dẫn và mục tiêu của chính Tác nhân.

| Trường | Mô tả |
|---|---|
| `mode` | `merge` (mặc định) giữ lại các quy tắc đã có trên Tác nhân và thêm vào đó. `replace` thiết kế tập hợp từ đầu. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/generate?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mode": "merge" }'
```

**Phản hồi** (`202`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "mode": "merge" }
```

Công việc chạy trong nền. Hãy đọc phần Agent và theo dõi `tag_generation.status`; các quy tắc sẽ nằm trong `tags` của Agent. Mỗi Agent chỉ chạy một tác vụ tại một thời điểm (nếu không sẽ gặp `409`) và tác vụ này sẽ sử dụng tín dụng AI.

---

## Nguồn kiến thức

Nguồn kiến thức là các trang và tài liệu mà nền tảng đã đọc cho bạn. Việc đính kèm một nguồn vào Agent cho phép nó trả lời dựa trên nội dung đó.

**Nguồn gốc của id nguồn.** Thêm nội dung bằng các endpoint cơ sở kiến thức — `POST /kb-sources/url` cho một trang, `POST /kb-sources/file` cho một tài liệu, `POST /kb-sources/bulk-import` cho toàn bộ trang web. Các endpoint này trả về một `source_id` mà bạn cần thăm dò bằng `GET /kb-sources/{sourceId}` cho đến khi nó sẵn sàng. `POST /kb-sources/url` cũng chấp nhận `autoLinkToAgentId`, giúp đính kèm nguồn vào Agent ngay khi quá trình nhập hoàn tất, vì vậy bạn có thể bỏ qua lệnh gọi đính kèm bên dưới.

### Đính kèm nguồn kiến thức

`POST /agents/{agentId}/kb-sources` — gửi `kb_source_ids` kèm theo danh sách để đính kèm toàn bộ tập hợp trong một lệnh gọi (điều bạn muốn sau khi thu thập dữ liệu trang web), hoặc `kb_source_id` cho một nguồn duy nhất. Chỉ gửi một trong hai. Việc đính kèm một thứ đã được đính kèm sẽ không thay đổi gì cả.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/kb-sources?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kb_source_ids": ["kb2QwErTyUi9OpAs", "kb6ZxCvBnM4kLjHg"] }'
```

**Phản hồi** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "kb_source_id": "kb2QwErTyUi9OpAs",
  "kb_source_ids": ["kb2QwErTyUi9OpAs", "kb6ZxCvBnM4kLjHg"]
}
```

### Gỡ nguồn kiến thức

`DELETE /agents/{agentId}/kb-sources/{kbSourceId}` cho một mục, hoặc `POST /agents/{agentId}/kb-sources/bulk-remove` với `kb_source_ids` cho nhiều mục. Việc xóa hàng loạt là một `POST` vì danh sách các id được truyền trong phần thân yêu cầu.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/kb-sources/bulk-remove?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kb_source_ids": ["kb2QwErTyUi9OpAs"] }'
```

Bản thân các nguồn không bị xóa và vẫn khả dụng cho các Tác nhân khác của bạn. Việc tách một thứ gì đó không được đính kèm sẽ không thay đổi bất cứ điều gì.

### Câu hỏi thường gặp (FAQs)

Các FAQ được quản lý trên các điểm cuối riêng và được liên kết với một Tác nhân từ đó: `POST /faqs/{faqId}/link` với `{ "agent_id": "ag7HkQ2ZpLxR3mNb" }`, và `POST /faqs/{faqId}/unlink` để gỡ bỏ nó. Một FAQ có thể được chia sẻ bởi bất kỳ số lượng Tác nhân nào. Xem [API FAQ](faqs.md).

> Một FAQ chỉ được sử dụng bởi các Tác nhân mà nó được liên kết — việc tạo ra một FAQ là chưa đủ.

---

## Công cụ

### Hàm tùy chỉnh

`POST /agents/{agentId}/custom-functions` cho phép Tác nhân gọi một trong các hàm tùy chỉnh của bạn trong khi trò chuyện. Chỉ các hàm thuộc cùng một tài khoản mới có thể được đính kèm, và việc đính kèm một hàm đã được đính kèm sẽ không thay đổi bất cứ điều gì.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/custom-functions?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "custom_function_id": "cf7Hk2ZpLxR3mNbV" }'
```

`DELETE /agents/{agentId}/custom-functions/{customFunctionId}` sẽ tách nó ra. Bản thân hàm không bị xóa và vẫn khả dụng cho các Tác nhân khác của bạn.

Quản lý chính các hàm trên `/custom-functions` — xem [Hàm tùy chỉnh](../ai-automation/custom-functions.md) để biết chúng là gì.

### Máy chủ MCP

Máy chủ MCP là một gói công cụ có sẵn mà Tác nhân của bạn có thể tự khám phá và gọi — xem [Kết nối Máy chủ MCP với Bot của bạn](../ai-automation/mcp-servers.md). Các máy chủ được đăng ký một lần trên tài khoản, sau đó được đính kèm vào bất kỳ Tác nhân nào cần sử dụng chúng.

> Các máy chủ MCP cần tính năng **hàm tùy chỉnh** trong gói của bạn. Nếu không có tính năng này, các điểm cuối `/mcp-servers` ở cấp tài khoản sẽ trả về `403`. Việc đính kèm một máy chủ đã đăng ký vào một Tác nhân không bị giới hạn.

#### Đăng ký máy chủ

`POST /mcp-servers`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `name` | Có | Nhãn cho máy chủ. |
| `url` | Có | Địa chỉ của máy chủ. Phải truy cập được qua internet công cộng. |
| `auth_type` | Không | `header` (mặc định) cho tiêu đề xác thực tĩnh, hoặc `oauth2`. |
| `auth_header_name` | Không | Tiêu đề để gửi thông tin xác thực. Mặc định là `Authorization`. |
| `auth_header_value` | Không | Bản thân thông tin xác thực. Không bao giờ được trả về trong bất kỳ phản hồi nào. |
| `enabled` | Không | Liệu máy chủ có khả dụng cho các Tác nhân (Agents) hay không. Mặc định là `true`. |
| `enabled_tools` | Không | Danh sách cho phép các tên công cụ. `null` có nghĩa là mọi công cụ mà máy chủ cung cấp đều được bật. |
| `tool_policies` | Không | Các giới hạn cho mỗi công cụ, được khóa theo tên công cụ — tần suất một công cụ có thể kích hoạt, bộ nhớ đệm kết quả và ghi đè chỉ đọc. Truyền `null` để xóa tất cả. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/mcp-servers?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Inventory",
    "url": "https://tools.example.com/mcp",
    "auth_header_value": "Bearer sk_live_xxx"
  }'
```

**Phản hồi** (`201`)

```json
{
  "success": true,
  "server_id": "ms4TgBnH7yUj2kLp",
  "tools": [{ "name": "check_stock", "description": "Look up stock for a SKU." }],
  "last_error": null,
  "server": { "server_id": "ms4TgBnH7yUj2kLp", "name": "Inventory", "...": "..." }
}
```

Khi lưu, nền tảng sẽ kết nối với máy chủ và lưu vào bộ nhớ đệm danh sách các công cụ mà nó cung cấp. **Một máy chủ không thể kết nối vẫn được lưu**, với lý do nằm trong `last_error` và danh sách công cụ trống — vì vậy bạn có thể đăng ký trước và khắc phục kết nối sau.

Một `auth_type` là `oauth2` sẽ lưu đăng ký với `oauth_connected: false` và không có công cụ nào: chưa có mã thông báo (token). Việc ủy quyền cho máy chủ OAuth cần đăng nhập qua trình duyệt và được thực hiện từ bảng điều khiển, không phải qua API.

#### Liệt kê, cập nhật và xóa máy chủ

- `GET /mcp-servers` — mọi máy chủ đã đăng ký, mới nhất trước, trong `servers`.
- `PUT /mcp-servers/{serverId}` — chỉ gửi những gì bạn muốn thay đổi. Việc thay đổi URL hoặc các trường xác thực sẽ kiểm tra lại kết nối và làm mới danh sách công cụ đã lưu trong bộ nhớ đệm.
- `DELETE /mcp-servers/{serverId}` — xóa đăng ký và hủy liên kết khỏi mọi Tác nhân và chiến dịch đã bật nó.

```bash
curl "https://api.youraiconnector.com/v1/mcp-servers?apiKey=YOUR_API_KEY"
```

**Thông tin bí mật không bao giờ được trả về.** Các phản hồi mang theo `auth_header_value_set` (một cờ `true`/`false` cho biết giá trị đã được lưu trữ) thay vì thông tin xác thực, và các mã thông báo OAuth cùng bí mật khách hàng vẫn nằm ở phía máy chủ. Mọi thứ khác đều được trả về: `name`, `url`, `enabled`, `auth_type`, `auth_header_name`, `tools`, `enabled_tools`, `tool_policies`, `oauth_connected`, `tools_cached_at`, `last_connected_at`, `last_error`, `created_at`, `updated_at`.

#### Kiểm tra kết nối

`POST /mcp-servers/test-connection` — kết nối tới một máy chủ và liệt kê các công cụ của nó. Có hai cách để gọi lệnh này:

- với `server_id` — kiểm tra cấu hình **đã lưu** và làm mới danh sách công cụ được lưu trong bộ nhớ đệm;
- với `url` nội dòng (cộng với `auth_header_name` / `auth_header_value`) — một bài kiểm tra trước khi lưu mà không lưu trữ bất kỳ thứ gì.

```bash
curl -X POST "https://api.youraiconnector.com/v1/mcp-servers/test-connection?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://tools.example.com/mcp", "auth_header_value": "Bearer sk_live_xxx" }'
```

**Phản hồi** (`200`)

```json
{
  "success": true,
  "server_name": "Inventory tools",
  "tools": [{ "name": "check_stock", "description": "Look up stock for a SKU." }]
}
```

Lỗi kết nối **không phải** là lỗi HTTP — bạn sẽ nhận được một `200` với `success: false` và một `error` mô tả những gì đã xảy ra, vì vậy bạn có thể hiển thị nó bên cạnh trường mà người vận hành đang chỉnh sửa.

#### Gắn máy chủ vào một Tác nhân (Agent)

Việc đăng ký một máy chủ không cấp quyền truy cập cho bất kỳ Tác nhân nào vào máy chủ đó. Hãy gắn nó:

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/mcp-servers?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mcp_server_id": "ms4TgBnH7yUj2kLp" }'
```

**Phản hồi** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "mcp_server_id": "ms4TgBnH7yUj2kLp" }
```

`DELETE /agents/{agentId}/mcp-servers/{mcpServerId}` sẽ tách nó ra một lần nữa. Bản thân máy chủ không bị xóa và vẫn khả dụng cho các Tác nhân khác của bạn. Việc gắn hoặc tách một thứ gì đó đã ở trạng thái đó sẽ không thay đổi bất cứ điều gì.

---

## Thư viện phương tiện

Thư viện phương tiện lưu trữ các tệp mà một Tác nhân có thể gửi trong cuộc trò chuyện — menu, bảng giá, ảnh sản phẩm. Một Tác nhân có thể lưu giữ tối đa **50 mục**.

### Liệt kê phương tiện

`GET /agents/{agentId}/media-library`

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library?apiKey=YOUR_API_KEY"
```

**Phản hồi** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "media_items": [
    {
      "id": "mi4RtY7uIoP1aSdF",
      "item_id": "mi4RtY7uIoP1aSdF",
      "media_home": "agent",
      "title": "Spring menu",
      "description": "Send when someone asks what is on the menu.",
      "ai_description": "A one-page menu listing seasonal dishes and prices.",
      "type": "document",
      "media_content_type": "application/pdf",
      "media_url": "https://storage.googleapis.com/...",
      "max_sends_per_conversation": 1,
      "created_at": 1700000000000
    }
  ]
}
```

Các mục được lưu trữ trên Tác nhân (Agent) sẽ xuất hiện trước, sau đó là các mục cũ hơn vẫn còn được lưu trữ trên chiến dịch mà Tác nhân đó được tạo ra; `media_home` (`agent` hoặc `campaign`) cho biết mục nào thuộc nhóm nào. Trong mỗi nhóm, mục mới nhất sẽ được hiển thị trước.

> **`media_url` hết hạn sau 7 ngày.** Đây là liên kết tải xuống được tạo khi tệp được tải lên — hãy coi liên kết cũ là đã hết hạn thay vì bị hỏng, và đọc lại danh sách để nhận liên kết mới.

### Tải lên phương tiện

`POST /agents/{agentId}/media-library` — tệp được tải lên nội dòng dưới dạng base64, tối đa **10 MB**. Lệnh gọi sẽ trả về sau khi tệp được lưu trữ, vì vậy hãy cho phép thời gian chờ lâu hơn một chút so với yêu cầu thông thường. Lưu ý rằng phần thân này sử dụng tên trường theo kiểu camelCase.

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `base64Data` | Có | Nội dung tệp, được mã hóa base64, không có tiền tố data-URL. |
| `mimeType` | Có | Loại MIME của tệp. |
| `fileName` | Có | Tên tệp gốc, được sử dụng để đặt tên cho tệp đã lưu trữ. |
| `title` | Không | Nhãn ngắn hiển thị trong thư viện. |
| `description` | Không | Hướng dẫn "khi nào Tác nhân nên gửi tệp này". |
| `sendMessage` | Không | Cách diễn đạt ưu tiên mà Tác nhân sử dụng khi gửi mục này. Được cắt ngắn còn 500 ký tự. |
| `maxSendsPerConversation` | Không | Số lần tệp có thể được gửi cho cùng một liên hệ trong một cuộc trò chuyện. Mặc định là `1`. |
| `sendAsVoiceNote` | Không | Chỉ dành cho tệp âm thanh — lưu trữ tệp dưới dạng tin nhắn thoại WhatsApp. Bị bỏ qua đối với các loại tệp khác. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "base64Data": "JVBERi0xLjQKJcfs...",
    "mimeType": "application/pdf",
    "fileName": "spring-menu.pdf",
    "title": "Spring menu",
    "description": "Send when someone asks what is on the menu.",
    "maxSendsPerConversation": 1
  }'
```

Hai việc sẽ tự động diễn ra: ảnh GIF động được chuyển đổi thành video để có thể phát trên mọi kênh, và nền tảng sẽ viết một bản tóm tắt ngắn gọn về nội dung thực sự có trong tệp để Tác nhân biết khi nào tệp đó phù hợp.

Mã `400` bao gồm các trường bị thiếu, loại tệp không được hỗ trợ, tệp trống hoặc quá lớn và việc đạt giới hạn 50 mục. Mã `403` có nghĩa là thư viện phương tiện đã bị tắt đối với tài khoản này.

### Cập nhật mục phương tiện

`PATCH /agents/{agentId}/media-library/{itemId}` — chỉ dành cho siêu dữ liệu. Bản thân tệp không thể thay thế được; hãy tải lên mục mới và xóa mục cũ. Phần thân này sử dụng kiểu snake_case: `title`, `description`, `send_message`, `max_sends_per_conversation` (một số nguyên không âm, hoặc `null` để xóa giới hạn).

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library/mi4RtY7uIoP1aSdF?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Summer menu", "max_sends_per_conversation": 2 }'
```

**Phản hồi** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "item_id": "mi4RtY7uIoP1aSdF",
  "campaign_id": "",
  "media_home": "agent"
}
```

### Xóa mục phương tiện

`DELETE /agents/{agentId}/media-library/{itemId}` — xóa mục và tệp đã lưu trữ của nó. Việc xóa một mục đã không còn tồn tại vẫn thành công và báo cáo `deleted: false`, vì vậy lệnh gọi này an toàn để thử lại.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library/mi4RtY7uIoP1aSdF?apiKey=YOUR_API_KEY"
```

---

## Tạo tin nhắn theo dõi

`POST /agents/{agentId}/template-generation` — tự động viết các tin nhắn theo dõi của Tác nhân cho bạn (các lời nhắc mà Tác nhân gửi khi cuộc trò chuyện trở nên im ắng), dựa trên mục đích của Tác nhân đó.

| Trường | Mô tả |
|---|---|
| `type` | `all` (mặc định) ghi lại toàn bộ tập hợp. `cold_only` chỉ ghi lại các tin nhắn cho những liên hệ chưa từng phản hồi. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/template-generation?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "all" }'
```

Có hai cách để nhận kết quả này, và trường `target` sẽ cho bạn biết đó là cách nào:

- **`target: "agent"` với `200`** — các tin nhắn đã được ghi lại trong cuộc gọi và kết quả nằm trong `data`. Đọc lại chúng từ `follow_up_config` của Tác nhân. Đây là trường hợp thông thường.
- **`target: "campaign"` với `202`** — công việc đã được xếp hàng chờ cho chiến dịch có tên trong `campaign_id`. Hãy theo dõi `template_generation_status` của chiến dịch đó cho đến khi hoàn tất.

`cold_only` cần một chiến dịch gửi đi và sẽ bị từ chối với `409` (`reason: "cold_only_requires_campaign"`) trên một Tác nhân không có chiến dịch nào. `403` nghĩa là tính năng tự động theo dõi không được bật cho tài khoản. Tính năng này sử dụng tín dụng AI, và `400` với `"Insufficient credits."` nghĩa là tài khoản đã hết tín dụng.

---

## Định tuyến cuộc hội thoại đến một Tác nhân

Một Tác nhân chỉ trả lời các cuộc hội thoại mà **Điểm truy cập** gửi đến. Cho đến khi một kênh có Điểm truy cập, tin nhắn đầu tiên từ một người mà bạn chưa từng trò chuyện vẫn được lưu trữ, nhưng không có gì tiếp nhận nó và không có trợ lý nào trả lời.

| Bạn muốn làm gì | Gọi |
|---|---|
| Đặt một Tác nhân làm người trả lời cho toàn bộ kênh | `PUT /entry-points/channel-defaults` với `{ "channel": "instagram", "agent_id": "AGENT_ID" }` |
| Thêm một quy tắc hẹp hơn (từ khóa, bình luận, người theo dõi mới) | `POST /agents/{agentId}/entry-points` |
| Xem các quy tắc trỏ đến một Tác nhân | `GET /agents/{agentId}/entry-points` |
| Để một kênh không có ai trả lời | `DELETE /entry-points/channel-defaults?channel=instagram` |

### Liệt kê các Điểm truy cập của Tác nhân

`GET /agents/{agentId}/entry-points` — các quy tắc định tuyến gửi cuộc hội thoại đến Tác nhân này, quy tắc mới nhất hiển thị trước. Cả quy tắc hiện tại và quy tắc đã ngừng hoạt động đều được trả về; quy tắc đã ngừng hoạt động sẽ có `enabled: false`.

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/entry-points?apiKey=YOUR_API_KEY"
```

Đối với các mặc định kênh của toàn bộ tài khoản, bao gồm cả kênh được cố tình đặt là không có ai trả lời, hãy đọc `GET /entry-points/channel-defaults` thay thế.

### Tạo Điểm truy cập

`POST /agents/{agentId}/entry-points` — Tác nhân trong đường dẫn luôn được ưu tiên, vì vậy không bao giờ có thể tạo quy tắc cho một Tác nhân khác với Tác nhân trong URL.

| `type` | Chức năng |
|---|---|
| `channel_default` | Tác nhân trả lời mọi liên hệ mới trên các kênh được liệt kê. Hãy ưu tiên `PUT /entry-points/channel-defaults` cho việc này — nó sẽ tự động ngừng hoạt động của người trả lời trước đó cho bạn, điều mà việc tạo mặc định thứ hai ở đây không làm được. |
| `keyword` | Tác nhân tiếp quản khi tin nhắn đầu tiên chứa một trong các `match_config.keywords`. Cần ít nhất một từ khóa. |
| `instagram_comment` / `facebook_comment` | Tác nhân trả lời các bình luận trên bài đăng của bạn. Kênh khớp phải được liệt kê trong `channels`. |
| `instagram_follower` | Tác nhân chào mừng những người theo dõi mới. |

`channels` là bắt buộc và cho biết các kênh mà quy tắc áp dụng — ví dụ: `whatsapp`, `whatsapp_web`, `instagram`, `messenger`, `telegram`, `sms`, `email`, `chat_widget` hoặc `custom_channel`. Các quy tắc mới được bật trừ khi bạn chỉ định khác.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/entry-points?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "keyword",
    "channels": ["whatsapp", "instagram"],
    "match_config": { "keywords": ["pricing", "quote"] }
  }'
```

**Phản hồi** (`201`)

```json
{ "success": true, "entry_point_id": "ep3KmQ8vTzXr5nWd" }
```

**Quy tắc nào thắng khi có nhiều quy tắc có thể áp dụng:** một cuộc hội thoại đang diễn ra hoặc một phân công thủ công sẽ giữ lại Tác nhân mà nó đã có; nếu không, các quy tắc từ khóa sẽ thắng quy tắc bình luận, quy tắc bình luận thắng quy tắc người theo dõi, và mặc định kênh là lựa chọn cuối cùng. Việc các quy tắc này đã quyết định bất cứ điều gì trên tài khoản hay chưa được báo cáo bởi `GET /entry-points/routing-status`.

Đây là phiên bản rút gọn. Hướng dẫn [Entry Points API](entry-points.md) bao gồm toàn bộ các quy tắc về thứ bậc, bình luận và người theo dõi, mỗi số WhatsApp chỉ được dùng một Agent, cũng như cách thay đổi hoặc xóa quy tắc. Xem [Entry Points](../ai-agents/entry-points.md) để biết về khái niệm này và [Channels API](channels.md) để kết nối chính kênh đó.

---

## Lỗi API Tác nhân AI

Các endpoint của Tác nhân trả về cấu trúc lỗi tiêu chuẩn:

```json
{
  "success": false,
  "error": "Agent not found"
}
```

| Trạng thái | Khi nào lỗi xảy ra trên một endpoint Tác nhân |
|---|---|
| `400` | Một trường bắt buộc bị thiếu hoặc không hợp lệ — phần thân cập nhật trống, giá trị nằm ngoài danh sách cho phép (`ai_speed`, `anthropic_model`, `booking_provider`, `mode`, `type`), khóa không phải ngày trong tuần trong `availability`, tên trường có dấu chấm trong `bot-config`, hoặc id bị định dạng sai trong đường dẫn. |
| `403` | Tài khoản không được phép sử dụng cài đặt bạn đã gửi, bạn đã đạt giới hạn Tác nhân của gói dịch vụ, hoặc một tính năng mà endpoint này cần (thư viện phương tiện, theo dõi, hàm tùy chỉnh cho máy chủ MCP) đang bị tắt. Một thay đổi vượt quá kích thước cấu hình mà gói của bạn cho phép sẽ bị từ chối với `400`. |
| `404` | Tác nhân, quy tắc thẻ, mục phương tiện hoặc máy chủ MCP không được tìm thấy — hoặc là nó không tồn tại hoặc nó thuộc về một tài khoản khác. |
| `409` | Có thứ gì đó đang chạy hoặc gây cản trở: một quá trình tối ưu hóa hoặc tạo thẻ đang chạy, Tác nhân vẫn đang được gắn vào một chương trình phát sóng, Điểm truy cập hoặc chiến dịch, hoặc `cold_only` đã được yêu cầu mà không có chiến dịch gửi đi. |

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](errors-and-pagination.md).

> **Lưu ý về trình khám phá.** Các endpoint `/agents` nằm trong đặc tả OpenAPI đã xuất bản, vì vậy bạn có thể duyệt qua các trường chính xác của chúng và chạy các yêu cầu trực tiếp trong [Tài liệu tham khảo API](reference.md). Các endpoint `/mcp-servers` ở cấp tài khoản cũng nằm trong đặc tả, vì vậy bạn cũng có thể khám phá chúng ở đó.


---

## Liên quan

- [Tác nhân AI](../ai-agents/ai-agents.md) — Tác nhân là gì, giải thích bằng ngôn ngữ đơn giản.
- [Điểm truy cập](../ai-agents/entry-points.md) — cách các cuộc hội thoại được định tuyến đến một Tác nhân.
- [API Câu hỏi thường gặp](faqs.md) — xây dựng và liên kết kiến thức mà Tác nhân của bạn dùng để trả lời.
- [API Kênh](channels.md) — kết nối các kênh mà một Tác nhân phản hồi.
- [Kết nối Máy chủ MCP với Bot của bạn](../ai-automation/mcp-servers.md) · [Hàm tùy chỉnh](../ai-automation/custom-functions.md)
- [Tài liệu tham khảo API](reference.md) — trình khám phá endpoint tương tác đầy đủ.
