
# API Mẫu tin nhắn WhatsApp

Các mẫu tin nhắn WhatsApp là những tin nhắn được soạn sẵn đã được phê duyệt để gửi bên ngoài cửa sổ hội thoại 24 giờ thông thường — ví dụ như tin nhắn chào mừng, lời nhắc cuộc hẹn hoặc thông báo nhắc nhở để tương tác lại. API này cho phép bạn liệt kê, tạo, chỉnh sửa, gửi, kiểm tra, xóa và gửi các mẫu tin nhắn theo lập trình.

Tất cả các đường dẫn bên dưới đều tương đối so với URL cơ sở của API:

```
https://api.youraiconnector.com/v1
```

Mọi yêu cầu đều phải được xác thực. Xem phần [Xác thực](authentication.md) để biết bốn phương thức được chấp nhận. Các ví dụ trên trang này sử dụng tiêu đề `X-API-Key` (và một dạng tham số truy vấn cho cURL).

::: note
**Lưu ý:** Các mẫu (template) hoạt động trên kênh WhatsApp Business API, vì vậy phần này của API yêu cầu cả quyền truy cập API và gói dịch vụ bao gồm các kênh WhatsApp. Nếu không có các yếu tố này, các yêu cầu sẽ bị từ chối với mã `403`.
:::


---

## Làm việc với các tài khoản phụ (đại lý)


---

## Các trạng thái phê duyệt

Vì các tin nhắn gửi bên ngoài một cuộc hội thoại đang mở phải được WhatsApp xem xét trước, mỗi mẫu tin nhắn đều mang một `status` phê duyệt:

| Trạng thái | Ý nghĩa |
|---|---|
| `draft` | Đã tạo hoặc đã lưu nhưng chưa gửi để xem xét. Bạn vẫn có thể chỉnh sửa mẫu này. |
| `received` | Đã gửi và được chấp nhận vào hàng đợi xem xét. |
| `pending` | Đang được xem xét. |
| `approved` | Đã được phê duyệt để gửi. |
| `rejected` | Bị từ chối. Trường `rejection_reason` giải thích lý do; hãy sửa lại rồi gửi lại. |

Chỉ các mẫu tin nhắn `draft` và `rejected` mới có thể được chỉnh sửa hoặc gửi (lại). Khi một mẫu tin nhắn đã ở trạng thái `approved`, nó sẽ bị khóa — hãy tạo một mẫu mới nếu bạn cần thay đổi.

> **Tự động phê duyệt:** Một số kênh không yêu cầu bước xem xét bên ngoài. Các mẫu tin nhắn được tạo hoặc gửi cho một chiến dịch trên các kênh như vậy sẽ được lưu ngay lập tức dưới dạng `approved`, không có ID nội dung (`sid`).

---

## Các mẫu trên tài khoản kết nối Meta

Các điểm cuối này hoạt động theo cùng một cách bất kể tài khoản của bạn đang chạy trên kết nối WhatsApp nào, nhưng những gì xảy ra phía sau chúng lại khác nhau:

- Trên **kết nối WhatsApp được quản lý**, các mẫu được đăng ký với nhà cung cấp dịch vụ nhắn tin và `sid` là ID nội dung của nhà cung cấp (`HXXXXXXXX…`).
- Trên tài khoản có số điện thoại chạy trên **Tài khoản WhatsApp Business riêng** (một trong hai tùy chọn kết nối Meta), các mẫu được tạo và xem xét **trong Tài khoản WhatsApp Business đó** và `sid` là ID mẫu của riêng Meta — một chuỗi số như `"3394843740694756"`. `status` vẫn sử dụng các giá trị trong bảng trên và `rejection_reason` vẫn chứa giải thích của Meta.

Có hai điểm cuối bổ sung cho việc này: một để hỏi bạn đang sử dụng kết nối nào và một để đồng bộ hóa danh sách mẫu của bạn với Tài khoản WhatsApp Business. Các mẫu đã tồn tại trong Tài khoản WhatsApp Business sẽ được nhập vào thư viện của bạn thông qua quá trình đồng bộ hóa, vì vậy `GET /whatsapp-templates` sau đó sẽ liệt kê chúng giống như bất kỳ mẫu nào khác.

### Kiểm tra kết nối mà các mẫu đang chạy trên đó

`GET /whatsapp-templates/provider`

