> 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/api/api-reference/dui-hua-ping-tai.md).

# 對話平台

對話平台（Inbox）是對話的歸屬單位，也是 Webhook 的設定位置：每個對話平台可以設定多組 Webhook，在使用者訊息進入（`incoming`）或 Agent 回覆（`outgoing`）時推送到您的系統。Web Chat 類型的對話平台另有 [Web Chat 端點](/api/api-reference/dui-hua-widget.md)。設定方式與 payload 格式見技術手冊 [Webhook](https://docs.maiagent.ai/tech/api-integration/webhook)。

### 列出對話平台 <a href="#inboxes-list" id="inboxes-list"></a>

GET `/api/v1/inboxes/`

#### 參數

| 參數名稱          | 必填 | 類型      | 說明                                                                      |
| ------------- | -- | ------- | ----------------------------------------------------------------------- |
| `accessType`  | ❌  | string  | 存取類型過濾                                                                  |
| `channelType` | ❌  | string  | 頻道類型過濾                                                                  |
| `chatbot`     | ❌  | string  | 聊天機器人 ID 過濾                                                             |
| `isActive`    | ❌  | boolean | 是否啟用過濾                                                                  |
| `ordering`    | ❌  | string  | Which field to use when ordering the results.                           |
| `page`        | ❌  | integer | A page number within the paginated result set.                          |
| `pageSize`    | ❌  | integer | Number of results to return per page.                                   |
| `pagination`  | ❌  | string  | 是否分頁 (true/false)。當設為 false 時，會回傳簡化版的資料格式                               |
| `query`       | ❌  | string  |                                                                         |
| `source`      | ❌  | string  | \`self\_built\`: self\_built ; \`built\_in\`: built\_in ; \`all\`: all; |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/inboxes/?accessType=example&channelType=example&chatbot=example&isActive=true&ordering=example&page=1&pageSize=1&pagination=example&query=example&source=all" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/inboxes/?accessType=example&channelType=example&chatbot=example&isActive=true&ordering=example&page=1&pageSize=1&pagination=example&query=example&source=all", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/?accessType=example&channelType=example&chatbot=example&isActive=true&ordering=example&page=1&pageSize=1&pagination=example&query=example&source=all"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/inboxes/?accessType=example&channelType=example&chatbot=example&isActive=true&ordering=example&page=1&pageSize=1&pagination=example&query=example&source=all", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200 - 對話平台列表**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string (uuid)
      "name": string
      "channelType": string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber
      "unreadConversationsCount"?: integer // 非必填
      "signAuth"?:  // 非必填
      {
        "id": string (uuid)
        "signSource": string (uuid)
        "signParams": {
        {
          "keycloak": 
          {
            "clientId": string
            "url": string
            "realm": string
          }
          "line": 
          {
            "liffId": string
          }
          "ad": 
          {
            "saml": string
          }
          "google"?:  // 非必填
          {
            "enabled": boolean
          }
        }
        }
        "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
        "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
        {
        }
        "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
        {
        }
        "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
        "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
          string
        ]
        "organizationLogin": object // How visitors sign in when the sign source is "organization" (mirrors the back-office login); null for other sign sources
      }
      "enableAnalysis"?: boolean // 非必填
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "961dcaac-bd2e-44d3-9050-82596dbb3334",
      "chatbot": {
        "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b",
        "name": "客服機器人",
        "groups": [],
        "largeLanguageModel": {
          "id": "933aa8b3-cdf4-47a7-86d5-b5dc27fbb044",
          "name": "llm"
        },
        "embeddingModel": {
          "id": "aefcc4f9-917d-4a8a-bd36-d97e3b7cecfe",
          "name": "embedding",
          "icon": null,
          "isDefault": false
        },
        "rerankerModel": {
          "id": "86c2ddfd-0df9-47b9-8f3b-0c42e3347da3",
          "name": "rerank",
          "icon": null,
          "isDefault": true
        },
        "knowledgeBases": [],
        "tools": [],
        "agentMode": "normal",
        "replyMode": "normal",
        "updatedAt": "1739519493000",
        "enableEvaluation": false,
        "enableInlineCitations": false,
        "enableKnowledgeBaseRag": true,
        "enableAgenticTextToSql": true,
        "enableToolSearching": true,
        "numberOfRetrievedChunks": 12
      },
      "groups": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "name": "管理員群組"
        }
      ],
      "channelType": "web",
      "channelTypeLabel": "Web",
      "name": "1345",
      "autoReplySchedules": [
        {
          "id": "2f4f6383-d8b5-4d88-b4a1-6d02d731f2a6",
          "weekday": 0,
          "isEnabled": true,
          "timeSlots": [
            [
              "00:00:00",
              "00:00:00"
            ]
          ],
          "weekdayName": "Monday"
        },
        {
          "id": "2866f624-a5c3-4ffb-b980-0f8d6a9f0c93",
          "weekday": 1,
          "isEnabled": true,
          "timeSlots": [
            [
              "00:00:00",
              "00:00:00"
            ]
          ],
          "weekdayName": "Tuesday"
        },
        {
          "id": "3cf1e488-fb13-426d-bd59-e62bd71aca85",
          "weekday": 2,
          "isEnabled": true,
          "timeSlots": [
            [
              "00:00:00",
              "00:00:00"
            ]
          ],
          "weekdayName": "Wednesday"
        },
        {
          "id": "491776a9-fcf1-4e2e-892f-6d9ad5aebea4",
          "weekday": 3,
          "isEnabled": true,
          "timeSlots": [
            [
              "00:00:00",
              "00:00:00"
            ]
          ],
          "weekdayName": "Thursday"
        },
        {
          "id": "dfecb0a9-5001-4aa0-b2cc-5459b6d64351",
          "weekday": 4,
          "isEnabled": true,
          "timeSlots": [
            [
              "00:00:00",
              "00:00:00"
            ]
          ],
          "weekdayName": "Friday"
        },
        {
          "id": "68b6b4d1-7ac8-450f-8877-41b72b499919",
          "weekday": 5,
          "isEnabled": true,
          "timeSlots": [
            [
              "00:00:00",
              "00:00:00"
            ]
          ],
          "weekdayName": "Saturday"
        },
        {
          "id": "15228ea1-4513-4504-81f4-4e486703d8b9",
          "weekday": 6,
          "isEnabled": true,
          "timeSlots": [
            [
              "00:00:00",
              "00:00:00"
            ]
          ],
          "weekdayName": "Sunday"
        }
      ],
      "unreadConversationsCount": 0,
      "totalConversationsCount": 42,
      "channel": {
        "id": "801a690a-1038-4fdd-8aba-bf003b12c3ef",
        "name": "1345",
        "avatar": "https://media-dev.maiagent.ai/static/images/default-chatbot-avatar.png",
        "logo": null,
        "description": "",
        "cover": null,
        "backUrl": "",
        "isActive": true,
        "enableSpeech": false,
        "displayGreeting": null,
        "displayConversationStarters": [],
        "theme": {
          "primaryColor": "#3854d8",
          "navbarTextColor": "#ffffff",
          "conversationBackgroundColor": "#ffffff",
          "chatbotMessageTextColor": "#374151",
          "userMessageTextColor": "#374151",
          "chatbotMessageBackgroundColor": "#DCE9F6",
          "userMessageBackgroundColor": "#DDEAF6",
          "chatbotMessageBackgroundShadowEnabled": true,
          "userMessageBackgroundShadowEnabled": true
        },
        "darkTheme": {
          "primaryColor": "#404040",
          "navbarTextColor": "#ffffff",
          "conversationBackgroundColor": "#18181B",
          "chatbotMessageTextColor": "#ffffff",
          "userMessageTextColor": "#ffffff",
          "chatbotMessageBackgroundColor": "#171717",
          "userMessageBackgroundColor": "#333842",
          "chatbotMessageBackgroundShadowEnabled": false,
          "userMessageBackgroundShadowEnabled": false
        },
        "enableFileUpload": true,
        "enableDisplayCitations": true,
        "enableShareConversation": false,
        "enableLocation": false,
        "enableShowPoweredBy": true,
        "enableDisplayChatbotAvatar": true,
        "enableDisplayChatbotName": true,
        "enableDisplayPreviousConversation": true,
        "enableDisplayConversationHistory": true,
        "enableConversationTimer": false,
        "conversationTimerDuration": null,
        "enableAutoNewConversationOnTimeout": false,
        "accessType": "api",
        "greetings": [],
        "greetingsByLocale": {
          "en": [
            "Hello, how can I help you?"
          ],
          "zh-hant": [
            "你好，我可以幫你什麼嗎？"
          ],
          "ja": [
            "こんにちは、何かお手伝いできますか？"
          ],
          "ko": [
            "안녕하세요, 무엇을 도와드릴까요?"
          ]
        },
        "conversationStarters": [],
        "conversationStartersByLocale": {
          "en": [
            "What can I help you with today?"
          ],
          "zh-hant": [
            "你今天需要什麼幫助？"
          ],
          "ja": [
            "今日は何かお手伝いできますか？"
          ],
          "ko": [
            "오늘 뭘 도와줄수있어？"
          ]
        }
      },
      "webhooks": [],
      "createdAt": "1739519493000",
      "updatedAt": "1739519493000",
      "organization": "24b619d9-e981-4a8b-96da-63dc4f96bda6",
      "signAuth": null
    }
  ]
}
```

***

### 建立對話平台 <a href="#inboxes-create" id="inboxes-create"></a>

POST `/api/v1/inboxes/`

#### 請求內容

**請求參數**

| 欄位                                            | 類型                                                                                                                      | 必填 | 說明                                                                                                                                                                                                           |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name                                          | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| channelType                                   | string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team\_plus, line\_works, viber) | 是  | `line`: LINE ; `telegram`: Telegram ; `teams`: Teams ; `web`: Web ; `messenger`: Messenger ; `instagram`: Instagram ; `email`: Email ; `whatsapp`: WhatsApp ; `slack`: Slack ; `team_plus`: Team+ ; \`lin... |
| unreadConversationsCount                      | integer                                                                                                                 | 否  |                                                                                                                                                                                                              |
| signAuth                                      | object (含 9 個屬性: id, signSource, signParams...)                                                                         | 否  |                                                                                                                                                                                                              |
| signAuth.signSource                           | string (uuid)                                                                                                           | 是  |                                                                                                                                                                                                              |
| signAuth.signParams                           | object                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak                  | object (含 3 個屬性: clientId, url, realm)                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.clientId         | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.url              | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.realm            | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.line                      | object (含 1 個屬性: liffId)                                                                                                | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.line.liffId               | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.ad                        | object (含 1 個屬性: saml)                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.ad.saml                   | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.google                    | object (含 1 個屬性: enabled)                                                                                               | 否  |                                                                                                                                                                                                              |
| signAuth.signParams.google.enabled            | boolean                                                                                                                 | 是  |                                                                                                                                                                                                              |
| signAuth.sourceIdAccessEnabled                | boolean                                                                                                                 | 否  | When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged.                 |
| signAuth.sourceIdVerifyMode                   | object                                                                                                                  | 否  | "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testin...  |
| signAuth.sourceIdSignatureTtlMinutes          | object                                                                                                                  | 否  | How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism. `1`: 1 ; `5`: 5 ; `15`: 15;                     |
| signAuth.keycloakTokenPassthrough             | boolean                                                                                                                 | 否  | When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-to...  |
| signAuth.keycloakTokenPassthroughAllowedHosts | array\[string]                                                                                                          | 否  | Hostnames (or "\*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to                                                                                                             |
| enableAnalysis                                | boolean                                                                                                                 | 否  |                                                                                                                                                                                                              |

**請求結構範例**

```typescript
{
  "name": string
  "channelType": string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber
  "unreadConversationsCount"?: integer // 非必填
  "signAuth"?:  // 非必填
  {
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // 非必填
      {
        "enabled": boolean
      }
    }
    }
    "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
    "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
    {
    }
    "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
    {
    }
    "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
      string
    ]
  }
  "enableAnalysis"?: boolean // 非必填
}
```

**請求範例值**

```json
{
  "chatbot": {
    "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
  },
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "name": "更新後的名稱"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/inboxes/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "更新後的名稱"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "更新後的名稱"
  };

