> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/tech/serve/customer-service-system-integration.md).

# 第三方客服系統串接（含轉真人）

客服系統或聊天平台以 API 接入 MaiAgent 當 AI 引擎：訊息進出、AI 判定轉真人時交由您的真人客服接手、結束後回到 AI 的端到端規格

本頁適合「已有自己的客服系統或聊天前台（自有網頁、LINE、Messenger 等通道掛在您這邊），要把 MaiAgent 當作 **AI 引擎**」的整合方：訪客訊息由您的系統送進 MaiAgent，AI 回覆推回您的系統；當 AI 判定需要真人時，由**您的真人客服**接手，服務結束後再把對話交還給 AI。

整合只用到 MaiAgent 既有的公開 API 與兩組 Webhook，不需要為單一客服系統開發專屬介面。

## 兩種串接情境 <a href="#scenarios" id="scenarios"></a>

| 情境                        | 訪客在哪裡對話                                        | 真人客服在哪裡 | 怎麼串                                                       |
| ------------------------- | ---------------------------------------------- | ------- | --------------------------------------------------------- |
| **情境 A**：MaiAgent 當 AI 引擎 | 您的系統（自有網頁、LINE 等通道掛在您這邊）                       | 您的系統    | [前置設定](#setup)後依[步驟一](#step-identity)～[步驟六](#step-return) |
| **情境 B**：只有真人客服在您的系統      | MaiAgent 的對話平台（Web Chat、LINE 官方帳號等接在 MaiAgent） | 您的系統    | [前置設定](#setup)後依[情境 B](#scenario-b)                       |

真人客服使用 Genesys Cloud 時，情境 B 可改用內建的 [Genesys Cloud 整合](/tech/serve/customer-service-system-integration/genesys-cloud-integration.md)，不需自行串接。

兩種情境的轉真人事件、[事件一覽](#events)與[狀態查詢](#query-state)相同。下方的整合全景與步驟一～六以情境 A 說明。

## 整合全景 <a href="#overview" id="overview"></a>

```mermaid
sequenceDiagram
    participant V as 訪客
    participant S as 您的客服系統
    participant M as MaiAgent
    participant H as 您的真人客服

    V->>S: 發話（網頁 / LINE / …）
    S->>M: ① 身分同步（sourceId → contactId）
    S->>M: ② 建立對話（首次）
    S->>M: ③ 送出訊息 POST /messages/
    M-->>S: 201（AI 回覆非同步）
    M-)S: ④ Outgoing Webhook：AI 回覆
    S->>V: 顯示 AI 回覆

    Note over M: AI 判定需要真人
    M-)S: ⑤ handoff.requested
    S->>H: 建立案件、指派客服
    H->>V: 真人接續服務（在您的系統內）
    S->>M: ⑥ PATCH /conversations/{id}/return-to-ai/
    M-)S: handoff.returned_to_ai
    Note over M: 後續訊息恢復由 AI 回覆
```

### 雙方分工 <a href="#responsibilities" id="responsibilities"></a>

| 誰            | 負責                                                                      |
| ------------ | ----------------------------------------------------------------------- |
| **您的系統**     | 通道接入、訪客介面、案件與客服座席、對話紀錄的保存與呈現；把訪客訊息送進 MaiAgent、接收 Webhook、真人服務結束時呼叫回到 AI |
| **MaiAgent** | AI 回覆、對話上下文維持、以 LLM 判定是否轉真人、轉真人與回到 AI 的事件推送                             |

## 前置設定 <a href="#setup" id="setup"></a>

以下都在 MaiAgent 後台完成，一個對話平台設定一次。

### 1. 建立 Web Chat 對話平台並取得憑證 <a href="#setup-inbox" id="setup-inbox"></a>

API 串接使用 **Web Chat** 類型的對話平台。您需要：

* **API 金鑰**：取得方式見 [快速上手](/tech/api-integration/quickstart.md)。
* **Web Chat ID**：<mark style="color:blue;">客服對話</mark> → <mark style="color:blue;">對話平台</mark> → 編輯該 API 平台 → <mark style="color:blue;">串接與登入</mark> → <mark style="color:blue;">Webhook 設定</mark> 最下方的 <mark style="color:blue;">API 資訊</mark> 卡，唯讀並可複製；見使用者手冊[對話平台基本設定](https://docs.maiagent.ai/build/conversation-settings/platform-settings/basic-settings#web-chat-id)。

### 2. 設定 Outgoing Webhook（接收 AI 回覆） <a href="#setup-outgoing-webhook" id="setup-outgoing-webhook"></a>

<mark style="color:blue;">客服對話</mark> → <mark style="color:blue;">對話平台</mark> → 編輯該平台 → <mark style="color:blue;">Webhook 設定</mark> → <mark style="color:blue;">新增 Webhook</mark>，類型選 **Outgoing**，端點填您的回覆接收 URL。格式選 **MaiAgent 標準格式**；若您的系統要求固定 JSON 結構，選 **自訂範本**。欄位與 payload 見 [Webhook](/tech/serve/webhook.md)。

### 3. 啟用真人客服轉接 <a href="#setup-handoff" id="setup-handoff"></a>

同一個對話平台 → <mark style="color:blue;">客服轉真人設定</mark>。每個欄位的意義與操作畫面見使用者手冊的[客服轉真人設定](https://docs.maiagent.ai/build/conversation-settings/human-handoff)；真人客服在您的系統時，建議這樣設定：

| 設定                                                                                  | 真人客服在您的系統時的建議                                                                                                                                                                                                   |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <mark style="color:blue;">啟用真人客服轉接</mark>                                           | 開啟                                                                                                                                                                                                              |
| <mark style="color:blue;">轉真人條件</mark> 的判定規則（<mark style="color:blue;">角色指令</mark>） | 先用預設規則：訪客明確要求真人、問題超出 AI 能處理、訪客情緒不佳、涉及需人工核實的帳務操作。再依您的業務調整，例如加上關鍵字、信心不足即轉                                                                                                                                         |
| <mark style="color:blue;">派工設定</mark> → <mark style="color:blue;">派工模式</mark>       | 選 **接手制**。MaiAgent 不會把對話派給後台成員，對話留在排隊中，由您的系統接手                                                                                                                                                                  |
| <mark style="color:blue;">派工設定</mark> → <mark style="color:blue;">等待超時時間</mark>     | 勾選 **不逾時**（只有接手制能勾）。對話會一直排隊，直到您呼叫回到 AI；MaiAgent 不會自行把對話轉回 AI                                                                                                                                                    |
| <mark style="color:blue;">派工設定</mark> → <mark style="color:blue;">排隊上限</mark>       | 依您的客服容量設定（1–500）。額滿時新的轉真人請求不會觸發：該則訊息不會有 AI 回覆，也不會發送 `handoff.requested`                                                                                                                                         |
| <mark style="color:blue;">服務時間</mark>                                               | 視需要啟用。<mark style="color:blue;">顯示離線訊息</mark> 時，非服務時間不轉真人：該則訊息不回 AI、也不發送 `handoff.requested`（離線訊息只推給 Web Chat 前端，非服務時間的提示請由您的系統處理）；<mark style="color:blue;">接受留言</mark> 時仍進入排隊並發送 `handoff.requested`，且不啟動等待超時 |

以 API 設定對話平台時，接手制加不逾時對應 `dispatchMode: "handover"` 與 `assignmentQueueTimeout: 0`。

{% hint style="danger" %}
**不要在自動派工下把等待超時時間設成 0。** 自動派工（預設）的等待超時只接受 1～3600 秒：畫面上填 0 會提示超出範圍，透過 API 送出 0 則會被改成預設的 300 秒。300 秒後沒有 MaiAgent 成員接手，MaiAgent 就會送出 `handoff.queue_timeout`，讓 AI 接回對話，訪客與您的客服都不會察覺。
{% endhint %}

{% hint style="warning" %} <mark style="color:blue;">轉接通知訊息</mark>、<mark style="color:blue;">排隊等待提示</mark> 等「給訪客看的提示文字」是推送給 MaiAgent 自家 Web Chat 前端的，**不會經由 Webhook 送到您的系統**。請在收到 `handoff.requested` 時，由您的系統自行向訪客顯示「正在為您轉接真人客服」等提示。
{% endhint %}

### 4. 開啟轉真人 Webhook <a href="#setup-handoff-webhook" id="setup-handoff-webhook"></a>

同一分頁 → 子分頁 <mark style="color:blue;">通知</mark> → 開啟 <mark style="color:blue;">Webhook 通知（系統串接）</mark>，填入：

* <mark style="color:blue;">Webhook 網址</mark>：僅接受 HTTPS。
* <mark style="color:blue;">簽章密鑰（選填）</mark>（建議設定）：設定後每次推送帶 HMAC-SHA256 簽章，驗證方式見[傳送與簽章](#handoff-delivery)。

<mark style="color:blue;">Email 通知</mark> 與 <mark style="color:blue;">通知中心公告</mark> 只在對話指派給 MaiAgent 成員時發送，與本整合無關，可關閉。

{% hint style="info" %}
這三個通知開關由對話平台的管理者在後台自行開啟，不需要另外申請。操作畫面見使用者手冊的[轉真人客服通知](https://docs.maiagent.ai/build/conversation-settings/human-handoff/handoff-notification)。
{% endhint %}

## 步驟一：對應訪客身分 <a href="#step-identity" id="step-identity"></a>

以您系統中的使用者 ID 呼叫身分同步 API，取得該訪客在 MaiAgent 的 `contactId`：

```bash
curl -X POST \
  'https://api.maiagent.ai/api/v1/web-chats/{webChatId}/setup-contact-credentials/' \
  -H 'Content-Type: application/json' \
  -d '{ "sourceId": "your-user-id", "name": "王小明" }'
```

```json
{ "contactId": "c0ffee00-1111-2222-3333-444455556666" }
```

同一個 `sourceId` 重複呼叫會回傳同一個 `contactId`（冪等），請把 `sourceId ↔ contactId` 存在您的使用者資料中。`sourceId` 請使用不可猜測的值。完整說明見 [聯絡人身分同步與 Token 更新](/tech/serve/contacts/contact-credentials-sync.md)。

## 步驟二：建立對話 <a href="#step-conversation" id="step-conversation"></a>

每位訪客建立一個對話並**長期沿用**，MaiAgent 會以對話為單位維持上下文：

```bash
curl -X POST 'https://api.maiagent.ai/api/v1/conversations/' \
  -H 'Authorization: Api-Key <您的API金鑰>' \
  -H 'Content-Type: application/json' \
  -d '{ "webChat": "<Web Chat ID>", "contact": "<contactId>" }'
```

回應中請記下 `id`（對話 ID）與 `inbox.id`（對話平台 ID，設定 Webhook 時會用到）。回應欄位見 [建立對話與訊息](/tech/api-integration/conversations-and-messages.md)。

若您希望每次來訪重新開始一段對話（例如案件結案後），再建立一個新對話即可；舊對話的紀錄仍保留。

## 步驟三：送出訪客訊息 <a href="#step-send" id="step-send"></a>

```bash
curl -X POST 'https://api.maiagent.ai/api/v1/messages/' \
  -H 'Authorization: Api-Key <您的API金鑰>' \
  -H 'Content-Type: application/json' \
  -d '{
    "conversation": "<對話 ID>",
    "content": "我想查詢訂單進度",
    "attachments": []
  }'
```

回應 `201` 只代表訊息已建立，**AI 回覆會在數秒內以 Outgoing Webhook 推送**（步驟四），HTTP 回應本身不帶回覆。附件請先上傳取得附件物件再帶入 `attachments`，見 [Presigned 檔案上傳模式](/tech/api-integration/api_knowledge.md)。

## 步驟四：接收 AI 回覆 <a href="#step-receive" id="step-receive"></a>

AI 回覆建立後，MaiAgent 對您設定的 Outgoing Webhook 發出請求。以標準格式為例，您的端點會收到：

```json
{
  "id": "2491074a-6d23-4289-af45-caa12531420e",
  "type": "outgoing",
  "content": "您的訂單 #12345 目前配送中，預計明天送達。",
  "created_at": "2026-09-09T10:15:30.123456+00:00",
  "conversation": {
    "id": "8e44604a-8278-4c96-96b5-3e5a0548d738",
    "status": "open",
    "progress_status": "ai_processing",
    "auto_reply_enabled": true,
    "assignee": null
  },
  "contact": { "id": "c0ffee00-1111-2222-3333-444455556666", "name": "王小明" },
  "sender": { "id": "…", "name": "AI 智能客服", "type": "chatbot" },
  "attachments": []
}
```

您的系統依 `contact.id` 找到對應使用者、依 `conversation.id` 找到對話，把 `content` 與附件轉成您通道的格式送給訪客。請回應 2xx；完整欄位、自訂範本與傳送行為見 [Webhook](/tech/serve/webhook.md)。

{% hint style="info" %}
若您需要在 payload 裡直接拿到自己的使用者 ID 或可下載的附件網址，使用 **自訂範本** 輸出 `contact.source_id` 與 `attachment.file.url`，範例見 [Webhook › 自訂範本](/tech/serve/webhook.md#custom-template)。
{% endhint %}

## 步驟五：AI 判定轉真人 <a href="#step-handoff" id="step-handoff"></a>

每則訪客訊息進來時，MaiAgent 先以判定模型判斷是否需要真人。判定為「需要」時：

1. 對話狀態變為 `queued`、`auto_reply_enabled` 變為 `false`，**這則訊息不會有 AI 回覆**，後續訊息也不再由 AI 回覆。
2. MaiAgent 對您的轉真人 Webhook 網址送出 `handoff.requested` 事件。

### 事件 payload <a href="#handoff-payload" id="handoff-payload"></a>

事件的欄位表與 JSON 範例見 API 文件[轉真人 Webhook 事件](https://docs.maiagent.ai/api/preparation/handoff-webhook)的「事件格式」。串接本流程時要掌握的幾點：

* 四種事件的欄位完全相同，請依 `event` 分流（見下方[事件一覽](#events)）。
* `conversation.id`、`contact.id` 對應您在步驟一、二記下的對話與訪客。
* 以事件 `id` 去重、以 `occurred_at` 排序；payload 只含識別資訊，不含對話內容。
* `assignee` 是事件當下被指派的 MaiAgent 成員；`handoff.requested` 與由您的客服接手時恆為 `null`。
* 欄位命名與巢狀結構和步驟四的訊息 Webhook 一致，同一支接收端可以同時處理兩組推送。

### 傳送與簽章 <a href="#handoff-delivery" id="handoff-delivery"></a>

`POST`、`Content-Type: application/json`，逾時 10 秒；非 2xx 或連線失敗會**每 60 秒重試，最多 3 次**。有設定簽章密鑰時，請求帶 `X-MaiAgent-Signature-256: sha256=<hex>`，值為以密鑰對原始請求內容計算的 HMAC-SHA256。驗證程式與可直接啟動的接收端範例見 API 文件[轉真人 Webhook 事件](https://docs.maiagent.ai/api/preparation/handoff-webhook)的「簽章驗證」與[接收端最小範例](https://docs.maiagent.ai/api/preparation/handoff-webhook#receiver-example)。

### 您的系統收到 `handoff.requested` 後 <a href="#after-triggered" id="after-triggered"></a>

* 在您的系統建立案件、指派真人客服，並向訪客顯示轉接提示。
* 之後訪客的訊息由您的客服在您的系統內處理。**可以不再送進 MaiAgent**；若您仍希望 MaiAgent 保留完整紀錄，可以繼續呼叫 `POST /messages/`——訊息會存入對話並觸發 Incoming Webhook，但在回到 AI 之前不會產生 AI 回覆。
* 真人客服的回覆由您的系統直接送給訪客，不需要經過 MaiAgent。

## 步驟六：真人服務結束，回到 AI <a href="#step-return" id="step-return"></a>

案件結束時，呼叫回到 AI：

```bash
curl -X PATCH 'https://api.maiagent.ai/api/v1/conversations/{conversationId}/return-to-ai/' \
  -H 'Authorization: Api-Key <您的API金鑰>'
```

對話回到 `open`、`auto_reply_enabled` 恢復 `true`，MaiAgent 送出 `handoff.returned_to_ai`，之後的訪客訊息恢復由 AI 回覆。回應為更新後的對話物件。

{% hint style="warning" %}
API 金鑰所屬的成員需要有該對話平台的對話存取權限。若沒有依[前置設定](#setup-handoff)選擇接手制並勾選 <mark style="color:blue;">不逾時</mark>，<mark style="color:blue;">等待超時時間</mark> 到期時 MaiAgent 會自動回到 AI 並送出 `handoff.queue_timeout`，請確認這符合您的流程。非服務時間以 <mark style="color:blue;">接受留言</mark> 進入排隊的對話**不會啟動等待超時**，一律要由您的系統呼叫 `return-to-ai` 結束。
{% endhint %}

## 情境 B：訪客在 MaiAgent 對話平台，真人客服在您的系統 <a href="#scenario-b" id="scenario-b"></a>

訪客透過 MaiAgent 的對話平台與 Agent 對話，只有轉真人後的真人客服在您的客服系統回覆。訪客訊息本來就進 MaiAgent，您的系統不需要做步驟一～三；改用訊息 Webhook 把轉真人期間的訊息帶進您的系統，再以 API 把客服回覆寫回對話，讓兩邊雙向同步。

前置設定在訪客所在的對話平台上完成：[啟用真人客服轉接](#setup-handoff)（接手制＋不逾時）與[開啟轉真人 Webhook](#setup-handoff-webhook) 和情境 A 相同；[訊息 Webhook](#setup-outgoing-webhook) 要新增 **Incoming**（訪客訊息）與 **Outgoing**（Agent 或客服回覆）兩個方向。寫回客服回覆與回到 AI 需要 API 金鑰，取得方式見[快速上手](/tech/api-integration/quickstart.md)。

### 串接流程 <a href="#scenario-b-flow" id="scenario-b-flow"></a>

1. **得知轉真人開始**：收到 `handoff.requested` 後，在您的系統以 `conversation.id` 開單或建立會話，並記下 `contact.id`。事件不含對話文字；需要轉真人前的對話內容時，以 `conversation.id` 呼叫 API 文件的[取得訊息列表](https://docs.maiagent.ai/api/api-reference/dui-hua-he-xun-xi#messages-list)。若之後收到 `handoff.assigned`，代表對話被指派給 MaiAgent 後台的成員，`assignee.id` 是這位成員。
2. **接收訪客訊息與客服回覆**：訊息 Webhook 的每筆 payload 都帶對話的目前狀態。只處理 `conversation.auto_reply_enabled` 為 `false` 的訊息，就能略過 Agent 自動回覆中的流量；以 `sender.type` 分辨訪客（`contact`）、真人客服（`user`）與 Agent（`chatbot`）。欄位定義見 [Webhook › 欄位說明](/tech/serve/webhook.md#standard-fields)。
3. **把客服回覆寫回對話**：以 API 金鑰呼叫 `POST /api/v1/messages/outgoing/`，帶 `conversation` 與 `content`，MaiAgent 會把訊息送到訪客所在的對話平台。訊息的發送者是 API 金鑰所屬的成員，這位成員需要有該對話平台的對話存取權限。欄位見 API 文件[發送主動訊息](https://docs.maiagent.ai/api/api-reference/dui-hua-he-xun-xi#messages-outgoing-create)。
4. **結束轉真人**：客服處理完畢後呼叫 `return-to-ai`（呼叫方式同[步驟六](#step-return)），Agent 重新接手。無論是您呼叫 API，還是成員在後台按「轉回 AI Agent」，您都會收到 `handoff.returned_to_ai`，請據此關閉您系統中的會話。

{% hint style="warning" %}
依建議的接手制＋不逾時設定，轉真人後的對話會一直是排隊中，`conversation.progress_status` 為 `waiting_for_human`；只有對話被指派給 MaiAgent 後台成員時才會變成 `human_serving`。判斷是否由真人處理時請看 `auto_reply_enabled`，不要只比對 `progress_status` 是否為 `human_serving`，否則會漏掉訪客訊息。
{% endhint %}

### 呼叫範例 <a href="#scenario-b-examples" id="scenario-b-examples"></a>

**（1）轉真人期間收到的訊息 Webhook**（MaiAgent 標準格式，節錄）：`auto_reply_enabled` 為 `false` 代表由真人處理，`sender.type` 為 `contact` 代表是訪客訊息。

```json
{
  "id": "9d2f7a10-...",
  "type": "incoming",
  "content": "我要改訂單地址",
  "created_at": "2026-09-09T02:30:00+00:00",
  "conversation": {
    "id": "6c2b7c1e-...",
    "title": "...",
    "type": "individual",
    "status": "queued",
    "progress_status": "waiting_for_human",
    "auto_reply_enabled": false,
    "assignee": null
  },
  "inbox": { "id": "0f9a3d42-...", "name": "官網客服", "channel_type": "web" },
  "contact": { "id": "a4c1f6b3-...", "name": "王小明", "email": null, "phone_number": null },
  "sender": { "id": "a4c1f6b3-...", "name": "王小明", "type": "contact" },
  "attachments": [],
  "metadata": {}
}
```

**（2）把客服回覆寫回對話**：帶 `conversation` 與 `content` 即可，訊息會以 API 金鑰所屬成員的身分送到訪客所在的對話平台。

```bash
curl -X POST "https://api.maiagent.ai/api/v1/messages/outgoing/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation": "6c2b7c1e-...",
    "content": "您好，地址已為您更新為台北市信義區…"
  }'
```

**（3）三步合在一起**（Python，`requests`）：

```python
import requests

API = "https://api.maiagent.ai/api/v1"
HEADERS = {"Authorization": "Api-Key YOUR_API_KEY"}


def on_message_webhook(payload: dict) -> None:
    conv = payload["conversation"]
    if conv["auto_reply_enabled"]:
        return  # Agent 自動回覆中的流量不進客服系統
    if payload["sender"]["type"] == "contact":
        push_to_agent_console(conv["id"], payload["content"])  # 訪客訊息→您的客服介面


def reply(conversation_id: str, text: str) -> None:
    requests.post(f"{API}/messages/outgoing/", headers=HEADERS,
                  json={"conversation": conversation_id, "content": text}, timeout=10).raise_for_status()


def finish(conversation_id: str) -> None:
    requests.patch(f"{API}/conversations/{conversation_id}/return-to-ai/", headers=HEADERS, timeout=10).raise_for_status()
```

### 注意事項 <a href="#scenario-b-notes" id="scenario-b-notes"></a>

* 透過 API 寫回的客服回覆，會再經由 Outgoing 訊息 Webhook 送出一次（`sender.type` 為 `user`）；請以訊息 `id` 去重，避免在您的系統重複顯示。
* `handoff.assigned` 在轉接給另一位成員時會再送一筆，`assignee.id` 為新的負責人；請以 `conversation.id` 更新既有會話，不要重複開單。
* 訊息 Webhook 與轉真人 Webhook 的驗證方式不同，見[串接前常見問題 › 認證](#faq-auth)。

## 事件一覽 <a href="#events" id="events"></a>

| `event`                  | 觸發時機                                            | 對您的系統的意義                     |
| ------------------------ | ----------------------------------------------- | ---------------------------- |
| `handoff.requested`      | AI 判定需要真人，對話進入排隊，AI 停止回覆                        | 由您的真人客服接手                    |
| `handoff.assigned`       | 對話指派給 MaiAgent 後台的客服成員（成員在後台接手、轉接或自動指派；轉接會再送一筆） | 若真人全在您的系統，不會收到此事件            |
| `handoff.returned_to_ai` | 您呼叫 `return-to-ai`，或成員在後台按「轉回 AI Agent」         | AI 恢復回覆，您可結案                 |
| `handoff.queue_timeout`  | 等待超時時間到期，MaiAgent 自動把對話轉回 AI                    | AI 已恢復回覆；若您的客服仍在處理，這是需要告警的異常 |

每個事件在 `GET /api/v1/conversations/{id}/events/` 都有對應的 `event_type`（`transfer_triggered`／`human_assigned`／`returned_to_ai`／`queue_timeout`），可用於對帳。

{% hint style="info" %}
事件各自以背景任務送出，**不保證到達順序**，也可能因重試而重複。請以事件 `id` 去重、以 `occurred_at` 排序，並把 `handoff.assigned` 視為隱含已觸發。
{% endhint %}

### 用 API 查詢目前狀態 <a href="#query-state" id="query-state"></a>

Webhook 之外，隨時可以查詢對話目前由誰處理：

```bash
GET https://api.maiagent.ai/api/v1/conversations/{conversationId}/
```

`status`（`open`／`queued`／`resolved`）、`autoReplyEnabled` 與 `progressStatus`（`ai_processing`／`waiting_for_human`／`human_serving`）足以還原狀態；`GET /api/v1/conversations/{conversationId}/events/` 則列出轉真人相關的事件紀錄（`transfer_triggered`、`queued`、`human_assigned`、`returned_to_ai`、`queue_timeout` 等），可作為對帳或補償用途。

## 串接前常見問題 <a href="#kickoff-faq" id="kickoff-faq"></a>

客服系統廠商在 kick-off 時通常會提出下列問題，答案整理於此，可直接作為雙方對接文件的附件。

### 環境與路徑 <a href="#faq-environments" id="faq-environments"></a>

| 環境 | Base URL                              |
| -- | ------------------------------------- |
| 測試 | `https://api-dev.maiagent.ai/api/v1/` |
| 正式 | `https://api.maiagent.ai/api/v1/`     |

本整合用到的路徑固定：`POST /web-chats/{webChatId}/setup-contact-credentials/`、`POST /conversations/`、`POST /messages/`、`PATCH /conversations/{id}/return-to-ai/`；對帳用 `GET /conversations/{id}/` 與 `GET /conversations/{id}/events/`。測試環境的組織、API 金鑰與 Web Chat 由您的對接窗口建立後提供。

### 認證 <a href="#faq-auth" id="faq-auth"></a>

* **您呼叫 MaiAgent**：標頭 `Authorization: Api-Key <金鑰>`。身分同步 API 不需金鑰，以 `webChatId` 識別。
* **MaiAgent 推送給您**：兩者都以 HMAC-SHA256 簽章，標頭同為 `X-MaiAgent-Signature-256: sha256=<hex>`，但簽章內容不同。訊息 Webhook（需設定 Secret Token）對「`X-MaiAgent-Timestamp` 的值 + `.` + 原始 request body」簽章，見 [Webhook › 驗證簽章與時間戳](/tech/serve/webhook.md#webhook-signature)；轉真人 Webhook 只對原始 request body 簽章。

### 逾時、重試與流量上限 <a href="#faq-limits" id="faq-limits"></a>

| 方向                        | 逾時                   | 重試                                                                                                                          |
| ------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| 您呼叫 `POST /messages/`     | 同步回 201，建議客戶端逾時 10 秒 | 4xx 先修正請求；5xx 或逾時表示結果不確定，先對帳，不要直接重送                                                                                         |
| 訊息 Webhook（MaiAgent → 您）  | 30 秒                 | 逾時、連線失敗、5xx、429 約 1、5、15 分鐘後各重送一次，最多 3 次；其他 4xx 不重送。請先落地再回 2xx，以訊息 `id` 去重，見 [Webhook › 自動重送](/tech/serve/webhook.md#retry) |
| 轉真人 Webhook（MaiAgent → 您） | 10 秒                 | 失敗每 60 秒重試，最多 3 次；以事件 `id` 去重                                                                                               |

`POST /messages/` 不保證冪等：伺服器可能已建立訊息，但回應在傳輸途中遺失。請先透過對話記錄與自有送件記錄確認結果；無法確認時，直接重送可能新增重複訊息並再次觸發 AI 回覆。

每把 API 金鑰可設定每分鐘請求上限（RPM），預設不限制；正式上線前請提供預估流量，由對接窗口設定。

### 來源 IP 白名單 <a href="#faq-egress" id="faq-egress"></a>

MaiAgent 推送 Webhook 的出站 IP 固定。若您的接收端需要白名單，請向對接窗口索取正式與測試環境的最新清單。MaiAgent 對您的接收端網域沒有出站限制。

### 對話 session 的對應 <a href="#faq-session" id="faq-session"></a>

鍵是聯絡人的 `sourceId`（建議用 `{平台}:{您的使用者 ID}` 避免跨通道撞號）。同一 `sourceId` 重複呼叫身分同步 API 回同一 `contactId`；對話建立後**沒有存續時間限制**，可長期沿用同一對話 ID 維持上下文，也可在結案後為同一聯絡人建立新對話重新開始。

### 轉真人的判定邏輯 <a href="#faq-handoff-logic" id="faq-handoff-logic"></a>

由判定模型依對話最近 N 則訊息判斷，預設規則：訪客明確要求真人、問題超出 AI 能處理、訪客情緒不佳、涉及需人工核實的帳務操作。規則以自然語言在<mark style="color:blue;">角色指令</mark>調整，可加關鍵字、信心不足即轉等條件；也可設定<mark style="color:blue;">服務時間</mark>決定非服務時間是否轉接。判定結果就是 `handoff.requested` 事件。

### 多段回覆與訊息樣式 <a href="#faq-message-format" id="faq-message-format"></a>

每則 AI 回覆推送一筆訊息 Webhook（一筆一則），不做批次；一則回覆可含多個附件。若您的系統要求陣列格式，以自訂範本輸出單元素陣列即可。標準支援文字（Markdown）與附件（圖片／影片／音訊／檔案）；按鈕、卡片、快速回覆等通道專屬樣式不在標準範圍，請於 kick-off 提出需求另行評估。

### 附件網址與存續時間 <a href="#faq-attachments" id="faq-attachments"></a>

AI 回覆的附件以自訂範本輸出 `attachment.file.url`，為簽名網址、**有效 1 小時**，請於收到後立即取檔轉存。訪客上傳的附件由您的系統先取得可下載網址，於送出訊息時帶入 `attachments[]`。

### 錯誤與用量查詢 <a href="#faq-observability" id="faq-observability"></a>

訊息 Webhook 每次推送的請求、回應與狀態碼可在 MaiAgent 後台 Agent 頁面的 <mark style="color:blue;">Webhook</mark> 分頁查看；對話狀態與轉真人事件可用對話 API 與事件紀錄 API 查詢對帳；AI 用量在後台<mark style="color:blue;">用量統計</mark>。轉真人 Webhook 推送失敗會進 MaiAgent 的監控告警。

## 整合檢查清單 <a href="#checklist" id="checklist"></a>

* [ ] 後台：Outgoing Webhook 已設定並能收到 AI 回覆
* [ ] 後台：真人客服轉接已啟用；外部真人客服的派工模式為 <mark style="color:blue;">接手制</mark>，並已勾選 <mark style="color:blue;">不逾時</mark>
* [ ] 後台：轉真人 Webhook 已開啟、HTTPS 端點可達、簽章驗證通過
* [ ] 您的系統：`sourceId ↔ contactId ↔ conversationId` 對應已落地
* [ ] 您的系統：`handoff.requested` → 建案與轉接提示；`handoff.returned_to_ai` → 結案；`handoff.queue_timeout` → 告警或結案
* [ ] 您的系統：真人服務結束時呼叫 `return-to-ai`
* [ ] 兩個 Webhook 端點皆做冪等：轉真人事件與訊息推送都以各自的 `id`
* [ ] 情境 B：訊息 Webhook 已新增 Incoming 與 Outgoing 兩個方向，並以 `auto_reply_enabled` 判斷是否由真人處理
* [ ] 若您的網路需要來源 IP 白名單，請向對接窗口索取 MaiAgent 的出站 IP

## 相關頁面 <a href="#related" id="related"></a>

* [轉真人 Webhook 事件](https://docs.maiagent.ai/api/preparation/handoff-webhook)（API 文件）：事件完整規格、簽章驗證、可直接啟動的接收端範例
* [客服轉真人設定](https://docs.maiagent.ai/build/conversation-settings/human-handoff)（使用者手冊）：轉真人條件、服務時間、派工設定等後台欄位的操作說明
* [Webhook](/tech/serve/webhook.md)：訊息推送格式、自訂範本、以 API 管理 Webhook
* [Genesys Cloud 整合](/tech/serve/customer-service-system-integration/genesys-cloud-integration.md)：以 Genesys Cloud Open Messaging 串接，內建訊息格式、OAuth 與簽章驗證
* [建立對話與訊息](/tech/api-integration/conversations-and-messages.md)：建立對話與送出訊息的流程，欄位連到 API 文件
* [聯絡人身分同步與 Token 更新](/tech/serve/contacts/contact-credentials-sync.md)：`setup-contact-credentials` 完整規格
* [Presigned 檔案上傳模式](/tech/api-integration/api_knowledge.md)：附件上傳


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/tech/serve/customer-service-system-integration.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