| Trường | Mô tả |
|---|---|
| `provider` | `twilio` khi các mẫu được đăng ký với nhà cung cấp dịch vụ nhắn tin được quản lý, `meta` khi chúng nằm trong Tài khoản WhatsApp Business của riêng bạn. |
| `lane` | Kết nối Meta nào đang được sử dụng — `meta_cloud_api` (ứng dụng Meta của riêng bạn) hoặc `meta_embedded` (kết nối thông qua ứng dụng Meta của chúng tôi). `null` trên kết nối được quản lý. |
| `waba_id` | Tài khoản WhatsApp Business nơi các mẫu được tạo, hoặc `null`. |
| `templates_enabled` | `false` khi kết nối Meta chưa hoàn tất (chưa có Tài khoản WhatsApp Business hoặc mã truy cập được lưu trữ). Việc tạo hoặc gửi mẫu sẽ thất bại với `400` cho đến khi hoàn tất. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/provider?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/provider", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/provider",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "provider": "meta",
  "lane": "meta_cloud_api",
  "waba_id": "2357661648036355",
  "templates_enabled": true
}
```

### Đồng bộ hóa các mẫu từ Meta

Làm mới trạng thái phê duyệt của mọi mẫu nằm trong Tài khoản WhatsApp Business của bạn và nhập bất kỳ mẫu nào đã tồn tại ở đó nhưng chưa có trong thư viện của bạn. Bạn có thể gọi lệnh này bao nhiêu lần tùy thích. Trên kết nối được quản lý, không có gì để đồng bộ hóa, vì vậy lệnh gọi này không thực hiện gì cả và chỉ báo cáo số lượng mẫu bạn có.

`POST /whatsapp-templates/meta-sync`

| Trường | Mô tả |
|---|---|
| `imported` | Các mẫu được tìm thấy trong Tài khoản WhatsApp Business đã được thêm vào thư viện của bạn bởi lệnh gọi này. |
| `updated` | Các mẫu hiện có có trạng thái hoặc chi tiết đã thay đổi. |
| `total` | Các mẫu trong thư viện của bạn sau khi đồng bộ hóa. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/meta-sync",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "provider": "meta",
  "imported": 2,
  "updated": 5,
  "total": 12
}
```

### Giao tiếp trực tiếp với Meta (nâng cao)

Nếu bạn cần một tính năng mà các điểm cuối trên không cung cấp — tiêu đề mẫu, chân trang, nút hoặc một mẫu được xây dựng thủ công hoàn toàn — `/v1/meta-templates` sẽ chuyển yêu cầu của bạn trực tiếp đến API mẫu của Meta mà không lưu trữ bất kỳ thứ gì trong thư viện mẫu của bạn. Nó chỉ hoạt động trên các tài khoản có số điện thoại chạy trên Tài khoản WhatsApp Business của riêng họ; trên kết nối được quản lý, mọi lệnh gọi sẽ trả về `400` yêu cầu bạn kết nối ứng dụng Meta trước.

| Điểm cuối | Chức năng |
|---|---|
| `GET /meta-templates` | Liệt kê các mẫu trên Tài khoản WhatsApp Business của bạn cùng với trạng thái mới nhất của chúng. Thêm `?name=` để lọc theo một tên mẫu chính xác. Trả về `{ "success": true, "templates": [...] }`. |
| `POST /meta-templates` | Tạo một mẫu và gửi nó để Meta xem xét trong một bước. Yêu cầu `name`, `language` và `body` (hoặc một mảng `components` đầy đủ thay vì `body`). Tùy chọn: `variables` (mảng chuỗi), `category` (`MARKETING`, `UTILITY` hoặc `AUTHENTICATION`), `header`, `footer`, `buttons`. Trả về `201` với `{ "success": true, "template": {...} }`. |
| `DELETE /meta-templates/{name}` | Xóa mẫu theo tên Meta của nó — **mọi ngôn ngữ** của mẫu đó. Thêm `?hsm_id=` với ID mẫu của Meta để xóa một ngôn ngữ duy nhất. Trả về `{ "success": true, "name": "..." }`. |

Một mẫu bị Meta từ chối sẽ trả về `400` với giải thích của riêng Meta trong `error`.

---

## Liệt kê các mẫu tin nhắn

Trả về tất cả các mẫu tin nhắn trong tài khoản của bạn, kèm theo bản tóm tắt nhẹ về từng mẫu.

`GET /whatsapp-templates`

**cURL**

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

**JavaScript**

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

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": [
    {
      "id": "template_abc123",
      "name": "welcome_message",
      "status": "approved",
      "language": "en",
      "body": "Hi {{first_name}}, thanks for reaching out!"
    },
    {
      "id": "template_def456",
      "name": "appointment_reminder",
      "status": "pending",
      "language": "en",
      "body": "Hi {{first_name}}, this is a reminder about your appointment."
    }
  ]
}
```

---

## Lấy một mẫu tin nhắn

Trả về thông tin chi tiết đầy đủ của một mẫu đơn, bao gồm các biến, trạng thái và dấu thời gian của mẫu đó.

`GET /whatsapp-templates/{templateId}`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "template": {
    "id": "template_abc123",
    "name": "welcome_message",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "language": "en",
    "variables": ["first_name"],
    "status": "approved",
    "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "type": "general",
    "category": "marketing",
    "rejection_reason": null,
    "campaign_id": "campaign123",
    "date_created": "2026-06-01T10:00:00.000Z",
    "date_updated": "2026-06-02T08:30:00.000Z",
    "submitted_at": "2026-06-01T10:05:00.000Z",
    "approved_at": "2026-06-02T08:30:00.000Z"
  }
}
```

Một mẫu không tồn tại trong tài khoản của bạn sẽ trả về `404` với `{ "success": false, "error": "Template not found" }`.

---

## Tạo mẫu