axios.post("https://api.maiagent.ai/api/v1/inboxes/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "chatbot": {
        "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
        {
            "id": "550e8400-e29b-41d4-a716-446655440000"
        }
    ],
    "name": "更新後的名稱"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/inboxes/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'chatbot' => [
                'id' => '80f3170d-eed7-4651-a8da-6b7e6bdbef8b'
            ],
            'groups' => [
                [
                    'id' => '550e8400-e29b-41d4-a716-446655440000'
                ]
            ],
            'name' => '更新後的名稱'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "channelType": string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber
  "unreadConversationsCount"?: integer // 非必填
  "signAuth"?:  // 非必填
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // 非必填
      {
        "enabled": boolean
      }
    }
    }
    "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
    "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
    {
    }
    "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
    {
    }
    "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
      string
    ]
    "organizationLogin": object // How visitors sign in when the sign source is "organization" (mirrors the back-office login); null for other sign sources
  }
  "enableAnalysis"?: boolean // 非必填
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "channelType": "line",
  "unreadConversationsCount": 456,
  "signAuth": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "signSource": "550e8400-e29b-41d4-a716-446655440000",
    "signParams": {
      "keycloak": {
        "clientId": "回應字串",
        "url": "回應字串",
        "realm": "回應字串"
      },
      "line": {
        "liffId": "回應字串"
      },
      "ad": {
        "saml": "回應字串"
      },
      "google": {
        "enabled": false
      }
    },
    "sourceIdAccessEnabled": false,
    "sourceIdVerifyMode": {},
    "sourceIdSignatureTtlMinutes": {},
    "keycloakTokenPassthrough": false,
    "keycloakTokenPassthroughAllowedHosts": [
      "回應字串"
    ],
    "organizationLogin": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  },
  "enableAnalysis": false
}
```

***

### 取得特定對話平台 <a href="#inboxes-retrieve" id="inboxes-retrieve"></a>

GET `/api/v1/inboxes/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                    |
| ---- | -- | ------ | ------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this Inbox. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "channelType": string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber
  "unreadConversationsCount"?: integer // 非必填
  "signAuth"?:  // 非必填
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // 非必填
      {
        "enabled": boolean
      }
    }
    }
    "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
    "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
    {
    }
    "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
    {
    }
    "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
      string
    ]
    "organizationLogin": object // How visitors sign in when the sign source is "organization" (mirrors the back-office login); null for other sign sources
  }
  "enableAnalysis"?: boolean // 非必填
}
```

**回應範例值**

```json
{
  "id": "961dcaac-bd2e-44d3-9050-82596dbb3334",
  "chatbot": {
    "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b",
    "name": "客服機器人",
    "groups": [],
    "largeLanguageModel": {
      "id": "933aa8b3-cdf4-47a7-86d5-b5dc27fbb044",
      "name": "llm"
    },
    "embeddingModel": {
      "id": "aefcc4f9-917d-4a8a-bd36-d97e3b7cecfe",
      "name": "embedding",
      "icon": null,
      "isDefault": false
    },
    "rerankerModel": {
      "id": "86c2ddfd-0df9-47b9-8f3b-0c42e3347da3",
      "name": "rerank",
      "icon": null,
      "isDefault": true
    },
    "knowledgeBases": [],
    "tools": [],
    "agentMode": "normal",
    "replyMode": "normal",
    "updatedAt": "1739519493000",
    "enableEvaluation": false,
    "enableInlineCitations": false,
    "enableKnowledgeBaseRag": true,
    "enableAgenticTextToSql": true,
    "enableToolSearching": true,
    "numberOfRetrievedChunks": 12
  },
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "管理員群組"
    }
  ],
  "channelType": "web",
  "channelTypeLabel": "Web",
  "name": "1345",
  "autoReplySchedules": [
    {
      "id": "2f4f6383-d8b5-4d88-b4a1-6d02d731f2a6",
      "weekday": 0,
      "isEnabled": true,
      "timeSlots": [
        [
          "00:00:00",
          "00:00:00"
        ]
      ],
      "weekdayName": "Monday"
    },
    {
      "id": "2866f624-a5c3-4ffb-b980-0f8d6a9f0c93",
      "weekday": 1,
      "isEnabled": true,
      "timeSlots": [
        [
          "00:00:00",
          "00:00:00"
        ]
      ],
      "weekdayName": "Tuesday"
    },
    {
      "id": "3cf1e488-fb13-426d-bd59-e62bd71aca85",
      "weekday": 2,
      "isEnabled": true,
      "timeSlots": [
        [
          "00:00:00",
          "00:00:00"
        ]
      ],
      "weekdayName": "Wednesday"
    },
    {
      "id": "491776a9-fcf1-4e2e-892f-6d9ad5aebea4",
      "weekday": 3,
      "isEnabled": true,
      "timeSlots": [
        [
          "00:00:00",
          "00:00:00"
        ]
      ],
      "weekdayName": "Thursday"
    },
    {
      "id": "dfecb0a9-5001-4aa0-b2cc-5459b6d64351",
      "weekday": 4,
      "isEnabled": true,
      "timeSlots": [
        [
          "00:00:00",
          "00:00:00"
        ]
      ],
      "weekdayName": "Friday"
    },
    {
      "id": "68b6b4d1-7ac8-450f-8877-41b72b499919",
      "weekday": 5,
      "isEnabled": true,
      "timeSlots": [
        [
          "00:00:00",
          "00:00:00"
        ]
      ],
      "weekdayName": "Saturday"
    },
    {
      "id": "15228ea1-4513-4504-81f4-4e486703d8b9",
      "weekday": 6,
      "isEnabled": true,
      "timeSlots": [
        [
          "00:00:00",
          "00:00:00"
        ]
      ],
      "weekdayName": "Sunday"
    }
  ],
  "unreadConversationsCount": 0,
  "totalConversationsCount": 42,
  "channel": {
    "id": "801a690a-1038-4fdd-8aba-bf003b12c3ef",
    "name": "1345",
    "avatar": "https://media-dev.maiagent.ai/static/images/default-chatbot-avatar.png",
    "logo": null,
    "description": "",
    "cover": null,
    "backUrl": "",
    "isActive": true,
    "enableSpeech": false,
    "displayGreeting": null,
    "displayConversationStarters": [],
    "theme": {
      "primaryColor": "#3854d8",
      "navbarTextColor": "#ffffff",
      "conversationBackgroundColor": "#ffffff",
      "chatbotMessageTextColor": "#374151",
      "userMessageTextColor": "#374151",
      "chatbotMessageBackgroundColor": "#DCE9F6",
      "userMessageBackgroundColor": "#DDEAF6",
      "chatbotMessageBackgroundShadowEnabled": true,
      "userMessageBackgroundShadowEnabled": true
    },
    "darkTheme": {
      "primaryColor": "#404040",
      "navbarTextColor": "#ffffff",
      "conversationBackgroundColor": "#18181B",
      "chatbotMessageTextColor": "#ffffff",
      "userMessageTextColor": "#ffffff",
      "chatbotMessageBackgroundColor": "#171717",
      "userMessageBackgroundColor": "#333842",
      "chatbotMessageBackgroundShadowEnabled": false,
      "userMessageBackgroundShadowEnabled": false
    },
    "enableFileUpload": true,
    "enableDisplayCitations": true,
    "enableShareConversation": false,
    "enableLocation": false,
    "enableShowPoweredBy": true,
    "enableDisplayChatbotAvatar": true,
    "enableDisplayChatbotName": true,
    "enableDisplayPreviousConversation": true,
    "enableDisplayConversationHistory": true,
    "enableConversationTimer": false,
    "conversationTimerDuration": null,
    "enableAutoNewConversationOnTimeout": false,
    "accessType": "api",
    "greetings": [],
    "greetingsByLocale": {
      "en": [
        "Hello, how can I help you?"
      ],
      "zh-hant": [
        "你好，我可以幫你什麼嗎？"
      ],
      "ja": [
        "こんにちは、何かお手伝いできますか？"
      ],
      "ko": [
        "안녕하세요, 무엇을 도와드릴까요?"
      ]
    },
    "conversationStarters": [],
    "conversationStartersByLocale": {
      "en": [
        "What can I help you with today?"
      ],
      "zh-hant": [
        "你今天需要什麼幫助？"
      ],
      "ja": [
        "今日は何かお手伝いできますか？"
      ],
      "ko": [
        "오늘 뭘 도와줄수있어？"
      ]
    }
  },
  "webhooks": [],
  "createdAt": "1739519493000",
  "updatedAt": "1739519493000",
  "organization": "24b619d9-e981-4a8b-96da-63dc4f96bda6",
  "signAuth": null
}
```

***

### 更新對話平台 <a href="#inboxes-update" id="inboxes-update"></a>

PUT `/api/v1/inboxes/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                    |
| ---- | -- | ------ | ------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this Inbox. |

