> 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/contacts.md).

# 聯絡人 (Contact) 介紹及串接

聯絡人（Contact）介紹及串接：以 sourceId 把自家系統使用者對應到終端使用者，建立與同步聯絡人的四種方式、Excel 批次匯入與實作建議。

## 聯絡人是什麼？ <a href="#what-is-contact" id="what-is-contact"></a>

聯絡人（Contact）代表「跟 Agent 對話的**終端使用者**」，不需要 MaiAgent 帳號。企業把自家系統的使用者以 `sourceId` 對應到聯絡人後，AI 就能認得「誰在問」，正確回溯這個人的對話歷史與權限設定。聯絡人的概念、匿名與非匿名聯絡人的差別，以及後台操作，見使用者手冊[聯絡人](https://docs.maiagent.ai/serve/daily-operations/contact)；和成員／角色的差別見[角色和聯絡人的差異](https://docs.maiagent.ai/org/roles/contact-role-comparison)。本頁只寫 API 串接。

### 聯絡人上可以掛什麼 <a href="#contact-capabilities" id="contact-capabilities"></a>

| 資料                            | 用途                           | 詳細說明                                                                                                                          |
| ----------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| 基本資料（`name`、`email`、`avatar`） | 顯示在後台聯絡人列表與對話記錄              | 本頁下方 API 說明                                                                                                                   |
| 自訂屬性（`metadata`）              | 部門、會員等級等背景資料，**AI 會讀取並帶入回答** | [聯絡人身分同步與 Token 更新](/tech/serve/contacts/contact-credentials-sync.md#sync-contact-profile)                                    |
| 查詢元資料（`query_metadata`）       | 限制該使用者可檢索的知識庫／文件／標籤範圍        | [知識管理權限（Query Metadata）](/tech/identity-and-access/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan.md) |
| MCP／API 工具憑證                  | 讓 AI 以**該使用者的身分與權限**呼叫外部工具   | [聯絡人身分同步與 Token 更新](/tech/serve/contacts/contact-credentials-sync.md)                                                         |
| 對話歷史                          | 跨裝置延續對話                      | 前端帶 `contactId` 即生效                                                                                                           |

## 建立與同步聯絡人的四條路 <a href="#three-paths" id="three-paths"></a>

| 方式                                        | 適合                                     | 說明                                                                                                                                                    |
| ----------------------------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **身分同步 API**（`setup-contact-credentials`） | 使用者登入時同步、要綁工具憑證、既有系統批次補建               | 冪等（同 `sourceId` 不重複建立）、免 API Key。含 Web Chat 前端 `auth` 自動呼叫的版本。**多數串接場景建議走這條**，詳見[聯絡人身分同步與 Token 更新](/tech/serve/contacts/contact-credentials-sync.md) |
| **聯絡人 API**（`POST /api/v1/contacts/`）     | 後端完全掌控聯絡人生命週期、需要建立時就設定 query\_metadata | 需要 API Key；更新用 `PATCH /api/v1/contacts/{contact_id}/`（只更新有傳入的欄位）。schema 見 [API 文件-聯絡人](https://docs.maiagent.ai/api/api-reference/lian-luo-ren)       |
| **批次匯入**（Excel）                           | 既有系統首次串接，一次補建大量使用者                     | 上限 10,000 列，可同時帶 query\_metadata 與 API 工具憑證，見[下方說明](#bulk-import)                                                                                     |
| **後台圖形化介面**                               | 少量、手動管理的場景                             | 見[下方操作說明](#tu-xing-hua-jie-mian-jian-li-lian-luo-ren)                                                                                                 |

四條路建立的是同一種聯絡人，可混用（例如首次串接用批次匯入、日常登入走身分同步）。

### 聯絡人 API 的請求欄位 <a href="#contact-api-fields" id="contact-api-fields"></a>

`POST /api/v1/contacts/` 的請求內容（camelCase 與 snake\_case 都接受）：

| 欄位                             | 必填     | 說明                                                                                                                               |
| ------------------------------ | ------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `name`                         | 是      | 顯示名稱，最長 255 字元                                                                                                                   |
| `inboxes`                      | 是（二擇一） | `[{"id": "<對話平台 ID>"}]`，聯絡人所屬的對話平台，必須屬於金鑰所在的組織；舊欄位 `inbox`（單一 `{"id": …}`）仍接受，兩者都帶時以 `inboxes` 為準，都沒帶回 `400`                     |
| `sourceId`                     | 否      | 您系統中的使用者 ID，最長 255 字元。同一個對話平台內不可重複，重複回 `400`；沒帶時這位聯絡人只能用 `contactId` 識別                                                          |
| `email`、`phoneNumber`、`avatar` | 否      | 基本資料；`avatar` 可填完整網址或平台相對路徑                                                                                                      |
| `metadata`                     | 否      | 自訂屬性，鍵值陣列格式見[聯絡人身分同步與 Token 更新](/tech/serve/contacts/contact-credentials-sync.md#sync-contact-profile)                           |
| `queryMetadata`                | 否      | 知識檢索範圍，格式見 [Query Metadata](/tech/identity-and-access/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan.md) |

最小的有效請求是 `{"name": "王小明", "inboxes": [{"id": "<對話平台 ID>"}]}`。回應 `201` 帶完整聯絡人物件，其中 `mcpCredentials`、`apiCredentials`、`contactConnectors`、`tags` 是唯讀欄位，憑證要用各自的端點寫入。

### 聯絡人的歸屬與可見範圍 <a href="#contact-ownership" id="contact-ownership"></a>

聯絡人屬於**組織**，不屬於建立它的 API 金鑰：同一組織內任何一把金鑰，只要綁定的成員具備聯絡人權限，都能讀取、更新與刪除同一位聯絡人；輪替金鑰後 `contactId` 與 `sourceId` 都照常可用。跨組織則完全看不到（回 `404`）。

### 成員登入後會不會變成聯絡人？ <a href="#member-as-contact" id="member-as-contact"></a>

會，但不是在登入時：成員（含 SSO 登入的成員）在 MaiGPT、後台測試對話等以平台帳號發起對話時，平台會在該對話平台上為這位成員建立（或沿用）一位 `sourceId` 等於其使用者 ID、並連結到該帳號的聯絡人；用 API 金鑰呼叫 `completions` 而不帶 `sender` 時也是同一條規則（見[省略 `message.sender` 時的身分](/tech/api-integration/dui-hua-yu-xun-xi-hui-fu-chuan-liu-tong-bu.md#anonymous-sender)）。因此掛在這位聯絡人上的 MCP／API 工具憑證與 `queryMetadata`，在成員自己的對話中同樣生效；聯絡人是依對話平台建立的，同一位成員在不同對話平台會有不同的聯絡人。成員的角色權限與聯絡人設定各自獨立，見[角色(Role) 和 聯絡人(Contact) 的差異](/tech/serve/contacts/role-vs-contact.md)。

## 串接流程 <a href="#e5-ae-8c-e6-95-b4-e6-b5-81-e7-a8-8b-e5-9c-96" id="e5-ae-8c-e6-95-b4-e6-b5-81-e7-a8-8b-e5-9c-96"></a>

```mermaid
sequenceDiagram
    participant CU as 使用者
    participant ES as 企業系統
    participant MA as MaiAgent
    CU ->> ES: 開啟網站並登入（具備企業系統的 user ID）
    ES ->> ES: 查會員資料：已有對應的 Contact ID？
    alt 尚無對應
        ES ->> MA: 建立聯絡人（身分同步 API 或 POST /api/v1/contacts/）
        MA -->> ES: 回傳 contactId
        ES ->> ES: contactId 存入會員資料表
    end
    ES ->> CU: 載入 Web Chat 嵌入碼（config 帶 contactId）
    CU ->> MA: Web Chat 以該聯絡人身分初始化
    MA -->> CU: 顯示該使用者的對話歷史與對應權限
```

三個步驟：

1. **檢查對應**：以企業系統的 user ID 查會員資料，確認是否已有 MaiAgent `contact_id`
2. **建立或更新**：沒有就建立（存回 `contact_id`）；使用者改了姓名／Email、或權限異動時，同步更新聯絡人（`PATCH /api/v1/contacts/{contact_id}/`），確保後續對話的個人化內容與權限正確
3. **初始化 Web Chat**：前端 config 帶 `contactId`，見 [Web Chat 嵌入與 SDK](/tech/serve/web-chat-sdk.md#identify-users)

{% hint style="info" %}
若您的場景是「使用者登入企業系統時，同步建立聯絡人並更新 Token 憑證」（例如讓 AI 以使用者權限呼叫 MCP 工具），請參考[聯絡人身分同步與 Token 更新](/tech/serve/contacts/contact-credentials-sync.md)，一次呼叫即可完成聯絡人建立與憑證綁定。
{% endhint %}

## 聯絡人批次匯入（Excel） <a href="#bulk-import" id="bulk-import"></a>

既有系統首次串接時，用 Excel 一次補建（或更新）大量聯絡人：

{% stepper %}
{% step %}

### 下載模板

`GET /api/v1/contacts/bulk-import-template/` 下載 Excel 模板（含標題列與範例列）。
{% endstep %}

{% step %}

### 填入資料

| 欄位                    | 必填 | 說明                                                                                                                                                                        |
| --------------------- | -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Name(required)`      | ✅  | 聯絡人顯示名稱                                                                                                                                                                   |
| `Email(required)`     | ✅  | 比對鍵之一（不分大小寫）                                                                                                                                                              |
| `Phone Number`        |    | 電話                                                                                                                                                                        |
| `Source ID(required)` | ✅  | 企業系統的使用者識別碼，比對鍵之一；請使用不可猜測的值（同[身分同步 API 的安全提醒](/tech/serve/contacts/contact-credentials-sync.md#request-body)）                                                             |
| `Query Metadata`      |    | JSON 物件，寫入聯絡人的知識查詢範圍；**空白儲存格＝保留既有值**。格式見 [JSON 格式指南](/tech/identity-and-access/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan/json-interfaces.md) |
| `API Credentials`     |    | JSON 陣列 `[{"tool": "<工具 ID>", "headers": {...}}]`，綁定 API 工具憑證；空白＝保留既有憑證                                                                                                   |
| {% endstep %}         |    |                                                                                                                                                                           |

{% step %}

### 上傳匯入

`POST /api/v1/contacts/bulk-import/`（`multipart/form-data`，`Authorization: Api-Key` 認證，與聯絡人 API 相同）：

* `file`：填好的 `.xlsx`（上限 10 MB、10,000 列）
* `inboxes`：收件匣 UUID 清單（至少一個）；之後要走 Web Chat 登入同步，請確認包含對應的 Web Chat 收件匣
* `inboxMode`（選填，預設 `replace`）：`replace` 時，每個匯入的聯絡人的收件匣集合會被**整份取代**為 `inboxes`；`merge` 時只加入 `inboxes`，保留聯絡人既有的收件匣
* `dryRun`（選填，預設 `false`）：`true` 時只解析與驗證檔案、回報將新增與更新的筆數，不寫入任何資料（回 `200`；正式匯入回 `201`）

回應：`{ "created": N, "updated": M, "dryRun": false }`

建議先以 `dryRun=true` 送一次，確認筆數符合預期再正式匯入。
{% endstep %}
{% endstepper %}

匯入的比對與更新規則：

* 以（`Source ID`、`Email`）為鍵做 upsert：命中既有聯絡人時更新姓名／電話／Query Metadata（空白儲存格不動），未命中則建立
* `API Credentials` 以（聯絡人、工具）為鍵 upsert；檔案中未提及的工具憑證不會被動到
* 整批在同一交易內完成：任一列格式錯誤（如欄位名不符、JSON 不合法）整批不寫入，錯誤訊息會標明列號

{% hint style="info" %}
匯入只建立對應與屬性；使用者的 Token 憑證仍由登入流程的[身分同步 API](/tech/serve/contacts/contact-credentials-sync.md) 在每次登入時更新。
{% endhint %}

## 圖形化介面建立聯絡人 <a href="#tu-xing-hua-jie-mian-jian-li-lian-luo-ren" id="tu-xing-hua-jie-mian-jian-li-lian-luo-ren"></a>

少量聯絡人可以在後台手動新增或以 Excel 批次匯入（含預覽），步驟見使用者手冊[新增聯絡人](https://docs.maiagent.ai/serve/daily-operations/contact#add-contact)與[批次匯入聯絡人](https://docs.maiagent.ai/serve/daily-operations/contact#bulk-import-contacts)。建立後可在聯絡人列表複製聯絡人 ID，即 Web Chat 初始化參數 `contactId`。

{% hint style="info" %}
聯絡人上設定的身分資訊，將用於查詢時產生對應的 `query_metadata` 條件組合。

[**👉 了解 Query Metadata**](/tech/identity-and-access/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan.md)
{% endhint %}

## 實作建議 <a href="#e5-af-a6-e4-bd-9c-e5-bb-ba-e8-a-d-b0" id="e5-af-a6-e4-bd-9c-e5-bb-ba-e8-a-d-b0"></a>

1. **會員資料表加一個對應欄位**（如 `maiagent_contact_id`，UUID、nullable），連同建立／更新時間一起記錄，確保企業 user ID ↔ Contact ID 的對應可追溯
2. **實作冪等**：建立前先查對應，或直接走身分同步 API（`sourceId` 冪等，重跑不會產生重複聯絡人）
3. **記錄 API 呼叫 log**，方便追查對應異常
4. **非同步呼叫**：聯絡人相關 API 與登入流程其他請求平行執行，失敗不阻擋使用者登入、下次登入重試


---

# 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/contacts.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.