Tạo một mẫu cho tin nhắn mở đầu của chiến dịch và gửi đi để phê duyệt trong một bước duy nhất.

`POST /whatsapp-templates`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `campaign_id` | Có | Chiến dịch mà mẫu thuộc về. |
| `name` | Có | Tên của mẫu. |
| `language` | Có | Mã ngôn ngữ, ví dụ: `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Có | Nội dung tin nhắn, tối đa 1024 ký tự. |
| `variables` | Không | Danh sách tên các biến được sử dụng trong nội dung theo thứ tự. |

Các trình giữ chỗ biến có thể được viết là `{{first_name}}`, `{first_name}` hoặc `[first_name]` — tất cả đều được chuẩn hóa về dạng dấu ngoặc nhọn kép.

Kết quả phụ thuộc vào các kênh của chiến dịch:

- **Chiến dịch WhatsApp Business API:** nội dung được gửi đi để WhatsApp xem xét. Phản hồi sẽ bao gồm `campaign_status` (`received` hoặc `pending`) và một `template_sid`.
- **Kênh không có bước xem xét bên ngoài:** mẫu được lưu trữ và tự động phê duyệt (`campaign_status: "approved"`, `template_sid: null`).
- **Không có kênh WhatsApp trong chiến dịch:** không có gì được tạo và `campaign_status` là `not_applicable`.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "campaign123",
    "name": "welcome_message",
    "language": "en",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "variables": ["first_name"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaign_id: "campaign123",
    name: "welcome_message",
    language: "en",
    body: "Hi {{first_name}}, thanks for reaching out!",
    variables: ["first_name"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaign_id": "campaign123",
        "name": "welcome_message",
        "language": "en",
        "body": "Hi {{first_name}}, thanks for reaching out!",
        "variables": ["first_name"],
    },
)
data = res.json()
```

**Phản hồi** (đã gửi để xem xét)

```json
{
  "success": true,
  "campaign_status": "pending",
  "template_sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

---

## Tạo mẫu độc lập

Tạo một mẫu trong thư viện mẫu của bạn mà không gắn nó với tin nhắn mở đầu của chiến dịch. Đây là bước tạo trong vòng đời mà phần còn lại của trang này tuân theo: tạo mẫu tại đây, chỉnh sửa, gửi để xét duyệt, kiểm tra trạng thái và xóa khi bạn không còn cần đến nữa.

`POST /whatsapp-templates/docs`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `name` | Có | Tên của mẫu. |
| `language` | Có | Mã ngôn ngữ, ví dụ `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Có | Nội dung tin nhắn, tối đa 1024 ký tự. |
| `variables` | Không | Danh sách tên biến được sử dụng trong phần thân theo thứ tự. |
| `status` | Không | `draft` (mặc định) lưu mẫu mà không gửi; `submitted` đưa mẫu vào hàng đợi xét duyệt của WhatsApp ngay lập tức. |
| `type` | Không | `general` (mặc định) hoặc `smart_followup`. |
| `category` | Không | `marketing`, `utility`, `authentication`, hoặc `authentication-international`. |
| `campaign_id` | Không | Liên kết mẫu với một trong các chiến dịch của bạn. |

> **Các mẫu xác thực (mã dùng một lần).** WhatsApp không chấp nhận các mẫu xác thực dạng văn bản tự do: nội dung tin nhắn được thiết lập sẵn bởi WhatsApp và mẫu phải có nút "sao chép mã". Khi bạn tạo một mẫu với `category: "authentication"`, chúng tôi sẽ gửi nó dưới dạng cố định đó cho bạn. `body` của bạn được giữ làm bản xem trước hiển thị trong ứng dụng, nhưng văn bản mà liên hệ của bạn nhận được là cách diễn đạt riêng của WhatsApp (mã, lời nhắc bảo mật và ghi chú hết hạn sau 10 phút). Hãy khai báo chính xác một biến, ví dụ `["code"]`, và truyền mã khi bạn gửi (xem trường `variables` trên [Gửi mẫu cho liên hệ](#send-a-template-to-a-contact)). Mã phải ngắn hơn 15 ký tự.

> **Tôi nên sử dụng phương thức tạo nào?** Hãy sử dụng phương thức này khi bạn muốn có một mẫu mà bạn có thể tự chỉnh sửa và gửi. Sử dụng `POST /whatsapp-templates` (ở trên) khi bạn muốn thiết lập tin nhắn mở đầu của chiến dịch — phương thức đó yêu cầu `campaign_id` và ghi trực tiếp vào chiến dịch.

Một mẫu được tạo dưới dạng `submitted` sẽ được gửi để WhatsApp xét duyệt trong nền, vì vậy hãy kiểm tra endpoint trạng thái để biết kết quả thay vì mong đợi kết quả đó trong phản hồi.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/docs?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "welcome_message",
    "language": "en",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "variables": ["first_name"],
    "status": "draft",
    "category": "marketing"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/docs", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "welcome_message",
    language: "en",
    body: "Hi {{first_name}}, thanks for reaching out!",
    variables: ["first_name"],
    status: "draft",
    category: "marketing",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/docs",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "welcome_message",
        "language": "en",
        "body": "Hi {{first_name}}, thanks for reaching out!",
        "variables": ["first_name"],
        "status": "draft",
        "category": "marketing",
    },
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "status": "draft"
}
```

Việc thiếu `name`, `language`, hoặc `body`, ngôn ngữ không được hỗ trợ, `status` không phải là `draft` hoặc `submitted`, `type` hoặc `category` không xác định, hoặc phần thân vượt quá 1024 ký tự sẽ trả về `400` kèm theo `error` giải thích. Một `campaign_id` không thuộc các chiến dịch của bạn sẽ trả về `404`.

---

## Cập nhật mẫu

Chỉnh sửa một mẫu chưa được phê duyệt. Chỉ các mẫu có trạng thái `draft` hoặc `rejected` mới có thể được chỉnh sửa. Cung cấp bất kỳ tổ hợp nào của `name`, `body`, `language` và `variables` — chỉ các trường bạn gửi mới được thay đổi.

`PUT /whatsapp-templates/{templateId}`

> Việc chỉnh sửa **không** gửi lại mẫu để xét duyệt. Hãy sử dụng endpoint gửi sau đó.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi {{first_name}}, here is an update for you.",
    "variables": ["first_name"]
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      body: "Hi {{first_name}}, here is an update for you.",
      variables: ["first_name"],
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "body": "Hi {{first_name}}, here is an update for you.",
        "variables": ["first_name"],
    },
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "template_id": "template_abc123"
}
```