#### 請求內容

**請求參數**

| 欄位                                            | 類型                                                                                                                      | 必填 | 說明                                                                                                                                                                                                           |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name                                          | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| channelType                                   | string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team\_plus, line\_works, viber) | 是  | `line`: LINE ; `telegram`: Telegram ; `teams`: Teams ; `web`: Web ; `messenger`: Messenger ; `instagram`: Instagram ; `email`: Email ; `whatsapp`: WhatsApp ; `slack`: Slack ; `team_plus`: Team+ ; \`lin... |
| unreadConversationsCount                      | integer                                                                                                                 | 否  |                                                                                                                                                                                                              |
| signAuth                                      | object (含 9 個屬性: id, signSource, signParams...)                                                                         | 否  |                                                                                                                                                                                                              |
| signAuth.signSource                           | string (uuid)                                                                                                           | 是  |                                                                                                                                                                                                              |
| signAuth.signParams                           | object                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak                  | object (含 3 個屬性: clientId, url, realm)                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.clientId         | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.url              | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.realm            | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.line                      | object (含 1 個屬性: liffId)                                                                                                | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.line.liffId               | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.ad                        | object (含 1 個屬性: saml)                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.ad.saml                   | string                                                                                                                  | 是  |                                                                                                                                                                                                              |
| signAuth.signParams.google                    | object (含 1 個屬性: enabled)                                                                                               | 否  |                                                                                                                                                                                                              |
| signAuth.signParams.google.enabled            | boolean                                                                                                                 | 是  |                                                                                                                                                                                                              |
| signAuth.sourceIdAccessEnabled                | boolean                                                                                                                 | 否  | When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged.                 |
| signAuth.sourceIdVerifyMode                   | object                                                                                                                  | 否  | "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testin...  |
| signAuth.sourceIdSignatureTtlMinutes          | object                                                                                                                  | 否  | How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism. `1`: 1 ; `5`: 5 ; `15`: 15;                     |
| signAuth.keycloakTokenPassthrough             | boolean                                                                                                                 | 否  | When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-to...  |
| signAuth.keycloakTokenPassthroughAllowedHosts | array\[string]                                                                                                          | 否  | Hostnames (or "\*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to                                                                                                             |
| enableAnalysis                                | boolean                                                                                                                 | 否  |                                                                                                                                                                                                              |

**請求結構範例**

```typescript
{
  "name": string
  "channelType": string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber
  "unreadConversationsCount"?: integer // 非必填
  "signAuth"?:  // 非必填
  {
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // 非必填
      {
        "enabled": boolean
      }
    }
    }
    "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
    "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
    {
    }
    "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
    {
    }
    "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
      string
    ]
  }
  "enableAnalysis"?: boolean // 非必填
}
```

**請求範例值**

```json
{
  "chatbot": {
    "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
  },
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "name": "更新後的名稱"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PUT "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "更新後的名稱"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "更新後的名稱"
  };

axios.put("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "chatbot": {
        "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
        {
            "id": "550e8400-e29b-41d4-a716-446655440000"
        }
    ],
    "name": "更新後的名稱"
}

response = requests.put(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->put("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'chatbot' => [
                'id' => '80f3170d-eed7-4651-a8da-6b7e6bdbef8b'
            ],
            'groups' => [
                [
                    'id' => '550e8400-e29b-41d4-a716-446655440000'
                ]
            ],
            'name' => '更新後的名稱'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "channelType": string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber
  "unreadConversationsCount"?: integer // 非必填
  "signAuth"?:  // 非必填
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // 非必填
      {
        "enabled": boolean
      }
    }
    }
    "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
    "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
    {
    }
    "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
    {
    }
    "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
      string
    ]
    "organizationLogin": object // How visitors sign in when the sign source is "organization" (mirrors the back-office login); null for other sign sources
  }
  "enableAnalysis"?: boolean // 非必填
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "channelType": "line",
  "unreadConversationsCount": 456,
  "signAuth": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "signSource": "550e8400-e29b-41d4-a716-446655440000",
    "signParams": {
      "keycloak": {
        "clientId": "回應字串",
        "url": "回應字串",
        "realm": "回應字串"
      },
      "line": {
        "liffId": "回應字串"
      },
      "ad": {
        "saml": "回應字串"
      },
      "google": {
        "enabled": false
      }
    },
    "sourceIdAccessEnabled": false,
    "sourceIdVerifyMode": {},
    "sourceIdSignatureTtlMinutes": {},
    "keycloakTokenPassthrough": false,
    "keycloakTokenPassthroughAllowedHosts": [
      "回應字串"
    ],
    "organizationLogin": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  },
  "enableAnalysis": false
}
```

***

### 部分更新對話平台 <a href="#inboxes-partial-update" id="inboxes-partial-update"></a>

PATCH `/api/v1/inboxes/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                    |
| ---- | -- | ------ | ------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this Inbox. |

#### 請求內容

**請求參數**

| 欄位                                            | 類型                                                                                                                      | 必填 | 說明                                                                                                                                                                                                              |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| groups                                        | array\[IdName]                                                                                                          | 否  | 可存取此收件匣的群組列表                                                                                                                                                                                                    |
| channelType                                   | string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team\_plus, line\_works, viber) | 否  | `line`: LINE ; `telegram`: Telegram ; `teams`: Teams ; `web`: Web ; `messenger`: Messenger ; `instagram`: Instagram ; `email`: Email ; `whatsapp`: WhatsApp ; `slack`: Slack ; `team_plus`: Team+ ; \`lin...    |
| name                                          | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| autoReplySchedules                            | array\[AutoReplySchedule]                                                                                               | 否  |                                                                                                                                                                                                                 |
| channel                                       | object                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| organization                                  | string (uuid)                                                                                                           | 否  |                                                                                                                                                                                                                 |
| signAuth                                      | object (含 10 個屬性: id, signSource, signParams...)                                                                        | 否  |                                                                                                                                                                                                                 |
| signAuth.signSource                           | string (uuid)                                                                                                           | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams                           | object                                                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak                  | object (含 3 個屬性: clientId, url, realm)                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak.clientId         | string                                                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak.url              | string                                                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak.realm            | string                                                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.line                      | object (含 1 個屬性: liffId)                                                                                                | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.line.liffId               | string                                                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.ad                        | object (含 1 個屬性: saml)                                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.ad.saml                   | string                                                                                                                  | 是  |                                                                                                                                                                                                                 |
| signAuth.signParams.google                    | object (含 1 個屬性: enabled)                                                                                               | 否  |                                                                                                                                                                                                                 |
| signAuth.signParams.google.enabled            | boolean                                                                                                                 | 是  |                                                                                                                                                                                                                 |
| signAuth.sourceIdAccessEnabled                | boolean                                                                                                                 | 否  | When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged.                    |
| signAuth.sourceIdVerifyMode                   | object                                                                                                                  | 否  | "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testin...     |
| signAuth.sourceIdSignatureTtlMinutes          | object                                                                                                                  | 否  | How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism. `1`: 1 ; `5`: 5 ; `15`: 15;                        |
| signAuth.keycloakTokenPassthrough             | boolean                                                                                                                 | 否  | When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-to...     |
| signAuth.keycloakTokenPassthroughAllowedHosts | array\[string]                                                                                                          | 否  | Hostnames (or "\*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to                                                                                                                |
| enableTimeAwareResponse                       | boolean                                                                                                                 | 否  | Enable time aware responses for this inbox                                                                                                                                                                      |
| defaultTimezone                               | string                                                                                                                  | 否  | Default timezone for this inbox (e.g., Asia/Taipei, America/New\_York)                                                                                                                                          |
| enableSenderNameAwareResponse                 | boolean                                                                                                                 | 否  | Enable sender name aware responses for this inbox                                                                                                                                                               |
| enableGpsAwareResponse                        | boolean                                                                                                                 | 否  | Enable GPS aware responses for this inbox                                                                                                                                                                       |
| gpsRequestTiming                              | object                                                                                                                  | 否  | Web chat only. "on\_open" asks the browser for the location as soon as the chat opens (current behavior); "on\_demand" asks only when the AI requests it through an ask\_user\_question question carrying ex... |
| enableAiLineSticker                           | boolean                                                                                                                 | 否  | LINE inboxes only. When on, the AI may attach one LINE official sticker to a reply (from the global LINE AI sticker list).                                                                                      |
| enableOcr                                     | boolean                                                                                                                 | 否  | Retired: attachments pick their parser by content detection (image-heavy files go to the Vision Parser, billed by token; scanned and text files to the MaiAgent Parser, scanned pages billed as OCR) and...     |
| enableAgentAttachmentDecision                 | boolean                                                                                                                 | 否  | Kill switch for AGENT-mode attachment handling. When False (default), AGENT-mode chatbots skip auto-embedding on upload and let the agent handle attachments at runtime via ParseAttachmentContentTool /...     |
| enableStreamMessage                           | boolean                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| enableHumanHandoff                            | boolean                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| handoffPrompt                                 | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| handoffLlm                                    | string (uuid)                                                                                                           | 否  |                                                                                                                                                                                                                 |
| handoffContextMessageLimit                    | integer                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| handoffMessage                                | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| queuingMessage                                | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| assignedMessage                               | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| enablePendingReplyMessage                     | boolean                                                                                                                 | 否  | Send a placeholder message to the user while the AI is processing.                                                                                                                                              |
| pendingReplyMessage                           | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| pendingReplyInitialDelaySeconds               | integer                                                                                                                 | 否  | Delay before sending the first pending reply, so a fast AI response can pre-empt it.                                                                                                                            |
| pendingReplyIntervalSeconds                   | integer                                                                                                                 | 否  | Interval to repeat the pending reply while the AI is still processing.                                                                                                                                          |
| enablePendingReplyCleanup                     | boolean                                                                                                                 | 否  | Delete pending reply messages after the AI reply is sent. Only effective on platforms that support message deletion (Teams, Telegram, Slack).                                                                   |
| enableAnalysis                                | boolean                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| analysisLlm                                   | string (uuid)                                                                                                           | 否  |                                                                                                                                                                                                                 |
| analysisPrompt                                | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| analysisContextMessageLimit                   | integer                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| analysisGenerateSummary                       | boolean                                                                                                                 | 否  | When on, conversation analysis writes the conversation summary (editable, with revisions); inbox auto split brings it to the next conversation                                                                  |
| analysisApplyTags                             | boolean                                                                                                                 | 否  | When on, conversation analysis picks the conversation tags from the inbox tags                                                                                                                                  |
| enableServiceHours                            | boolean                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| serviceHoursTimezone                          | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| offlineBehavior                               | string (enum: show\_message, leave\_message)                                                                            | 否  | `show_message`: Show Message ; `leave_message`: Leave Message;                                                                                                                                                  |
| offlineMessage                                | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| serviceHoursSchedules                         | array\[ServiceHoursSchedule]                                                                                            | 否  |                                                                                                                                                                                                                 |
| dispatchMode                                  | object                                                                                                                  | 否  | Auto dispatch assigns transferred conversations to an agent automatically. Claim (handover) leaves them unassigned for online agents to pick up themselves; timeout reassignment does not apply and the ...     |
| assignmentRoutingModel                        | string (enum: round\_robin, least\_active)                                                                              | 否  | `round_robin`: Round Robin ; `least_active`: Least Active;                                                                                                                                                      |
| assignmentMaxConcurrent                       | integer                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| assignmentQueueTimeout                        | integer                                                                                                                 | 否  | Queue timeout in seconds                                                                                                                                                                                        |
| queueTimeoutMessage                           | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| maxQueueSize                                  | integer                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| queueFullMessage                              | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| assignmentTargetMembers                       | array\[string]                                                                                                          | 否  |                                                                                                                                                                                                                 |
| enableTagRouting                              | boolean                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| enableReassignOnTimeout                       | boolean                                                                                                                 | 否  | When on, a queued or assigned-but-unanswered conversation that times out is reassigned to the next available agent (skipping already-tried agents) instead of returning straight to the AI; it only retu...     |
| enableQueueReminder                           | boolean                                                                                                                 | 否  | Reply with a throttled waiting reminder when the contact sends messages while queued.                                                                                                                           |
| queueReminderMessage                          | string                                                                                                                  | 否  |                                                                                                                                                                                                                 |
| queueReminderCooldown                         | integer                                                                                                                 | 否  | Minimum seconds between queue reminders in one conversation                                                                                                                                                     |
| enableQueueCancel                             | boolean                                                                                                                 | 否  | Allow the contact to cancel a queued handoff and return to the AI by themselves.                                                                                                                                |
| queueCancelButtonText                         | string                                                                                                                  | 否  | Label of the cancel quick-reply button. Its text also counts as a cancel keyword, so tapping the button always cancels even when the keyword list changes.                                                      |
| queueCancelKeywords                           | object                                                                                                                  | 否  | Messages matching one of these exactly (after stripping surrounding whitespace) cancel the queued handoff. Empty means no keyword matching (the cancel button text still matches); the serializer requir...     |
| queueCancelMessage                            | string                                                                                                                  | 否  | Sent to the contact right after they cancel the queued handoff.                                                                                                                                                 |
| enableIdleAutoResolve                         | boolean                                                                                                                 | 否  | Resolve a conversation served by a human agent once the agent replied last and the contact has not answered for the idle minutes. Frees the agent slot; queued conversations and ones where the contact ...     |
| idleAutoResolveMinutes                        | integer                                                                                                                 | 否  | Minutes the contact may stay silent after the last agent reply before auto resolve                                                                                                                              |
| idleAutoResolveMessage                        | string                                                                                                                  | 否  | Sent to the contact when the conversation is auto resolved; blank sends nothing. LINE delivers it as a push message (counts toward the LINE message quota); Messenger / Instagram / WhatsApp skip it onc...     |
| enableAgentReplyTimeout                       | boolean                                                                                                                 | 否  | When on, a conversation served by a human agent returns to the AI once a contact message has gone unanswered by any agent for the configured seconds; the AI then answers the last unanswered message. A...     |
| agentReplyTimeout                             | integer                                                                                                                 | 否  | Seconds (60-86400) a contact message may go unanswered by a human agent before the AI takes over                                                                                                                |
| agentReplyTimeoutMessage                      | string                                                                                                                  | 否  | Sent to the contact when the conversation returns to the AI; leave empty to send none.                                                                                                                          |
| enableReturnToPreviousAssignee                | boolean                                                                                                                 | 否  | When on, a resolved conversation the contact writes to again within the configured hours reopens assigned to the agent who held it instead of to the AI. It still reopens to the AI when that agent is o...     |
| returnToPreviousAssigneeHours                 | integer                                                                                                                 | 否  | Hours (1-720), counted from when the conversation was resolved, during which a returning contact goes back to the agent who held it                                                                             |
| enableAutoSplit                               | boolean                                                                                                                 | 否  | When on, a one-to-one contact writing again after the conversation was resolved or went idle for the configured time starts a new conversation instead of continuing the old one. Web inboxes and group ...     |
| autoSplitOnResolve                            | boolean                                                                                                                 | 否  | Split when the latest conversation was resolved more than the configured minutes ago                                                                                                                            |
| autoSplitResolveMinutes                       | integer                                                                                                                 | 否  | Minutes (0-10080) after the latest resolve; 0 splits on the next contact message                                                                                                                                |
| autoSplitOnIdle                               | boolean                                                                                                                 | 否  | Split when the last message of the latest conversation is older than the configured hours, unless a human agent is serving it or it is queued                                                                   |
| autoSplitIdleHours                            | integer                                                                                                                 | 否  | Hours (1-720) since the last message of the latest conversation                                                                                                                                                 |
| enableContinuationSummary                     | boolean                                                                                                                 | 否  | When on, a conversation started by auto split gives its AI the previous conversations' analysis summaries; a previous conversation without a current summary gets one from conversation analysis (one bi...     |
| continuationSummaryCount                      | integer                                                                                                                 | 否  | How many previous conversations (1-3) a new conversation looks back at for summaries                                                                                                                            |
| copilotEnabled                                | boolean                                                                                                                 | 否  |                                                                                                                                                                                                                 |
| copilotTriggerMode                            | string (enum: manual, every\_incoming)                                                                                  | 否  | `manual`: Manual ; `every_incoming`: Every Incoming;                                                                                                                                                            |
| quotaExceededMessage                          | string                                                                                                                  | 否  | Custom message sent to the visitor when the inbox credit quota is exhausted. Used as the fallback when `quota_exceeded_message_by_locale` has no match for the conversation locale. Empty means the syst...     |
| quotaExceededMessageByLocale                  | object                                                                                                                  | 否  | Locale-keyed quota-exceeded messages. A dict mapping normalized locale codes from CHAT\_LANGUAGES (e.g. "en", "zh-hant", "ja") to a message string. Selected by the conversation locale; falls back to \`q...   |

**請求結構範例**

```typescript
{
  "groups"?: [ // 可存取此收件匣的群組列表 (非必填)
    {
      "id": string (uuid)
    }
  ]
  "channelType"?: string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber (非必填)
  "name"?: string // 非必填
  "autoReplySchedules"?: [ // 非必填
    {
      "isEnabled"?: boolean // 非必填
      "timeSlots"?: [ // 非必填
        array[string]
      ]
    }
  ]
  "channel"?: // 可能有不同的類型 (非必填)
  {
    "avatar"?: string (uri) // 非必填
    "logo"?: string (uri) // 非必填
    "description"?: string // 非必填
    "cover"?: string (uri) // 非必填
    "backUrl"?: string // 非必填
    "isActive"?: boolean // 非必填
    "theme": {
    {
      "primaryColor"?: string // 非必填
      "navbarTextColor"?: string // 非必填
      "conversationBackgroundColor"?: string // 非必填
      "chatbotMessageTextColor"?: string // 非必填
      "userMessageTextColor"?: string // 非必填
      "chatbotMessageBackgroundColor"?: string // 非必填
      "userMessageBackgroundColor"?: string // 非必填
      "chatbotMessageBackgroundShadowEnabled"?: boolean // 非必填
      "userMessageBackgroundShadowEnabled"?: boolean // 非必填
      "chatbotMessageGradientEnabled"?: boolean // 非必填
      "userMessageGradientEnabled"?: boolean // 非必填
    }
    }
    "darkTheme": {
    {
      "primaryColor"?: string // 非必填
      "navbarTextColor"?: string // 非必填
      "conversationBackgroundColor"?: string // 非必填
      "chatbotMessageTextColor"?: string // 非必填
      "userMessageTextColor"?: string // 非必填
      "chatbotMessageBackgroundColor"?: string // 非必填
      "userMessageBackgroundColor"?: string // 非必填
      "chatbotMessageBackgroundShadowEnabled"?: boolean // 非必填
      "userMessageBackgroundShadowEnabled"?: boolean // 非必填
      "chatbotMessageGradientEnabled"?: boolean // 非必填
      "userMessageGradientEnabled"?: boolean // 非必填
    }
    }
    "enableFileUpload"?: boolean // 非必填
    "enableDisplayCitations"?: boolean // 非必填
    "toolDisplayMode"?: string (enum: full, compact, hidden) // * `full` - Full
* `compact` - Compact
* `hidden` - Hidden (非必填)
    "enableAskOptionButtons"?: boolean // 開啟後 ask_user_question 選項以按鈕列浮在輸入框上方（輸入框保持可用）；關閉則維持現行覆蓋式面板。灰度開關，可隨時關閉回退。 (非必填)
    "enableConversationHandoff"?: boolean // 開啟後此對話平台的 webchat 顯示交接 UI（提示條、摘要卡、接續按鈕）並註冊交接工具；仍受系統設定的全域交接開關管制（全域關＝一律關）。MaiGPT 免此開關恆顯示。底部的上下文使用量百分比條另由「顯示上下文使用量」控制。預設關閉，客戶對外 webchat 不會看到任何交接 UI；灰度開關，關閉即回退、不需退版。 (非必填)
    "enableDisplayContextUsage"?: boolean // 開啟後此對話平台的 webchat 在輸入框下方顯示上下文使用量百分比條。與對話交接互相獨立：不受交接開關（含全域交接開關）影響，也不影響交接提示條。MaiGPT 免此開關恆顯示。預設關閉；關閉即回退、不需退版。 (非必填)
    "enableDisplayThinking"?: boolean // 非必填
    "enableUserThinkingControl"?: boolean // 非必填
    "enableDisplayQueryMetadata"?: boolean // 非必填
    "enableDisplayHookMarkers"?: boolean // 非必填
    "hookMarkerTextInputModify"?: string // 非必填
    "hookMarkerTextOutputModify"?: string // 非必填
    "hookMarkerTextInputBlock"?: string // 非必填
    "hookMarkerTextOutputBlock"?: string // 非必填
    "enableShareConversation"?: boolean // 非必填
    "enableLocation"?: boolean // 非必填
    "enableShowPoweredBy"?: boolean // 非必填
    "poweredByLogo"?: string (uri) // 非必填
    "enableAnonymous"?: boolean // 非必填
    "enableDisplayPreviousConversation"?: boolean // 非必填
    "enableDisplayConversationHistory"?: boolean // 非必填
    "enableConversationTimer"?: boolean // 非必填
    "conversationTimerDuration"?: integer // 計時器逾時時長，範圍 3-60 分鐘 (非必填)
    "enableAutoNewConversationOnTimeout"?: boolean // 非必填
    "enableSatisfactionSurvey"?: boolean // 非必填
    "satisfactionSurveyDelayMinutes"?: integer // 最後一則 AI 回覆後幾分鐘彈出問卷，範圍 1-60 分鐘 (非必填)
    "satisfactionSurveyPrompt"?: string // 自訂問卷標題文字，留空則使用前端多語系預設文字 (非必填)
    "enableThemeModeToggle"?: boolean // 非必填
    "enableDisplayFontSizeSwitch"?: boolean // 非必填
    "defaultThemeMode"?:  // 非必填
    {
    }
    "enableDownloadCitations"?: boolean // 非必填
    "customDomain"?:  // 非必填
    {
      "domain": string
    }
    "enableDisplayChatbotAvatar"?: boolean // 非必填
    "enableDisplayChatbotName"?: boolean // 非必填
    "buttonIcon"?: string (uri) // 非必填
    "conversationStartersDisplayCount"?: integer // 非必填
    "includeGreetingInContext"?: boolean // When enabled, the conversation greeting and the numbered conversation starters (in configured order, unshuffled and untruncated) are injected into the LLM context so the agent can resolve short replies like "1" to the matching starter option. (非必填)
    "preChatFormEnabled"?: boolean // 非必填
    "preChatFormFields"?: object // 非必填
    "preChatFormTitle"?: object // 非必填
    "preChatFormSubtitle"?: object // 非必填
    "loadingDisplayMode"?:  // Waiting-experience style. `narrative` shows per-stage copy; `brand_animation` plays the uploaded asset and hides every system narration line. Defaults to `narrative`, which with no copy configured behaves exactly as before this field existed.

* `narrative` - Narrative copy
* `brand_animation` - Brand animation (非必填)
    {
    }
    "loadingStageCopyByLocale"?: object // Locale-keyed per-stage waiting copy, shaped {locale: {stage: text}} where stage is one of LoadingStage. An absent locale or stage falls back to the built-in copy, so a partially filled dict is valid and never blocks a reply. (非必填)
    "loadingLongWaitCopyByLocale"?: object // Locale-keyed line shown once the wait exceeds `loading_long_wait_threshold_seconds`, shaped {locale: text}. Written in the brand character voice for the animation mode, but applies to both modes. Empty means no long-wait line is shown. (非必填)
    "loadingLongWaitThresholdSeconds"?: integer // How long a single reply must be pending before the long-wait copy appears. (非必填)
    "loadingAnimationUseSharedAsset"?: boolean // True (default) means every stage plays `loading_animation_shared_asset_url`, so the admin only uploads once. False expands per-stage assets, each falling back to the shared asset when its own slot is empty. (非必填)
    "loadingAnimationSharedAssetUrl"?: string (uri) // 非必填
    "loadingAnimationAssetUrlsByStage"?: object // Shaped {stage: url} keyed by LoadingStage. Only consulted when `loading_animation_use_shared_asset` is False; a missing stage falls back to the shared asset. (非必填)
    "loadingTypingShowCopy"?: boolean // Only affects the first "typing" stage. True (default, the pre-existing behavior) shows the typing-stage copy next to the pre-first-char animation/dot; False plays only the animation with no text line. Thinking / analyzing / long-wait stages are unaffected. (非必填)
    "toolCardRunningIconUrl"?: string (uri) // 非必填
    "toolCardCompletedIconUrl"?: string (uri) // 非必填
    "greetings"?: [ // Default greeting messages shown as the AI first message when a new conversation starts. One message is randomly selected per conversation. Used as the fallback when `greetings_by_locale` has no match for the request locale. (非必填)
      string
    ]
    "greetingsByLocale"?: object // Locale-keyed greetings. A dict mapping locale codes to a list of greeting strings (e.g. keys like "en", "zh-TW", "ja"). Selected by the conversation request Accept-Language header; falls back to `greetings` when no locale matches. (非必填)
    "voiceGreetings"?: [ // Greeting messages spoken aloud when a voice session starts. One message is randomly selected per session. The spoken greeting is ephemeral and NOT written back to conversation history. Used as the fallback when `voice_greetings_by_locale` has no match for the request locale. (非必填)
      string
    ]
    "voiceGreetingsByLocale"?: object // Locale-keyed voice greetings. A dict mapping locale codes to a list of greeting strings. Selected by the Accept-Language header; falls back to `voice_greetings` when no locale matches. (非必填)
    "conversationStarters"?: [ // Default suggested questions shown to the end-user as clickable prompts at the start of a conversation. Used as the fallback when `conversation_starters_by_locale` has no match for the request locale. (非必填)
      string
    ]
    "conversationStartersByLocale"?: object // Locale-keyed conversation starters. A dict mapping locale codes to a list of starter strings (e.g. keys like "en", "zh-TW", "ja"). Selected by the Accept-Language header; falls back to `conversation_starters` when no locale matches. (非必填)
    "allowedEmbedOrigins"?: [ // Origins allowed to embed this web chat and call the SDK contact-setup endpoint. Each entry is either an exact origin (scheme://host[:port], e.g. https://example.com) or a wildcard (*.example.com) that matches example.com and all of its subdomains on any scheme/port. An empty list means no restriction. Validated against the embedding page origin forwarded by the web chat frontend; bounds unauthorized-domain embedding. Browser-level enforcement (CSP frame-ancestors on the entry page) additionally requires an AWS/CloudFront deployment; on GCP storage the allowlist is enforced by the API alone. WARNING: leave empty until the web chat frontend forwards the embedding origin, otherwise setup calls fall back to the web chat host origin and every request is rejected. (非必填)
      string
    ]
  }
  "organization"?: string (uuid) // 非必填
  "signAuth"?:  // 非必填
  {
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // 非必填
      {
        "enabled": boolean
      }
    }
    }
    "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
    "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
    {
    }
    "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
    {
    }
    "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
      string
    ]
  }
  "enableTimeAwareResponse"?: boolean // Enable time aware responses for this inbox (非必填)
  "defaultTimezone"?: string // Default timezone for this inbox (e.g., Asia/Taipei, America/New_York) (非必填)
  "enableSenderNameAwareResponse"?: boolean // Enable sender name aware responses for this inbox (非必填)
  "enableGpsAwareResponse"?: boolean // Enable GPS aware responses for this inbox (非必填)
  "gpsRequestTiming"?:  // Web chat only. "on_open" asks the browser for the location as soon as the chat opens (current behavior); "on_demand" asks only when the AI requests it through an ask_user_question question carrying extra_params.requestLocation. LINE always offers a share-location quick reply regardless of this value.