Việc cố gắng chỉnh sửa một mẫu đã `approved` (hoặc không thể chỉnh sửa vì lý do khác), không gửi trường nào hoặc gửi giá trị không hợp lệ sẽ trả về `400` kèm theo `error` giải thích.

---

## Gửi mẫu để phê duyệt

Gửi một mẫu `draft` hoặc `rejected` để xét duyệt. Các mẫu trên kênh không yêu cầu xét duyệt bên ngoài sẽ được phê duyệt ngay lập tức; tất cả các mẫu khác sẽ được gửi đến WhatsApp và `status` được trả về (thường là `received` hoặc `pending`) sẽ được lưu trữ trên mẫu đó.

`POST /whatsapp-templates/{templateId}/submit`

> **Các mẫu tiếp theo** phải khai báo và sử dụng các biến bắt buộc trước khi có thể gửi: một trình giữ chỗ cho tên, cộng với một trình giữ chỗ ngữ cảnh cá nhân cho các mẫu tiếp theo thông minh.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/submit",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "status": "pending",
  "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

---

## Kiểm tra trạng thái phê duyệt

Một endpoint nhẹ để thăm dò trạng thái hiện tại của mẫu. Trạng thái được đọc từ bản ghi đã lưu, vốn được làm mới định kỳ trong nền, vì vậy một phê duyệt hoặc từ chối rất gần đây có thể mất một chút thời gian để hiển thị.

`GET /whatsapp-templates/{templateId}/status`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/status",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "name": "welcome_message",
  "status": "approved",
  "sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "rejection_reason": null,
  "date_updated": "2026-06-02T08:30:00.000Z"
}
```

---

## Xóa mẫu

Xóa bản ghi mẫu khỏi tài khoản của bạn.

`DELETE /whatsapp-templates/{templateId}`

::: warning
**Quan trọng:** Trên kết nối được quản lý, chỉ bản ghi đã lưu mới bị xóa — nội dung mà WhatsApp đã phê duyệt có thể vẫn được đăng ký với nhà cung cấp dịch vụ nhắn tin. Trên tài khoản chạy bằng Tài khoản WhatsApp Business riêng, mẫu cũng sẽ bị xóa khỏi tài khoản đó. Dù bằng cách nào, nếu một chiến dịch vẫn đang sử dụng mẫu này, hãy chuyển chiến dịch đó sang một mẫu khác **trước** khi xóa, nếu không các lượt gửi dựa vào mẫu đó sẽ thất bại.
:::


**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "template_id": "template_abc123",
  "note": "The template record was removed from your account. Content already approved by WhatsApp may remain registered with the messaging provider."
}
```

---

## Gửi mẫu cho một liên hệ

Gửi một mẫu đã được phê duyệt cho một liên hệ, ngay cả khi không có cuộc hội thoại nào đang mở — hành động này sẽ mở lại phiên trò chuyện. Bạn có thể nhắm mục tiêu đến liên hệ bằng `contactId` hoặc bằng `phoneNumber`, và chọn mẫu bằng `whatsappTemplateId` hoặc bằng `templateName`.