* `on_open` - Ask when the chat opens
* `on_demand` - Ask only when the AI needs it (非必填)
  {
  }
  "enableAiLineSticker"?: boolean // LINE inboxes only. When on, the AI may attach one LINE official sticker to a reply (from the global LINE AI sticker list). (非必填)
  "enableOcr"?: boolean // Retired: attachments pick their parser by content detection (image-heavy files go to the Vision Parser, billed by token; scanned and text files to the MaiAgent Parser, scanned pages billed as OCR) and this switch has no effect. (非必填)
  "enableAgentAttachmentDecision"?: boolean // Kill switch for AGENT-mode attachment handling. When False (default), AGENT-mode chatbots skip auto-embedding on upload and let the agent handle attachments at runtime via ParseAttachmentContentTool / IngestAttachmentTool. When True, AGENT-mode chatbots fall back to auto-embedding chat attachments into the knowledge base on upload, same as non-AGENT modes. Has no effect on non-AGENT chatbot modes (they always auto-embed). (非必填)
  "enableStreamMessage"?: boolean // 非必填
  "enableHumanHandoff"?: boolean // 非必填
  "handoffPrompt"?: string // 非必填
  "handoffLlm"?: string (uuid) // 非必填
  "handoffContextMessageLimit"?: integer // 非必填
  "handoffMessage"?: string // 非必填
  "queuingMessage"?: string // 非必填
  "assignedMessage"?: string // 非必填
  "enablePendingReplyMessage"?: boolean // Send a placeholder message to the user while the AI is processing. (非必填)
  "pendingReplyMessage"?: string // 非必填
  "pendingReplyInitialDelaySeconds"?: integer // Delay before sending the first pending reply, so a fast AI response can pre-empt it. (非必填)
  "pendingReplyIntervalSeconds"?: integer // Interval to repeat the pending reply while the AI is still processing. (非必填)
  "enablePendingReplyCleanup"?: boolean // Delete pending reply messages after the AI reply is sent. Only effective on platforms that support message deletion (Teams, Telegram, Slack). (非必填)
  "enableAnalysis"?: boolean // 非必填
  "analysisLlm"?: string (uuid) // 非必填
  "analysisPrompt"?: string // 非必填
  "analysisContextMessageLimit"?: integer // 非必填
  "analysisGenerateSummary"?: boolean // When on, conversation analysis writes the conversation summary (editable, with revisions); inbox auto split brings it to the next conversation (非必填)
  "analysisApplyTags"?: boolean // When on, conversation analysis picks the conversation tags from the inbox tags (非必填)
  "enableServiceHours"?: boolean // 非必填
  "serviceHoursTimezone"?: string // 非必填
  "offlineBehavior"?: string (enum: show_message, leave_message) // * `show_message` - Show Message