`POST /whatsapp-templates/send`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `contactId` | Một trong hai | ID của liên hệ. |
| `phoneNumber` | Một trong hai | Số điện thoại của liên hệ (kèm mã quốc gia, không có khoảng trắng). Được tra cứu hoặc tạo mới nếu cần. |
| `whatsappTemplateId` | Một trong hai | ID của mẫu. |
| `templateName` | Một trong hai | Tên của mẫu, như hiển thị trong ứng dụng. |
| `firstName` | Không | Được sử dụng để điền vào một liên hệ mới được tạo. |
| `lastName` | Không | Được sử dụng để điền vào một liên hệ mới được tạo. |
| `email` | Không | Được sử dụng để điền vào một liên hệ mới được tạo. |
| `variables` | Không | Các giá trị rõ ràng cho các biến của mẫu, được khóa theo tên biến, ví dụ `{ "code": "482913" }`. Giá trị được cung cấp ở đây sẽ ưu tiên hơn các trường của liên hệ cho biến đó; các biến bạn bỏ qua vẫn được điền từ liên hệ như mô tả bên dưới. Đây là cách bạn truyền mã dùng một lần cho một mẫu xác thực. |

Phần thân của mẫu hỗ trợ thay thế biến nâng cao:

- **Các biến cơ bản:** `{{first_name}}`, `{{email}}`, `{{company}}`
- **Giá trị mặc định:** `{{first_name|there}}` hiển thị `there` nếu trường trống
- **Các phép biến đổi:** `{{company|uppercase}}`, `{{name|lowercase}}`, `{{name|capitalize}}`
- **Kết hợp:** `{{company|Your Company|uppercase}}`

> **Tín dụng:** Việc gửi mẫu sẽ tiêu tốn tín dụng. Chi phí chính xác phụ thuộc vào quốc gia của người nhận và danh mục của mẫu.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contactId": "contact123",
    "whatsappTemplateId": "template_abc123"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/send", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contactId: "contact123",
    whatsappTemplateId: "template_abc123",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/send",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "contactId": "contact123",
        "whatsappTemplateId": "template_abc123",
    },
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": "WhatsApp template message sent successfully"
}
```

Yêu cầu thiếu cả định danh liên hệ và cả hai định danh mẫu sẽ trả về `400`. Nếu tài khoản của bạn thiếu thông tin xác thực nhắn tin cần thiết để gửi, phản hồi sẽ là `403`.

---

## Tạo hoặc cập nhật mẫu tin nhắn trực tiếp của chiến dịch

Một cặp endpoint thứ hai cho mẫu tin nhắn mở đầu của chiến dịch, được xác định theo đường dẫn thay vì theo `campaign_id` trong phần nội dung. Đây là những endpoint cần sử dụng cho một chiến dịch đã hoạt động: không giống như [Tạo mẫu tin nhắn](#create-a-template) ở trên, việc cập nhật tại đây cũng sẽ gửi lại các bản nháp tiếp theo của chiến dịch để xét duyệt, nhờ đó mẫu tin nhắn mở đầu và các tin nhắn tiếp theo luôn đồng bộ với nhau.

`POST /whatsapp-templates/campaign/{campaignId}` tạo mẫu tin nhắn mở đầu cho chiến dịch. `PUT /whatsapp-templates/campaign/{campaignId}` chỉnh sửa mẫu đó — chiến dịch phải có sẵn mẫu tin nhắn, nếu không hệ thống sẽ trả về `400`.

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `name` | Có | Tên của mẫu tin nhắn. |
| `language` | Có | Mã ngôn ngữ, ví dụ `en`, `es`, `de`, `pt_BR`, `zh_CN`. |
| `body` | Có | Nội dung tin nhắn, tối đa 1024 ký tự. |
| `variables` | Có | Danh sách tên các biến được sử dụng trong nội dung theo thứ tự. Truyền một mảng trống nếu mẫu tin nhắn không sử dụng biến nào. |

**cURL** (tạo)

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "welcome_message",
    "language": "en",
    "body": "Hi {{first_name}}, thanks for reaching out!",
    "variables": ["first_name"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "welcome_message",
    language: "en",
    body: "Hi {{first_name}}, thanks for reaching out!",
    variables: ["first_name"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/campaign/campaign123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "welcome_message",
        "language": "en",
        "body": "Hi {{first_name}}, thanks for reaching out!",
        "variables": ["first_name"],
    },
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "campaign_status": "pending",
  "template_sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "message": "WhatsApp template created and campaign updated successfully."
}
```

Để chỉnh sửa, hãy đổi phương thức thành `PUT` và sử dụng các trường tương tự — thao tác này sẽ gửi lại mẫu tin nhắn mở đầu (và các bản nháp tiếp theo của chiến dịch, đối với chiến dịch WhatsApp API) để xét duyệt.

Một chiến dịch không thuộc tài khoản của bạn sẽ trả về `404`; một chiến dịch thuộc tài khoản khác mà bạn không được ủy quyền sẽ trả về `403`. Việc chỉnh sửa một chiến dịch chưa có mẫu tin nhắn sẽ trả về `400`.

---

## Gửi mẫu tin nhắn cho một liên hệ hiện có