* `leave_message` - Leave Message (非必填)
  "offlineMessage"?: string // 非必填
  "serviceHoursSchedules"?: [ // 非必填
    {
      "weekday": integer
      "startTime": string (time)
      "endTime": string (time)
      "isEnabled"?: boolean // 非必填
    }
  ]
  "dispatchMode"?:  // Auto dispatch assigns transferred conversations to an agent automatically. Claim (handover) leaves them unassigned for online agents to pick up themselves; timeout reassignment does not apply and the queue timeout may be set to "no timeout".

* `auto` - Auto Dispatch
* `handover` - Claim (Handover) (非必填)
  {
  }
  "assignmentRoutingModel"?: string (enum: round_robin, least_active) // * `round_robin` - Round Robin
* `least_active` - Least Active (非必填)
  "assignmentMaxConcurrent"?: integer // 非必填
  "assignmentQueueTimeout"?: integer // Queue timeout in seconds (非必填)
  "queueTimeoutMessage"?: string // 非必填
  "maxQueueSize"?: integer // 非必填
  "queueFullMessage"?: string // 非必填
  "assignmentTargetMembers"?: [ // 非必填
    string (uuid)
  ]
  "enableTagRouting"?: boolean // 非必填
  "enableReassignOnTimeout"?: boolean // When on, a queued or assigned-but-unanswered conversation that times out is reassigned to the next available agent (skipping already-tried agents) instead of returning straight to the AI; it only returns to the AI once no agent is left to try. (非必填)
  "enableQueueReminder"?: boolean // Reply with a throttled waiting reminder when the contact sends messages while queued. (非必填)
  "queueReminderMessage"?: string // 非必填
  "queueReminderCooldown"?: integer // Minimum seconds between queue reminders in one conversation (非必填)
  "enableQueueCancel"?: boolean // Allow the contact to cancel a queued handoff and return to the AI by themselves. (非必填)
  "queueCancelButtonText"?: string // Label of the cancel quick-reply button. Its text also counts as a cancel keyword, so tapping the button always cancels even when the keyword list changes. (非必填)
  "queueCancelKeywords"?: object // Messages matching one of these exactly (after stripping surrounding whitespace) cancel the queued handoff. Empty means no keyword matching (the cancel button text still matches); the serializer requires at least one keyword while queue cancel is enabled. (非必填)
  "queueCancelMessage"?: string // Sent to the contact right after they cancel the queued handoff. (非必填)
  "enableIdleAutoResolve"?: boolean // Resolve a conversation served by a human agent once the agent replied last and the contact has not answered for the idle minutes. Frees the agent slot; queued conversations and ones where the contact spoke last are never resolved. (非必填)
  "idleAutoResolveMinutes"?: integer // Minutes the contact may stay silent after the last agent reply before auto resolve (非必填)
  "idleAutoResolveMessage"?: string // Sent to the contact when the conversation is auto resolved; blank sends nothing. LINE delivers it as a push message (counts toward the LINE message quota); Messenger / Instagram / WhatsApp skip it once the contact last wrote more than 24 hours ago. (非必填)
  "enableAgentReplyTimeout"?: boolean // When on, a conversation served by a human agent returns to the AI once a contact message has gone unanswered by any agent for the configured seconds; the AI then answers the last unanswered message. Auto-dispatched conversations the agent has not answered yet are left to timeout reassignment while that is enabled. (非必填)
  "agentReplyTimeout"?: integer // Seconds (60-86400) a contact message may go unanswered by a human agent before the AI takes over (非必填)
  "agentReplyTimeoutMessage"?: string // Sent to the contact when the conversation returns to the AI; leave empty to send none. (非必填)
  "enableReturnToPreviousAssignee"?: boolean // When on, a resolved conversation the contact writes to again within the configured hours reopens assigned to the agent who held it instead of to the AI. It still reopens to the AI when that agent is offline, paused, off duty, no longer an active member with access to this inbox, or the inbox is outside its service hours. (非必填)
  "returnToPreviousAssigneeHours"?: integer // Hours (1-720), counted from when the conversation was resolved, during which a returning contact goes back to the agent who held it (非必填)
  "enableAutoSplit"?: boolean // When on, a one-to-one contact writing again after the conversation was resolved or went idle for the configured time starts a new conversation instead of continuing the old one. Web inboxes and group conversations are never split; a returning contact handed back to the previous assignee stays. (非必填)
  "autoSplitOnResolve"?: boolean // Split when the latest conversation was resolved more than the configured minutes ago (非必填)
  "autoSplitResolveMinutes"?: integer // Minutes (0-10080) after the latest resolve; 0 splits on the next contact message (非必填)
  "autoSplitOnIdle"?: boolean // Split when the last message of the latest conversation is older than the configured hours, unless a human agent is serving it or it is queued (非必填)
  "autoSplitIdleHours"?: integer // Hours (1-720) since the last message of the latest conversation (非必填)
  "enableContinuationSummary"?: boolean // When on, a conversation started by auto split gives its AI the previous conversations' analysis summaries; a previous conversation without a current summary gets one from conversation analysis (one billed model call on that conversation). Needs conversation analysis with its summary on. (非必填)
  "continuationSummaryCount"?: integer // How many previous conversations (1-3) a new conversation looks back at for summaries (非必填)
  "copilotEnabled"?: boolean // 非必填
  "copilotTriggerMode"?: string (enum: manual, every_incoming) // * `manual` - Manual
* `every_incoming` - Every Incoming (非必填)
  "quotaExceededMessage"?: string // Custom message sent to the visitor when the inbox credit quota is exhausted. Used as the fallback when `quota_exceeded_message_by_locale` has no match for the conversation locale. Empty means the system default message is used. (非必填)
  "quotaExceededMessageByLocale"?: object // Locale-keyed quota-exceeded messages. A dict mapping normalized locale codes from CHAT_LANGUAGES (e.g. "en", "zh-hant", "ja") to a message string. Selected by the conversation locale; falls back to `quota_exceeded_message`. (非必填)
}
```

**請求範例值**

```json
{
  "chatbot": {
    "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
  },
  "groups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "name": "更新後的名稱"
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PATCH "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "更新後的名稱"
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "更新後的名稱"
  };

axios.patch("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "chatbot": {
        "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
        {
            "id": "550e8400-e29b-41d4-a716-446655440000"
        }
    ],
    "name": "更新後的名稱"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->patch("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'chatbot' => [
                'id' => '80f3170d-eed7-4651-a8da-6b7e6bdbef8b'
            ],
            'groups' => [
                [
                    'id' => '550e8400-e29b-41d4-a716-446655440000'
                ]
            ],
            'name' => '更新後的名稱'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "name": string
  "channelType": string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team_plus, line_works, viber) // * `line` - LINE
* `telegram` - Telegram
* `teams` - Teams
* `web` - Web
* `messenger` - Messenger
* `instagram` - Instagram
* `email` - Email
* `whatsapp` - WhatsApp
* `slack` - Slack
* `team_plus` - Team+
* `line_works` - LINE WORKS
* `viber` - Viber
  "unreadConversationsCount"?: integer // 非必填
  "signAuth"?:  // 非必填
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // 非必填
      {
        "enabled": boolean
      }
    }
    }
    "sourceIdAccessEnabled"?: boolean // When enabled, embedded visitors presenting a Source ID (verified per the verify mode below) may chat without going through the login flow. Disabled keeps every existing behavior unchanged. (非必填)
    "sourceIdVerifyMode"?:  // "Require signature verification": the embedding site must send an HMAC signature computed on its backend. "Source ID only": anyone knowing a Source ID can act as that contact; suitable only for testing or closed networks.