Một giải pháp thay thế đơn giản hơn, được xác định theo đường dẫn so với [Gửi mẫu tin nhắn cho một liên hệ](#send-a-template-to-a-contact) ở trên: cả mẫu tin nhắn và liên hệ đều phải tồn tại từ trước — không có thông tin nào được tra cứu theo tên hoặc tạo mới ngay lập tức.

`POST /whatsapp-templates/{templateId}/send-to-contact`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `contactId` | Có | ID của liên hệ. Phải thuộc về tài khoản của bạn. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactId": "contact123" }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ contactId: "contact123" }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/send-to-contact",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactId": "contact123"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": "WhatsApp template message sent successfully"
}
```

> **Tín dụng:** Việc gửi tin nhắn sẽ tiêu tốn tín dụng, với mức giá tương tự như endpoint ở trên. Một `contactId` bị thiếu hoặc không có trong tài khoản của bạn sẽ trả về `403`; một `templateId` không tồn tại sẽ trả về `404`.

---

## Gửi hàng loạt mẫu tin nhắn

Gửi một mẫu tin nhắn cho nhiều liên hệ trong một lần gọi duy nhất, kèm theo bản xem trước chi phí mà bạn có thể hiển thị trước khi xác nhận.

### Ước tính chi phí trước

Trả về chi phí gửi tin, được phân tách theo quốc gia đích, mà không thực sự gửi bất kỳ tin nhắn nào hoặc trừ tín dụng. Giá mẫu được tính theo quốc gia đích, vì vậy giá trị này phải được tính toán ở phía máy chủ dựa trên các liên hệ thực tế thay vì ước tính ở phía máy khách.

`POST /whatsapp-templates/{templateId}/estimate-bulk-cost`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `contactIds` | Có | Các liên hệ cần tính giá, tối đa 500 liên hệ mỗi lần gọi. Các liên hệ trùng lặp chỉ được tính một lần. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contact123", "contact456"] }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ contactIds: ["contact123", "contact456"] }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/estimate-bulk-cost",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contact123", "contact456"]},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": {
    "countries": [
      {
        "countryCode": "1",
        "name": "United States",
        "iso": "US",
        "flag": "🇺🇸",
        "contactCount": 120,
        "costPerContact": 0.5,
        "subtotal": 60.0
      }
    ],
    "totalContacts": 120,
    "totalTemplateCost": 60.0,
    "templateCategory": "marketing",
    "skippedContacts": 2
  }
}
```

`skippedContacts` đếm các id bị thiếu, không thuộc về bạn hoặc không có số điện thoại — ước tính chỉ bao gồm các liên hệ còn lại, vì vậy giá trị khác không có nghĩa là lần gửi thực tế sẽ tiếp cận ít liên hệ hơn so với số lượng bạn đã chọn.

### Gửi lô tin nhắn

Gửi mẫu tin nhắn đến mọi liên hệ trong danh sách, giải quyết mọi biến thông minh cho từng liên hệ và trừ tín dụng cho mỗi lần gửi.

`POST /whatsapp-templates/{templateId}/bulk-send`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `contactIds` | Có | Các liên hệ cần gửi đến, tối đa 5000 liên hệ mỗi lần gọi. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contact123", "contact456"] }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ contactIds: ["contact123", "contact456"] }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/template_abc123/bulk-send",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contact123", "contact456"]},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": { "sent": 118, "failed": 2, "total": 120 }
}
```

Một liên hệ bị lỗi (không tìm thấy, không có trong tài khoản của bạn hoặc lỗi gửi) sẽ bị bỏ qua và được tính vào `failed` thay vì dừng toàn bộ lô. Một `contactIds` trống, vượt quá 5000 ID trong một lần gửi (500 ID đối với ước tính) hoặc thiếu `templateId` sẽ trả về `400`.

---

## Thử lại tin nhắn thất bại

Hai điểm cuối (endpoint) để gửi lại tin nhắn đã thất bại mà không cần tạo bản ghi tin nhắn mới hoặc tốn thêm tín dụng.

`POST /whatsapp-templates/messages/{contactId}/{messageId}/retry-template` thử lại một tin nhắn mẫu (template) cụ thể — nó sẽ phân giải lại nội dung mẫu từ chiến dịch nếu tin nhắn thất bại chưa chứa nội dung đó. Chỉ những tin nhắn có trạng thái `failed` và loại `template` mới có thể được thử lại theo cách này.

`POST /whatsapp-templates/messages/{contactId}/{messageId}/retry` không phụ thuộc vào kênh và hoạt động với bất kỳ tin nhắn không phải mẫu nào bị lỗi (ví dụ: WhatsApp Web), gửi tin nhắn đến đúng đường dẫn dựa trên kênh của tin nhắn đó. Nó chấp nhận trạng thái `failed`, `failed_connection`, `limit_exceeded` hoặc `queued_retry`.

Cả hai điểm cuối đều không yêu cầu phần thân yêu cầu (request body).

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/messages/contact123/msg_abc789/retry-template",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": "Message retry initiated successfully"
}
```

Đối với phiên bản không phụ thuộc vào kênh, hãy đổi đường dẫn thành `.../msg_abc789/retry`. Một tin nhắn có trạng thái không đủ điều kiện để thử lại, hoặc (trên điểm cuối mẫu) không phải là tin nhắn mẫu, sẽ trả về `400`. Một liên hệ hoặc tin nhắn bị thiếu sẽ trả về `404`.

---

## Hồ sơ WhatsApp Business

Quản lý hồ sơ WhatsApp Business (giới thiệu, địa chỉ, mô tả, email, trang web, danh mục doanh nghiệp và logo) hiển thị cho các liên hệ trên WhatsApp. Hoạt động trên cả kết nối được quản lý và tài khoản đang chạy Tài khoản WhatsApp Business riêng.

### Lưu hồ sơ

`PUT /whatsapp-templates/profile`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `phoneNumber` | Có | Số WhatsApp mà hồ sơ này thuộc về. Phải được kết nối trên tài khoản của bạn. |
| `about` | Không | Văn bản "Giới thiệu" ngắn hiển thị trên hồ sơ. |
| `address` | Không | Địa chỉ doanh nghiệp. |
| `description` | Không | Mô tả doanh nghiệp dài hơn. |
| `email` | Không | Email liên hệ hiển thị trên hồ sơ. |
| `websites` | Không | Mảng các URL trang web. Mỗi URL phải là một URL hợp lệ. |
| `vertical` | Không | Danh mục doanh nghiệp, ví dụ `Retail` hoặc `Professional Services`. |
| `profilePictureHandle` | Không | Handle được trả về bởi endpoint tải ảnh lên bên dưới, để đặt ảnh hồ sơ. |

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/whatsapp-templates/profile?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+31612345678",
    "about": "We reply within a few hours",
    "email": "support@example.com",
    "websites": ["https://example.com"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/profile", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phoneNumber: "+31612345678",
    about: "We reply within a few hours",
    email: "support@example.com",
    websites: ["https://example.com"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/whatsapp-templates/profile",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phoneNumber": "+31612345678",
        "about": "We reply within a few hours",
        "email": "support@example.com",
        "websites": ["https://example.com"],
    },
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": "WhatsApp Business profile updated successfully"
}
```

Thiếu `phoneNumber`, URL trang web không hợp lệ hoặc `phoneNumber` không được kết nối trên tài khoản của bạn sẽ trả về `400` hoặc `404`.

### Tải ảnh hồ sơ lên

Tải xuống hình ảnh từ URL bạn cung cấp và tải nó lên WhatsApp, trả về một handle. Truyền handle đó dưới dạng `profilePictureHandle` trong lệnh lưu hồ sơ ở trên để đặt làm ảnh — endpoint này chỉ tải hình ảnh lên, nó không tự đặt ảnh.

`POST /whatsapp-templates/profile/picture`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `phoneNumber` | Có | Số WhatsApp mà hồ sơ này thuộc về. |
| `fileUrl` | Có | Một URL có thể truy cập công khai đến hình ảnh cần tải lên. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+31612345678",
    "fileUrl": "https://example.com/logo.png"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phoneNumber: "+31612345678",
    fileUrl: "https://example.com/logo.png",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/whatsapp-templates/profile/picture",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "phoneNumber": "+31612345678",
        "fileUrl": "https://example.com/logo.png",
    },
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": "1234567890123456"
}
```

`data` là handle của hình ảnh đã tải lên. Thiếu `phoneNumber` hoặc `fileUrl`, hoặc `phoneNumber` không có mã thông báo truy cập WhatsApp trong hồ sơ, sẽ trả về `400`; một `fileUrl` không thể truy cập hoặc không hợp lệ sẽ trả về lỗi mô tả lý do tải xuống thất bại.

---

## Kiểm tra trạng thái người gửi

Thăm dò (và làm mới) trạng thái gửi trực tiếp của một số WhatsApp đã kết nối với nhà cung cấp dịch vụ nhắn tin. Hữu ích để xác nhận một số thực sự có thể gửi tin nhắn trước khi bạn dựa vào nó.

`GET /whatsapp-templates/sender-status/{phoneNumber}`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/whatsapp-templates/sender-status/+31612345678",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Phản hồi**

```json
{
  "success": true,
  "data": "ONLINE"
}
```

`data` là một trong các giá trị `ONLINE` (đang gửi bình thường), `PENDING` (vẫn đang được xác minh), hoặc `DELETED` (nhà cung cấp không còn nhận diện người gửi này — hãy kết nối lại số điện thoại). Một `phoneNumber` không có thông tin doanh nghiệp WhatsApp trong hồ sơ sẽ trả về `404`.

---

## Tạo mẫu tin nhắn theo dõi bằng AI

Nền tảng có thể tự viết các mẫu tin nhắn theo dõi qua WhatsApp cho chiến dịch của bạn — các tin nhắn nhắc nhở được gửi khi cuộc trò chuyện bị bỏ ngỏ — dựa trên hướng dẫn và mục tiêu của chính chiến dịch đó. Có một endpoint công việc chạy trong nền, cộng với ba endpoint cũ hơn được giữ lại cho các tích hợp hiện có. Tất cả đều sử dụng tín dụng AI.

### Bắt đầu công việc tạo mẫu

`POST /campaigns/{campaignId}/template-generation`

| Trường | Bắt buộc | Mô tả |
|---|---|---|
| `type` | Không | `all` (mặc định) viết toàn bộ tập hợp tin nhắn theo dõi. `cold_only` chỉ viết tin nhắn cho những liên hệ chưa bao giờ phản hồi. |