* `signature` - Require signature verification
* `raw` - Source ID only (非必填)
    {
    }
    "sourceIdSignatureTtlMinutes"?:  // How long a signature can be used to obtain the contact identity. Not a session lifetime: once exchanged, the session follows the existing WebChat mechanism.

* `1` - 1
* `5` - 5
* `15` - 15 (非必填)
    {
    }
    "keycloakTokenPassthrough"?: boolean // When enabled, the Keycloak access token a visitor logged in with is forwarded as the Authorization header when the AI calls MCP and API tools on their behalf, so tools do not require a separate per-tool login. Only for the Keycloak sign source. Never overrides an Authorization header a tool already resolves from its own credentials. The visitor identity is the organization member bound to the conversation at login, never the contact Source ID. (非必填)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (非必填)
      string
    ]
    "organizationLogin": object // How visitors sign in when the sign source is "organization" (mirrors the back-office login); null for other sign sources
  }
  "enableAnalysis"?: boolean // 非必填
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "channelType": "line",
  "unreadConversationsCount": 456,
  "signAuth": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "signSource": "550e8400-e29b-41d4-a716-446655440000",
    "signParams": {
      "keycloak": {
        "clientId": "回應字串",
        "url": "回應字串",
        "realm": "回應字串"
      },
      "line": {
        "liffId": "回應字串"
      },
      "ad": {
        "saml": "回應字串"
      },
      "google": {
        "enabled": false
      }
    },
    "sourceIdAccessEnabled": false,
    "sourceIdVerifyMode": {},
    "sourceIdSignatureTtlMinutes": {},
    "keycloakTokenPassthrough": false,
    "keycloakTokenPassthroughAllowedHosts": [
      "回應字串"
    ],
    "organizationLogin": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應範例名稱",
      "description": "回應範例描述"
    }
  },
  "enableAnalysis": false
}
```

***

### 刪除對話平台 <a href="#inboxes-destroy" id="inboxes-destroy"></a>

DELETE `/api/v1/inboxes/{id}/`

#### 參數

| 參數名稱 | 必填 | 類型     | 說明                                    |
| ---- | -- | ------ | ------------------------------------- |
| `id` | ✅  | string | A UUID string identifying this Inbox. |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明               |
| --- | ---------------- |
| 204 | No response body |

***

### 列出對話平台的 Webhook <a href="#inboxes-webhooks-list" id="inboxes-webhooks-list"></a>

GET `/api/v1/inboxes/{inboxPk}/webhooks/`

#### 參數

| 參數名稱       | 必填 | 類型      | 說明                                             |
| ---------- | -- | ------- | ---------------------------------------------- |
| `inboxPk`  | ✅  | string  |                                                |
| `page`     | ❌  | integer | A page number within the paginated result set. |
| `pageSize` | ❌  | integer | Number of results to return per page.          |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/?page=1&pageSize=1" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/?page=1&pageSize=1", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/?page=1&pageSize=1"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/?page=1&pageSize=1", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "count": integer
  "next"?: string (uri) // 非必填
  "previous"?: string (uri) // 非必填
  "results": [
    {
      "id": string (uuid)
      "inbox": string (uuid)
      "name": string // Webhook configuration name for identification
      "direction":  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive
      {
      }
      "directionLabel": string
      "isEnabled"?: boolean // 非必填
      "url": string (uri)
      "method"?:  // 非必填
      {
      }
      "headersMasked": object
      "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
      "templatePresetLabel": string
      "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
      "payloadPreset"?: // 可能有不同的類型 (非必填)
      string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
      "payloadPresetLabel": string
      "receiveUrl": string
      "createdAt": string (timestamp)
      "updatedAt": string (timestamp)
    }
  ]
}
```

**回應範例值**

```json
{
  "count": 123,
  "next": "http://api.example.org/accounts/?page=4",
  "previous": "http://api.example.org/accounts/?page=2",
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "inbox": "550e8400-e29b-41d4-a716-446655440000",
      "name": "回應字串",
      "direction": {},
      "directionLabel": "回應字串",
      "isEnabled": false,
      "url": "https://example.com/file.jpg",
      "method": {},
      "headersMasked": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "回應範例名稱",
        "description": "回應範例描述"
      },
      "templatePreset": "maiagent_standard",
      "templatePresetLabel": "回應字串",
      "customTemplate": "回應字串",
      "payloadPreset": "genesys_cloud",
      "payloadPresetLabel": "回應字串",
      "receiveUrl": "回應字串",
      "createdAt": "回應字串",
      "updatedAt": "回應字串"
    }
  ]
}
```

***

### 建立 Webhook <a href="#inboxes-webhooks-create" id="inboxes-webhooks-create"></a>

POST `/api/v1/inboxes/{inboxPk}/webhooks/`

{% hint style="info" %}
`direction` 為 `incoming`（使用者訊息進入時觸發）或 `outgoing`（Agent 回覆時觸發）；`template_preset` 選 `maiagent_standard` 使用 MaiAgent 標準 payload。
{% endhint %}

#### 參數

| 參數名稱      | 必填 | 類型     | 說明 |
| --------- | -- | ------ | -- |
| `inboxPk` | ✅  | string |    |

#### 請求內容

**請求參數**

| 欄位             | 類型                                                        | 必填 | 說明                                                                                                                                    |
| -------------- | --------------------------------------------------------- | -- | ------------------------------------------------------------------------------------------------------------------------------------- |
| name           | string                                                    | 是  | Webhook configuration name for identification                                                                                         |
| direction      | object                                                    | 是  | When to trigger: incoming (user messages) or outgoing (bot replies) `incoming`: Incoming ; `outgoing`: Outgoing ; `receive`: Receive; |
| isEnabled      | boolean                                                   | 否  |                                                                                                                                       |
| url            | string (uri)                                              | 否  |                                                                                                                                       |
| method         | object                                                    | 否  |                                                                                                                                       |
| headers        | object                                                    | 否  | Custom HTTP headers as JSON object                                                                                                    |
| templatePreset | string (enum: maiagent\_standard, genesys\_cloud, custom) | 否  | `maiagent_standard`: MaiAgent Standard ; `genesys_cloud`: Genesys Cloud ; `custom`: Custom;                                           |
| customTemplate | string                                                    | 否  | Jinja2 template for custom payload format. Required when template\_preset is "custom".                                                |
| secretToken    | string                                                    | 否  | Secret token for webhook signature verification                                                                                       |
| payloadPreset  | object                                                    | 否  | Preset for parsing incoming webhook payloads (used with direction=receive) `genesys_cloud`: Genesys Cloud;                            |

**請求結構範例**

```typescript
{
  "name": string // Webhook configuration name for identification
  "direction":  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive
  {
  }
  "isEnabled"?: boolean // 非必填
  "url"?: string (uri) // 非必填
  "method"?:  // 非必填
  {
  }
  "headers"?: object // Custom HTTP headers as JSON object (非必填)
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
  "secretToken"?: string // Secret token for webhook signature verification (非必填)
  "payloadPreset"?: // 可能有不同的類型 (非必填)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
}
```

**請求範例值**

```json
{
  "name": "範例名稱",
  "direction": {},
  "isEnabled": true,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headers": null,
  "templatePreset": "maiagent_standard",
  "customTemplate": "範例字串",
  "secretToken": "範例字串",
  "payloadPreset": null
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X POST "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "範例名稱",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": null
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "範例名稱",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": null
  };

axios.post("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "範例名稱",
    "direction": {},
    "isEnabled": True,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": None,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": None
}

response = requests.post(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->post("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => '範例名稱',
            'direction' => new \stdClass(),
            'isEnabled' => true,
            'url' => 'https://example.com/file.jpg',
            'method' => new \stdClass(),
            'headers' => null,
            'templatePreset' => 'maiagent_standard',
            'customTemplate' => '範例字串',
            'secretToken' => '範例字串',
            'payloadPreset' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 201**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "inbox": string (uuid)
  "name": string // Webhook configuration name for identification
  "direction":  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive
  {
  }
  "directionLabel": string
  "isEnabled"?: boolean // 非必填
  "url": string (uri)
  "method"?:  // 非必填
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
  "payloadPreset"?: // 可能有不同的類型 (非必填)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
  "payloadPresetLabel": string
  "receiveUrl": string
  "createdAt": string (timestamp)
  "updatedAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "direction": {},
  "directionLabel": "回應字串",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "回應字串",
  "customTemplate": "回應字串",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "回應字串",
  "receiveUrl": "回應字串",
  "createdAt": "回應字串",
  "updatedAt": "回應字串"
}
```

***

### 取得特定 Webhook <a href="#inboxes-webhooks-retrieve" id="inboxes-webhooks-retrieve"></a>

GET `/api/v1/inboxes/{inboxPk}/webhooks/{id}/`

#### 參數

| 參數名稱      | 必填 | 類型     | 說明                                            |
| --------- | -- | ------ | --------------------------------------------- |
| `id`      | ✅  | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk` | ✅  | string |                                               |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X GET "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

axios.get("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.get(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->get("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "inbox": string (uuid)
  "name": string // Webhook configuration name for identification
  "direction":  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive
  {
  }
  "directionLabel": string
  "isEnabled"?: boolean // 非必填
  "url": string (uri)
  "method"?:  // 非必填
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
  "payloadPreset"?: // 可能有不同的類型 (非必填)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
  "payloadPresetLabel": string
  "receiveUrl": string
  "createdAt": string (timestamp)
  "updatedAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "direction": {},
  "directionLabel": "回應字串",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "回應字串",
  "customTemplate": "回應字串",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "回應字串",
  "receiveUrl": "回應字串",
  "createdAt": "回應字串",
  "updatedAt": "回應字串"
}
```

***

### 更新 Webhook <a href="#inboxes-webhooks-update" id="inboxes-webhooks-update"></a>

PUT `/api/v1/inboxes/{inboxPk}/webhooks/{id}/`