**cURL**

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

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ type: "all" }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/campaigns/campaign_abc123/template-generation",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"type": "all"},
)
data = res.json()
```

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

```json
{ "success": true, "campaign_id": "campaign_abc123", "type": "all" }
```

Lệnh gọi trả về ngay khi công việc được xếp hàng. Hãy đọc chiến dịch (`GET /campaigns/{campaignId}`, xem [API Chiến dịch](campaigns.md)) và theo dõi đối tượng `template_generation_status` của nó cho đến khi hoàn tất:

| Trường | Mô tả |
|---|---|
| `status` | `processing` trong khi công việc đang chạy, sau đó là `completed` hoặc `failed`. |
| `progress` | Từ 0 đến 100. |
| `current_template`, `total_templates` | Số lượng mẫu đã được viết cho đến nay, trên tổng số mẫu mà công việc sẽ thực hiện — 11 cho chiến dịch gửi đi hoặc chiến dịch kết hợp, 9 cho các trường hợp khác. |
| `error` | Lý do công việc `failed` bị dừng, ví dụ như không đủ tín dụng. |
| `started_at`, `completed_at` | Thời điểm công việc bắt đầu và kết thúc. |

Các mẫu được tạo sẽ xuất hiện trên chiến dịch giống như bất kỳ mẫu nào khác, vì vậy chúng sẽ hiển thị trong [Danh sách mẫu](#list-templates) và vẫn phải trải qua quá trình phê duyệt của WhatsApp trước khi có thể gửi đi. `400` có nghĩa là `type` không phải là `all` hoặc `cold_only`; `404` có nghĩa là chiến dịch không tồn tại hoặc thuộc về một tài khoản khác.

Các Tác nhân (Agents) có một lệnh gọi tương tự, `POST /agents/{agentId}/template-generation`, giúp viết các tin nhắn theo dõi cho một Tác nhân và hoàn tất ngay trong lệnh gọi như thông thường — xem [Tạo tin nhắn theo dõi](agents.md#generate-follow-up-messages) trong API Tác nhân AI.

### Các endpoint tạo mẫu cũ hơn

Ba endpoint trước đó thực hiện cùng một công việc và được giữ lại để các tích hợp hiện có tiếp tục hoạt động. Mã mới nên sử dụng endpoint công việc ở trên.

| Endpoint | Chức năng |
|---|---|
| `POST /whatsapp-templates/campaign/{campaignId}/generate-async` | Bắt đầu tạo tin nhắn theo dõi cho chiến dịch trong nền và trả về `202` với `{ "success": true, "data": { "result": "success", "message": "..." } }`. Tín dụng được trừ trước (bỏ qua đối với tài khoản sử dụng khóa AI riêng) và `template_generation_status` của chiến dịch báo cáo tiến độ chính xác như trên. |
| `POST /whatsapp-templates/campaign/{campaignId}/generate-followups` | Tạo tất cả chín mẫu tin nhắn theo dõi trong lệnh gọi — dành cho chiến dịch được tạo trước khi tính năng theo dõi tự động tồn tại, hoặc chiến dịch cần viết lại mẫu — và trả về `200` với `templatesGenerated` bên trong `data`. |
| `POST /whatsapp-templates/agent/{agentId}/generate-followups` | Quá trình tạo đồng bộ tương tự như Tác nhân. Phản hồi thêm `agent_id`, `campaign_id` và `target`: `"campaign"` khi các mẫu được ghi vào chiến dịch của Tác nhân, `"agent"` (với `campaign_id: null`) khi Tác nhân không có chiến dịch và chúng được lưu trữ trên chính Tác nhân đó. Tác nhân bị thiếu hoặc thuộc tài khoản khác sẽ trả về `404`. |

Cả ba đều yêu cầu tính năng theo dõi tự động trên tài khoản và đủ tín dụng — `400` cho biết cái nào đang thiếu — và cặp endpoint dành cho chiến dịch sẽ trả về `403` khi chiến dịch thuộc về một tài khoản khác.

---

## Lỗi API mẫu

Các điểm cuối (endpoint) mẫu trả về cấu trúc lỗi tiêu chuẩn:

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

Một `404` trên các điểm cuối này thường có nghĩa là tài nguyên 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. Một vài điểm cuối (tạo/cập nhật theo phạm vi chiến dịch, và gửi đến một liên hệ hiện có) trả về `403` thay vào đó khi chiến dịch hoặc liên hệ thuộc về người khác thay vì không tồn tại. Một số điểm cuối cũng bao gồm trường `error_code` phản ánh trạng thái HTTP. Các mã chia sẻ mà mọi điểm cuối có thể trả về — `400`, `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).

---

## Các bước tiếp theo

- [Xác thực](authentication.md) — bốn cách để xác thực một yêu cầu.
- [Lỗi & Giới hạn tốc độ](errors-and-pagination.md) — các mã trạng thái và giới hạn 300 yêu cầu/phút.
- [API Chiến dịch](campaigns.md) — quản lý các chiến dịch mà mẫu được đính kèm vào.