#### 參數

| 參數名稱      | 必填 | 類型     | 說明                                            |
| --------- | -- | ------ | --------------------------------------------- |
| `id`      | ✅  | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk` | ✅  | string |                                               |

#### 請求內容

**請求參數**

| 欄位             | 類型                                                        | 必填 | 說明                                                                                                                                    |
| -------------- | --------------------------------------------------------- | -- | ------------------------------------------------------------------------------------------------------------------------------------- |
| name           | string                                                    | 是  | Webhook configuration name for identification                                                                                         |
| direction      | object                                                    | 是  | When to trigger: incoming (user messages) or outgoing (bot replies) `incoming`: Incoming ; `outgoing`: Outgoing ; `receive`: Receive; |
| isEnabled      | boolean                                                   | 否  |                                                                                                                                       |
| url            | string (uri)                                              | 否  |                                                                                                                                       |
| method         | object                                                    | 否  |                                                                                                                                       |
| headers        | object                                                    | 否  | Custom HTTP headers as JSON object                                                                                                    |
| templatePreset | string (enum: maiagent\_standard, genesys\_cloud, custom) | 否  | `maiagent_standard`: MaiAgent Standard ; `genesys_cloud`: Genesys Cloud ; `custom`: Custom;                                           |
| customTemplate | string                                                    | 否  | Jinja2 template for custom payload format. Required when template\_preset is "custom".                                                |
| secretToken    | string                                                    | 否  | Secret token for webhook signature verification                                                                                       |
| payloadPreset  | object                                                    | 否  | Preset for parsing incoming webhook payloads (used with direction=receive) `genesys_cloud`: Genesys Cloud;                            |

**請求結構範例**

```typescript
{
  "name": string // Webhook configuration name for identification
  "direction":  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive
  {
  }
  "isEnabled"?: boolean // 非必填
  "url"?: string (uri) // 非必填
  "method"?:  // 非必填
  {
  }
  "headers"?: object // Custom HTTP headers as JSON object (非必填)
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
  "secretToken"?: string // Secret token for webhook signature verification (非必填)
  "payloadPreset"?: // 可能有不同的類型 (非必填)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
}
```

**請求範例值**

```json
{
  "name": "範例名稱",
  "direction": {},
  "isEnabled": true,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headers": null,
  "templatePreset": "maiagent_standard",
  "customTemplate": "範例字串",
  "secretToken": "範例字串",
  "payloadPreset": null
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PUT "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "範例名稱",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": null
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "範例名稱",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": null
  };

axios.put("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "範例名稱",
    "direction": {},
    "isEnabled": True,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": None,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": None
}

response = requests.put(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->put("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => '範例名稱',
            'direction' => new \stdClass(),
            'isEnabled' => true,
            'url' => 'https://example.com/file.jpg',
            'method' => new \stdClass(),
            'headers' => null,
            'templatePreset' => 'maiagent_standard',
            'customTemplate' => '範例字串',
            'secretToken' => '範例字串',
            'payloadPreset' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "inbox": string (uuid)
  "name": string // Webhook configuration name for identification
  "direction":  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive
  {
  }
  "directionLabel": string
  "isEnabled"?: boolean // 非必填
  "url": string (uri)
  "method"?:  // 非必填
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
  "payloadPreset"?: // 可能有不同的類型 (非必填)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
  "payloadPresetLabel": string
  "receiveUrl": string
  "createdAt": string (timestamp)
  "updatedAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "direction": {},
  "directionLabel": "回應字串",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "回應字串",
  "customTemplate": "回應字串",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "回應字串",
  "receiveUrl": "回應字串",
  "createdAt": "回應字串",
  "updatedAt": "回應字串"
}
```

***

### 部分更新 Webhook <a href="#inboxes-webhooks-partial-update" id="inboxes-webhooks-partial-update"></a>

PATCH `/api/v1/inboxes/{inboxPk}/webhooks/{id}/`

#### 參數

| 參數名稱      | 必填 | 類型     | 說明                                            |
| --------- | -- | ------ | --------------------------------------------- |
| `id`      | ✅  | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk` | ✅  | string |                                               |

#### 請求內容

**請求參數**

| 欄位             | 類型                                                        | 必填 | 說明                                                                                                                                    |
| -------------- | --------------------------------------------------------- | -- | ------------------------------------------------------------------------------------------------------------------------------------- |
| name           | string                                                    | 否  | Webhook configuration name for identification                                                                                         |
| direction      | object                                                    | 否  | When to trigger: incoming (user messages) or outgoing (bot replies) `incoming`: Incoming ; `outgoing`: Outgoing ; `receive`: Receive; |
| isEnabled      | boolean                                                   | 否  |                                                                                                                                       |
| url            | string (uri)                                              | 否  |                                                                                                                                       |
| method         | object                                                    | 否  |                                                                                                                                       |
| headers        | object                                                    | 否  | Custom HTTP headers as JSON object                                                                                                    |
| templatePreset | string (enum: maiagent\_standard, genesys\_cloud, custom) | 否  | `maiagent_standard`: MaiAgent Standard ; `genesys_cloud`: Genesys Cloud ; `custom`: Custom;                                           |
| customTemplate | string                                                    | 否  | Jinja2 template for custom payload format. Required when template\_preset is "custom".                                                |
| secretToken    | string                                                    | 否  | Secret token for webhook signature verification                                                                                       |
| payloadPreset  | object                                                    | 否  | Preset for parsing incoming webhook payloads (used with direction=receive) `genesys_cloud`: Genesys Cloud;                            |

**請求結構範例**

```typescript
{
  "name"?: string // Webhook configuration name for identification (非必填)
  "direction"?:  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive (非必填)
  {
  }
  "isEnabled"?: boolean // 非必填
  "url"?: string (uri) // 非必填
  "method"?:  // 非必填
  {
  }
  "headers"?: object // Custom HTTP headers as JSON object (非必填)
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
  "secretToken"?: string // Secret token for webhook signature verification (非必填)
  "payloadPreset"?: // 可能有不同的類型 (非必填)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
}
```

**請求範例值**

```json
{
  "name": "範例名稱",
  "direction": {},
  "isEnabled": true,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headers": null,
  "templatePreset": "maiagent_standard",
  "customTemplate": "範例字串",
  "secretToken": "範例字串",
  "payloadPreset": null
}
```

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X PATCH "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "範例名稱",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": null
  }'

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// 請求內容 (payload)
const data = {
    "name": "範例名稱",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": null
  };

axios.patch("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY",
    "Content-Type": "application/json"
}

# 請求內容 (payload)
data = {
    "name": "範例名稱",
    "direction": {},
    "isEnabled": True,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": None,
    "templatePreset": "maiagent_standard",
    "customTemplate": "範例字串",
    "secretToken": "範例字串",
    "payloadPreset": None
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->patch("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY',
            'Content-Type' => 'application/json'
        ],
        'json' => [
            'name' => '範例名稱',
            'direction' => new \stdClass(),
            'isEnabled' => true,
            'url' => 'https://example.com/file.jpg',
            'method' => new \stdClass(),
            'headers' => null,
            'templatePreset' => 'maiagent_standard',
            'customTemplate' => '範例字串',
            'secretToken' => '範例字串',
            'payloadPreset' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

**狀態碼: 200**

**回應結構範例**

```typescript
{
  "id": string (uuid)
  "inbox": string (uuid)
  "name": string // Webhook configuration name for identification
  "direction":  // When to trigger: incoming (user messages) or outgoing (bot replies)

* `incoming` - Incoming
* `outgoing` - Outgoing
* `receive` - Receive
  {
  }
  "directionLabel": string
  "isEnabled"?: boolean // 非必填
  "url": string (uri)
  "method"?:  // 非必填
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (非必填)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (非必填)
  "payloadPreset"?: // 可能有不同的類型 (非必填)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (非必填)
  "payloadPresetLabel": string
  "receiveUrl": string
  "createdAt": string (timestamp)
  "updatedAt": string (timestamp)
}
```

**回應範例值**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "回應字串",
  "direction": {},
  "directionLabel": "回應字串",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "回應範例名稱",
    "description": "回應範例描述"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "回應字串",
  "customTemplate": "回應字串",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "回應字串",
  "receiveUrl": "回應字串",
  "createdAt": "回應字串",
  "updatedAt": "回應字串"
}
```

***

### 刪除 Webhook <a href="#inboxes-webhooks-destroy" id="inboxes-webhooks-destroy"></a>

DELETE `/api/v1/inboxes/{inboxPk}/webhooks/{id}/`

#### 參數

| 參數名稱      | 必填 | 類型     | 說明                                            |
| --------- | -- | ------ | --------------------------------------------- |
| `id`      | ✅  | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk` | ✅  | string |                                               |

#### 程式碼範例

{% tabs %}
{% tab title="Shell/Bash" %}

```bash
# 呼叫 API 示例 (Shell)
curl -X DELETE "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/" \
  -H "Authorization: Api-Key YOUR_API_KEY"

# 請確認在執行前替換 YOUR_API_KEY 並核對請求資料。
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');

// 設定請求標頭
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// 請求內容 (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('成功取得回應:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('請求發生錯誤:');
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/"
headers = {
    "Authorization": "Api-Key YOUR_API_KEY"
}


response = requests.delete(url, headers=headers)
try:
    print("成功取得回應:")
    print(response.json())
except Exception as e:
    print("請求發生錯誤:", e)
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();

try {
    $response = $client->delete("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/550e8400-e29b-41d4-a716-446655440000/", [
        'headers' => [
            'Authorization' => 'Api-Key YOUR_API_KEY'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "成功取得回應:\n";
    print_r($data);
} catch (Exception $e) {
    echo '請求發生錯誤: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### 回應內容

| 狀態碼 | 說明               |
| --- | ---------------- |
| 204 | No response body |

***


---

# 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/api/api-reference/dui-hua-ping-tai.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.
