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

# Inboxes

An inbox is the unit to which conversations belong and where Webhooks are configured. Each inbox can have multiple Webhooks that send notifications to your system when a user message arrives (`incoming`) or an Agent replies (`outgoing`). Web Chat inboxes also have [Web Chat endpoints](/api/en/api-reference/dui-hua-widget.md). For configuration instructions and payload formats, see [Webhook](https://docs.maiagent.ai/tech/api-integration/webhook) in the technical manual.

### List Inboxes <a href="#inboxes-list" id="inboxes-list"></a>

GET `/api/v1/inboxes/`

#### Parameters

| Parameter     | Required | Type    | Description                                                                           |
| ------------- | -------- | ------- | ------------------------------------------------------------------------------------- |
| `accessType`  | ❌        | string  | Filter by access type                                                                 |
| `channelType` | ❌        | string  | Filter by channel type                                                                |
| `chatbot`     | ❌        | string  | Filter by chatbot ID                                                                  |
| `isActive`    | ❌        | boolean | Filter by active status                                                               |
| `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  | Whether to paginate (true/false). When set to false, returns a simplified data format |
| `query`       | ❌        | string  |                                                                                       |
| `source`      | ❌        | string  | \`self\_built\`: self\_built ; \`built\_in\`: built\_in ; \`all\`: all;               |

#### Code Examples

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

```bash
# Example API call (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status code: 200 - Inbox list**

**Example Response Schema**

```typescript
{
  "count": integer
  "next"?: string (uri) // Optional
  "previous"?: string (uri) // Optional
  "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 // Optional
      "signAuth"?:  // Optional
      {
        "id": string (uuid)
        "signSource": string (uuid)
        "signParams": {
        {
          "keycloak": 
          {
            "clientId": string
            "url": string
            "realm": string
          }
          "line": 
          {
            "liffId": string
          }
          "ad": 
          {
            "saml": string
          }
          "google"?:  // Optional
          {
            "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. (Optional)
        "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 (Optional)
        {
        }
        "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 (Optional)
        {
        }
        "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. (Optional)
        "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
          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 // Optional
    }
  ]
}
```

**Example Response Values**

```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": "Customer Service Bot",
        "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": "Administrators"
        }
      ],
      "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
    }
  ]
}
```

***

### Create an Inbox <a href="#inboxes-create" id="inboxes-create"></a>

POST `/api/v1/inboxes/`

#### Request Body

**Request Parameters**

| Field                                         | Type                                                                                                                    | Required | Description                                                                                                                                                                                                  |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name                                          | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| channelType                                   | string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team\_plus, line\_works, viber) | Yes      | `line`: LINE ; `telegram`: Telegram ; `teams`: Teams ; `web`: Web ; `messenger`: Messenger ; `instagram`: Instagram ; `email`: Email ; `whatsapp`: WhatsApp ; `slack`: Slack ; `team_plus`: Team+ ; \`lin... |
| unreadConversationsCount                      | integer                                                                                                                 | No       |                                                                                                                                                                                                              |
| signAuth                                      | object (with 9 properties: id, signSource, signParams...)                                                               | No       |                                                                                                                                                                                                              |
| signAuth.signSource                           | string (uuid)                                                                                                           | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams                           | object                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak                  | object (with 3 properties: clientId, url, realm)                                                                        | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.clientId         | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.url              | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.realm            | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.line                      | object (with 1 property: liffId)                                                                                        | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.line.liffId               | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.ad                        | object (with 1 property: saml)                                                                                          | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.ad.saml                   | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.google                    | object (with 1 property: enabled)                                                                                       | No       |                                                                                                                                                                                                              |
| signAuth.signParams.google.enabled            | boolean                                                                                                                 | Yes      |                                                                                                                                                                                                              |
| signAuth.sourceIdAccessEnabled                | boolean                                                                                                                 | No       | 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                                                                                                                  | No       | "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                                                                                                                  | No       | 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                                                                                                                 | No       | 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]                                                                                                          | No       | Hostnames (or "\*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to                                                                                                             |
| enableAnalysis                                | boolean                                                                                                                 | No       |                                                                                                                                                                                                              |

**Example Request Schema**

```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 // Optional
  "signAuth"?:  // Optional
  {
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // Optional
      {
        "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. (Optional)
    "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 (Optional)
    {
    }
    "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 (Optional)
    {
    }
    "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. (Optional)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
      string
    ]
  }
  "enableAnalysis"?: boolean // Optional
}
```

**Example Request Values**

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

#### Code Examples

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

```bash
# Example API call (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": "Updated name"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "Updated name"
  };

axios.post("https://api.maiagent.ai/api/v1/inboxes/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "chatbot": {
        "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
        {
            "id": "550e8400-e29b-41d4-a716-446655440000"
        }
    ],
    "name": "Updated name"
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Updated name'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status code: 201**

**Example Response Schema**

```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 // Optional
  "signAuth"?:  // Optional
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // Optional
      {
        "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. (Optional)
    "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 (Optional)
    {
    }
    "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 (Optional)
    {
    }
    "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. (Optional)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
      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 // Optional
}
```

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "channelType": "line",
  "unreadConversationsCount": 456,
  "signAuth": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "signSource": "550e8400-e29b-41d4-a716-446655440000",
    "signParams": {
      "keycloak": {
        "clientId": "Response string",
        "url": "Response string",
        "realm": "Response string"
      },
      "line": {
        "liffId": "Response string"
      },
      "ad": {
        "saml": "Response string"
      },
      "google": {
        "enabled": false
      }
    },
    "sourceIdAccessEnabled": false,
    "sourceIdVerifyMode": {},
    "sourceIdSignatureTtlMinutes": {},
    "keycloakTokenPassthrough": false,
    "keycloakTokenPassthroughAllowedHosts": [
      "Response string"
    ],
    "organizationLogin": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  },
  "enableAnalysis": false
}
```

***

### Retrieve an Inbox <a href="#inboxes-retrieve" id="inboxes-retrieve"></a>

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

#### Parameters

| Parameter | Required | Type   | Description                           |
| --------- | -------- | ------ | ------------------------------------- |
| `id`      | ✅        | string | A UUID string identifying this Inbox. |

#### Code Examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```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 // Optional
  "signAuth"?:  // Optional
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // Optional
      {
        "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. (Optional)
    "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 (Optional)
    {
    }
    "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 (Optional)
    {
    }
    "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. (Optional)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
      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 // Optional
}
```

**Example Response Values**

```json
{
  "id": "961dcaac-bd2e-44d3-9050-82596dbb3334",
  "chatbot": {
    "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b",
    "name": "Customer service chatbot",
    "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": "Administrator group"
    }
  ],
  "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
}
```

***

### Update an Inbox <a href="#inboxes-update" id="inboxes-update"></a>

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

#### Parameters

| Parameter | Required | Type   | Description                           |
| --------- | -------- | ------ | ------------------------------------- |
| `id`      | ✅        | string | A UUID string identifying this Inbox. |

#### Request Body

**Request Parameters**

| Field                                         | Type                                                                                                                    | Required | Description                                                                                                                                                                                                  |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name                                          | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| channelType                                   | string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team\_plus, line\_works, viber) | Yes      | `line`: LINE ; `telegram`: Telegram ; `teams`: Teams ; `web`: Web ; `messenger`: Messenger ; `instagram`: Instagram ; `email`: Email ; `whatsapp`: WhatsApp ; `slack`: Slack ; `team_plus`: Team+ ; \`lin... |
| unreadConversationsCount                      | integer                                                                                                                 | No       |                                                                                                                                                                                                              |
| signAuth                                      | object (with 9 properties: id, signSource, signParams...)                                                               | No       |                                                                                                                                                                                                              |
| signAuth.signSource                           | string (uuid)                                                                                                           | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams                           | object                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak                  | object (with 3 properties: clientId, url, realm)                                                                        | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.clientId         | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.url              | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.keycloak.realm            | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.line                      | object (with 1 property: liffId)                                                                                        | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.line.liffId               | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.ad                        | object (with 1 property: saml)                                                                                          | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.ad.saml                   | string                                                                                                                  | Yes      |                                                                                                                                                                                                              |
| signAuth.signParams.google                    | object (with 1 property: enabled)                                                                                       | No       |                                                                                                                                                                                                              |
| signAuth.signParams.google.enabled            | boolean                                                                                                                 | Yes      |                                                                                                                                                                                                              |
| signAuth.sourceIdAccessEnabled                | boolean                                                                                                                 | No       | 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                                                                                                                  | No       | "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                                                                                                                  | No       | 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                                                                                                                 | No       | 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]                                                                                                          | No       | Hostnames (or "\*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to                                                                                                             |
| enableAnalysis                                | boolean                                                                                                                 | No       |                                                                                                                                                                                                              |

**Example Request Schema**

```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 // Optional
  "signAuth"?:  // Optional
  {
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // Optional
      {
        "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. (Optional)
    "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 (Optional)
    {
    }
    "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 (Optional)
    {
    }
    "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. (Optional)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
      string
    ]
  }
  "enableAnalysis"?: boolean // Optional
}
```

**Example Request Values**

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

#### Code Examples

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

```bash
# Example API call (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": "Updated name"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request payload
const data = {
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "Updated name"
  };

axios.put("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request payload
data = {
    "chatbot": {
        "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
        {
            "id": "550e8400-e29b-41d4-a716-446655440000"
        }
    ],
    "name": "Updated name"
}

response = requests.put(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Updated name'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```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 // Optional
  "signAuth"?:  // Optional
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // Optional
      {
        "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. (Optional)
    "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 (Optional)
    {
    }
    "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 (Optional)
    {
    }
    "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. (Optional)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
      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 // Optional
}
```

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "channelType": "line",
  "unreadConversationsCount": 456,
  "signAuth": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "signSource": "550e8400-e29b-41d4-a716-446655440000",
    "signParams": {
      "keycloak": {
        "clientId": "Response string",
        "url": "Response string",
        "realm": "Response string"
      },
      "line": {
        "liffId": "Response string"
      },
      "ad": {
        "saml": "Response string"
      },
      "google": {
        "enabled": false
      }
    },
    "sourceIdAccessEnabled": false,
    "sourceIdVerifyMode": {},
    "sourceIdSignatureTtlMinutes": {},
    "keycloakTokenPassthrough": false,
    "keycloakTokenPassthroughAllowedHosts": [
      "Response string"
    ],
    "organizationLogin": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  },
  "enableAnalysis": false
}
```

***

### Partially Update Inbox <a href="#inboxes-partial-update" id="inboxes-partial-update"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                           |
| -------------- | -------- | ------ | ------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Inbox. |

#### Request Body

**Request Parameters**

| Field                                         | Type                                                                                                                    | Required | Description                                                                                                                                                                                                     |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| groups                                        | array\[IdName]                                                                                                          | No       | List of groups that can access this inbox                                                                                                                                                                       |
| channelType                                   | string (enum: line, telegram, teams, web, messenger, instagram, email, whatsapp, slack, team\_plus, line\_works, viber) | No       | `line`: LINE ; `telegram`: Telegram ; `teams`: Teams ; `web`: Web ; `messenger`: Messenger ; `instagram`: Instagram ; `email`: Email ; `whatsapp`: WhatsApp ; `slack`: Slack ; `team_plus`: Team+ ; \`lin...    |
| name                                          | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| autoReplySchedules                            | array\[AutoReplySchedule]                                                                                               | No       |                                                                                                                                                                                                                 |
| channel                                       | object                                                                                                                  | No       |                                                                                                                                                                                                                 |
| organization                                  | string (uuid)                                                                                                           | No       |                                                                                                                                                                                                                 |
| signAuth                                      | object (with 10 properties: id, signSource, signParams...)                                                              | No       |                                                                                                                                                                                                                 |
| signAuth.signSource                           | string (uuid)                                                                                                           | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams                           | object                                                                                                                  | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak                  | object (with 3 properties: clientId, url, realm)                                                                        | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak.clientId         | string                                                                                                                  | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak.url              | string                                                                                                                  | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.keycloak.realm            | string                                                                                                                  | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.line                      | object (with 1 property: liffId)                                                                                        | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.line.liffId               | string                                                                                                                  | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.ad                        | object (with 1 property: saml)                                                                                          | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.ad.saml                   | string                                                                                                                  | Yes      |                                                                                                                                                                                                                 |
| signAuth.signParams.google                    | object (with 1 property: enabled)                                                                                       | No       |                                                                                                                                                                                                                 |
| signAuth.signParams.google.enabled            | boolean                                                                                                                 | Yes      |                                                                                                                                                                                                                 |
| signAuth.sourceIdAccessEnabled                | boolean                                                                                                                 | No       | 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                                                                                                                  | No       | "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                                                                                                                  | No       | 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                                                                                                                 | No       | 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]                                                                                                          | No       | Hostnames (or "\*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to                                                                                                                |
| enableTimeAwareResponse                       | boolean                                                                                                                 | No       | Enable time aware responses for this inbox                                                                                                                                                                      |
| defaultTimezone                               | string                                                                                                                  | No       | Default timezone for this inbox (e.g., Asia/Taipei, America/New\_York)                                                                                                                                          |
| enableSenderNameAwareResponse                 | boolean                                                                                                                 | No       | Enable sender name aware responses for this inbox                                                                                                                                                               |
| enableGpsAwareResponse                        | boolean                                                                                                                 | No       | Enable GPS aware responses for this inbox                                                                                                                                                                       |
| gpsRequestTiming                              | object                                                                                                                  | No       | 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                                                                                                                 | No       | 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                                                                                                                 | No       | 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                                                                                                                 | No       | 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                                                                                                                 | No       |                                                                                                                                                                                                                 |
| enableHumanHandoff                            | boolean                                                                                                                 | No       |                                                                                                                                                                                                                 |
| handoffPrompt                                 | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| handoffLlm                                    | string (uuid)                                                                                                           | No       |                                                                                                                                                                                                                 |
| handoffContextMessageLimit                    | integer                                                                                                                 | No       |                                                                                                                                                                                                                 |
| handoffMessage                                | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| queuingMessage                                | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| assignedMessage                               | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| enablePendingReplyMessage                     | boolean                                                                                                                 | No       | Send a placeholder message to the user while the AI is processing.                                                                                                                                              |
| pendingReplyMessage                           | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| pendingReplyInitialDelaySeconds               | integer                                                                                                                 | No       | Delay before sending the first pending reply, so a fast AI response can pre-empt it.                                                                                                                            |
| pendingReplyIntervalSeconds                   | integer                                                                                                                 | No       | Interval to repeat the pending reply while the AI is still processing.                                                                                                                                          |
| enablePendingReplyCleanup                     | boolean                                                                                                                 | No       | Delete pending reply messages after the AI reply is sent. Only effective on platforms that support message deletion (Teams, Telegram, Slack).                                                                   |
| enableAnalysis                                | boolean                                                                                                                 | No       |                                                                                                                                                                                                                 |
| analysisLlm                                   | string (uuid)                                                                                                           | No       |                                                                                                                                                                                                                 |
| analysisPrompt                                | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| analysisContextMessageLimit                   | integer                                                                                                                 | No       |                                                                                                                                                                                                                 |
| analysisGenerateSummary                       | boolean                                                                                                                 | No       | When on, conversation analysis writes the conversation summary (editable, with revisions); inbox auto split brings it to the next conversation                                                                  |
| analysisApplyTags                             | boolean                                                                                                                 | No       | When on, conversation analysis picks the conversation tags from the inbox tags                                                                                                                                  |
| enableServiceHours                            | boolean                                                                                                                 | No       |                                                                                                                                                                                                                 |
| serviceHoursTimezone                          | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| offlineBehavior                               | string (enum: show\_message, leave\_message)                                                                            | No       | `show_message`: Show Message ; `leave_message`: Leave Message;                                                                                                                                                  |
| offlineMessage                                | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| serviceHoursSchedules                         | array\[ServiceHoursSchedule]                                                                                            | No       |                                                                                                                                                                                                                 |
| dispatchMode                                  | object                                                                                                                  | No       | 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)                                                                              | No       | `round_robin`: Round Robin ; `least_active`: Least Active;                                                                                                                                                      |
| assignmentMaxConcurrent                       | integer                                                                                                                 | No       |                                                                                                                                                                                                                 |
| assignmentQueueTimeout                        | integer                                                                                                                 | No       | Queue timeout in seconds                                                                                                                                                                                        |
| queueTimeoutMessage                           | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| maxQueueSize                                  | integer                                                                                                                 | No       |                                                                                                                                                                                                                 |
| queueFullMessage                              | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| assignmentTargetMembers                       | array\[string]                                                                                                          | No       |                                                                                                                                                                                                                 |
| enableTagRouting                              | boolean                                                                                                                 | No       |                                                                                                                                                                                                                 |
| enableReassignOnTimeout                       | boolean                                                                                                                 | No       | 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                                                                                                                 | No       | Reply with a throttled waiting reminder when the contact sends messages while queued.                                                                                                                           |
| queueReminderMessage                          | string                                                                                                                  | No       |                                                                                                                                                                                                                 |
| queueReminderCooldown                         | integer                                                                                                                 | No       | Minimum seconds between queue reminders in one conversation                                                                                                                                                     |
| enableQueueCancel                             | boolean                                                                                                                 | No       | Allow the contact to cancel a queued handoff and return to the AI by themselves.                                                                                                                                |
| queueCancelButtonText                         | string                                                                                                                  | No       | 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                                                                                                                  | No       | 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                                                                                                                  | No       | Sent to the contact right after they cancel the queued handoff.                                                                                                                                                 |
| enableIdleAutoResolve                         | boolean                                                                                                                 | No       | 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                                                                                                                 | No       | Minutes the contact may stay silent after the last agent reply before auto resolve                                                                                                                              |
| idleAutoResolveMessage                        | string                                                                                                                  | No       | 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                                                                                                                 | No       | 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                                                                                                                 | No       | Seconds (60-86400) a contact message may go unanswered by a human agent before the AI takes over                                                                                                                |
| agentReplyTimeoutMessage                      | string                                                                                                                  | No       | Sent to the contact when the conversation returns to the AI; leave empty to send none.                                                                                                                          |
| enableReturnToPreviousAssignee                | boolean                                                                                                                 | No       | 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                                                                                                                 | No       | 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                                                                                                                 | No       | 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                                                                                                                 | No       | Split when the latest conversation was resolved more than the configured minutes ago                                                                                                                            |
| autoSplitResolveMinutes                       | integer                                                                                                                 | No       | Minutes (0-10080) after the latest resolve; 0 splits on the next contact message                                                                                                                                |
| autoSplitOnIdle                               | boolean                                                                                                                 | No       | 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                                                                                                                 | No       | Hours (1-720) since the last message of the latest conversation                                                                                                                                                 |
| enableContinuationSummary                     | boolean                                                                                                                 | No       | 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                                                                                                                 | No       | How many previous conversations (1-3) a new conversation looks back at for summaries                                                                                                                            |
| copilotEnabled                                | boolean                                                                                                                 | No       |                                                                                                                                                                                                                 |
| copilotTriggerMode                            | string (enum: manual, every\_incoming)                                                                                  | No       | `manual`: Manual ; `every_incoming`: Every Incoming;                                                                                                                                                            |
| quotaExceededMessage                          | string                                                                                                                  | No       | 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                                                                                                                  | No       | 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...   |

**Example Request Schema**

```typescript
{
  "groups"?: [ // List of groups that can access this inbox (Optional)
    {
      "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 (Optional)
  "name"?: string // Optional
  "autoReplySchedules"?: [ // Optional
    {
      "isEnabled"?: boolean // Optional
      "timeSlots"?: [ // Optional
        array[string]
      ]
    }
  ]
  "channel"?: // May have different types (Optional)
  {
    "avatar"?: string (uri) // Optional
    "logo"?: string (uri) // Optional
    "description"?: string // Optional
    "cover"?: string (uri) // Optional
    "backUrl"?: string // Optional
    "isActive"?: boolean // Optional
    "theme": {
    {
      "primaryColor"?: string // Optional
      "navbarTextColor"?: string // Optional
      "conversationBackgroundColor"?: string // Optional
      "chatbotMessageTextColor"?: string // Optional
      "userMessageTextColor"?: string // Optional
      "chatbotMessageBackgroundColor"?: string // Optional
      "userMessageBackgroundColor"?: string // Optional
      "chatbotMessageBackgroundShadowEnabled"?: boolean // Optional
      "userMessageBackgroundShadowEnabled"?: boolean // Optional
      "chatbotMessageGradientEnabled"?: boolean // Optional
      "userMessageGradientEnabled"?: boolean // Optional
    }
    }
    "darkTheme": {
    {
      "primaryColor"?: string // Optional
      "navbarTextColor"?: string // Optional
      "conversationBackgroundColor"?: string // Optional
      "chatbotMessageTextColor"?: string // Optional
      "userMessageTextColor"?: string // Optional
      "chatbotMessageBackgroundColor"?: string // Optional
      "userMessageBackgroundColor"?: string // Optional
      "chatbotMessageBackgroundShadowEnabled"?: boolean // Optional
      "userMessageBackgroundShadowEnabled"?: boolean // Optional
      "chatbotMessageGradientEnabled"?: boolean // Optional
      "userMessageGradientEnabled"?: boolean // Optional
    }
    }
    "enableFileUpload"?: boolean // Optional
    "enableDisplayCitations"?: boolean // Optional
    "toolDisplayMode"?: string (enum: full, compact, hidden) // * `full` - Full
* `compact` - Compact
* `hidden` - Hidden (Optional)
    "enableAskOptionButtons"?: boolean // When enabled, ask_user_question options appear as a row of buttons above the input field, which remains usable. When disabled, the existing overlay panel is retained. This gradual rollout switch can be disabled at any time to revert the behavior. (Optional)
    "enableConversationHandoff"?: boolean // When enabled, this inbox's webchat displays the handoff UI (notification bar, summary card, and continuation button) and registers handoff tools. The global handoff switch in system settings still applies: disabling it disables handoff everywhere. MaiGPT always displays this UI regardless of this switch. The context usage percentage bar at the bottom is controlled separately by "Display Context Usage". Disabled by default, so customer-facing webchat shows no handoff UI. This gradual rollout switch can be disabled to revert the behavior without rolling back the release. (Optional)
    "enableDisplayContextUsage"?: boolean // When enabled, this inbox's webchat displays a context usage percentage bar below the input field. This is independent of conversation handoff: handoff switches, including the global handoff switch, do not affect it, and it does not affect the handoff notification bar. MaiGPT always displays the bar regardless of this switch. Disabled by default; disable it to revert the behavior without rolling back the release. (Optional)
    "enableDisplayThinking"?: boolean // Optional
    "enableUserThinkingControl"?: boolean // Optional
    "enableDisplayQueryMetadata"?: boolean // Optional
    "enableDisplayHookMarkers"?: boolean // Optional
    "hookMarkerTextInputModify"?: string // Optional
    "hookMarkerTextOutputModify"?: string // Optional
    "hookMarkerTextInputBlock"?: string // Optional
    "hookMarkerTextOutputBlock"?: string // Optional
    "enableShareConversation"?: boolean // Optional
    "enableLocation"?: boolean // Optional
    "enableShowPoweredBy"?: boolean // Optional
    "poweredByLogo"?: string (uri) // Optional
    "enableAnonymous"?: boolean // Optional
    "enableDisplayPreviousConversation"?: boolean // Optional
    "enableDisplayConversationHistory"?: boolean // Optional
    "enableConversationTimer"?: boolean // Optional
    "conversationTimerDuration"?: integer // Timer timeout duration, ranging from 3 to 60 minutes (Optional)
    "enableAutoNewConversationOnTimeout"?: boolean // Optional
    "enableSatisfactionSurvey"?: boolean // Optional
    "satisfactionSurveyDelayMinutes"?: integer // Minutes after the last AI reply before the survey appears, ranging from 1 to 60 minutes (Optional)
    "satisfactionSurveyPrompt"?: string // Custom survey title; leave blank to use the frontend's default localized text (Optional)
    "enableThemeModeToggle"?: boolean // Optional
    "enableDisplayFontSizeSwitch"?: boolean // Optional
    "defaultThemeMode"?:  // Optional
    {
    }
    "enableDownloadCitations"?: boolean // Optional
    "customDomain"?:  // Optional
    {
      "domain": string
    }
    "enableDisplayChatbotAvatar"?: boolean // Optional
    "enableDisplayChatbotName"?: boolean // Optional
    "buttonIcon"?: string (uri) // Optional
    "conversationStartersDisplayCount"?: integer // Optional
    "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. (Optional)
    "preChatFormEnabled"?: boolean // Optional
    "preChatFormFields"?: object // Optional
    "preChatFormTitle"?: object // Optional
    "preChatFormSubtitle"?: object // Optional
    "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 (Optional)
    {
    }
    "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. (Optional)
    "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. (Optional)
    "loadingLongWaitThresholdSeconds"?: integer // How long a single reply must be pending before the long-wait copy appears. (Optional)
    "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. (Optional)
    "loadingAnimationSharedAssetUrl"?: string (uri) // Optional
    "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. (Optional)
    "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. (Optional)
    "toolCardRunningIconUrl"?: string (uri) // Optional
    "toolCardCompletedIconUrl"?: string (uri) // Optional
    "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. (Optional)
      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. (Optional)
    "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. (Optional)
      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. (Optional)
    "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. (Optional)
      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. (Optional)
    "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. (Optional)
      string
    ]
  }
  "organization"?: string (uuid) // Optional
  "signAuth"?:  // Optional
  {
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // Optional
      {
        "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. (Optional)
    "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 (Optional)
    {
    }
    "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 (Optional)
    {
    }
    "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. (Optional)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
      string
    ]
  }
  "enableTimeAwareResponse"?: boolean // Enable time aware responses for this inbox (Optional)
  "defaultTimezone"?: string // Default timezone for this inbox (e.g., Asia/Taipei, America/New_York) (Optional)
  "enableSenderNameAwareResponse"?: boolean // Enable sender name aware responses for this inbox (Optional)
  "enableGpsAwareResponse"?: boolean // Enable GPS aware responses for this inbox (Optional)
  "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 (Optional)
  {
  }
  "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). (Optional)
  "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. (Optional)
  "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). (Optional)
  "enableStreamMessage"?: boolean // Optional
  "enableHumanHandoff"?: boolean // Optional
  "handoffPrompt"?: string // Optional
  "handoffLlm"?: string (uuid) // Optional
  "handoffContextMessageLimit"?: integer // Optional
  "handoffMessage"?: string // Optional
  "queuingMessage"?: string // Optional
  "assignedMessage"?: string // Optional
  "enablePendingReplyMessage"?: boolean // Send a placeholder message to the user while the AI is processing. (Optional)
  "pendingReplyMessage"?: string // Optional
  "pendingReplyInitialDelaySeconds"?: integer // Delay before sending the first pending reply, so a fast AI response can pre-empt it. (Optional)
  "pendingReplyIntervalSeconds"?: integer // Interval to repeat the pending reply while the AI is still processing. (Optional)
  "enablePendingReplyCleanup"?: boolean // Delete pending reply messages after the AI reply is sent. Only effective on platforms that support message deletion (Teams, Telegram, Slack). (Optional)
  "enableAnalysis"?: boolean // Optional
  "analysisLlm"?: string (uuid) // Optional
  "analysisPrompt"?: string // Optional
  "analysisContextMessageLimit"?: integer // Optional
  "analysisGenerateSummary"?: boolean // When on, conversation analysis writes the conversation summary (editable, with revisions); inbox auto split brings it to the next conversation (Optional)
  "analysisApplyTags"?: boolean // When on, conversation analysis picks the conversation tags from the inbox tags (Optional)
  "enableServiceHours"?: boolean // Optional
  "serviceHoursTimezone"?: string // Optional
  "offlineBehavior"?: string (enum: show_message, leave_message) // * `show_message` - Show Message
* `leave_message` - Leave Message (Optional)
  "offlineMessage"?: string // Optional
  "serviceHoursSchedules"?: [ // Optional
    {
      "weekday": integer
      "startTime": string (time)
      "endTime": string (time)
      "isEnabled"?: boolean // Optional
    }
  ]
  "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) (Optional)
  {
  }
  "assignmentRoutingModel"?: string (enum: round_robin, least_active) // * `round_robin` - Round Robin
* `least_active` - Least Active (Optional)
  "assignmentMaxConcurrent"?: integer // Optional
  "assignmentQueueTimeout"?: integer // Queue timeout in seconds (Optional)
  "queueTimeoutMessage"?: string // Optional
  "maxQueueSize"?: integer // Optional
  "queueFullMessage"?: string // Optional
  "assignmentTargetMembers"?: [ // Optional
    string (uuid)
  ]
  "enableTagRouting"?: boolean // Optional
  "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. (Optional)
  "enableQueueReminder"?: boolean // Reply with a throttled waiting reminder when the contact sends messages while queued. (Optional)
  "queueReminderMessage"?: string // Optional
  "queueReminderCooldown"?: integer // Minimum seconds between queue reminders in one conversation (Optional)
  "enableQueueCancel"?: boolean // Allow the contact to cancel a queued handoff and return to the AI by themselves. (Optional)
  "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. (Optional)
  "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. (Optional)
  "queueCancelMessage"?: string // Sent to the contact right after they cancel the queued handoff. (Optional)
  "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. (Optional)
  "idleAutoResolveMinutes"?: integer // Minutes the contact may stay silent after the last agent reply before auto resolve (Optional)
  "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. (Optional)
  "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. (Optional)
  "agentReplyTimeout"?: integer // Seconds (60-86400) a contact message may go unanswered by a human agent before the AI takes over (Optional)
  "agentReplyTimeoutMessage"?: string // Sent to the contact when the conversation returns to the AI; leave empty to send none. (Optional)
  "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. (Optional)
  "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 (Optional)
  "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. (Optional)
  "autoSplitOnResolve"?: boolean // Split when the latest conversation was resolved more than the configured minutes ago (Optional)
  "autoSplitResolveMinutes"?: integer // Minutes (0-10080) after the latest resolve; 0 splits on the next contact message (Optional)
  "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 (Optional)
  "autoSplitIdleHours"?: integer // Hours (1-720) since the last message of the latest conversation (Optional)
  "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. (Optional)
  "continuationSummaryCount"?: integer // How many previous conversations (1-3) a new conversation looks back at for summaries (Optional)
  "copilotEnabled"?: boolean // Optional
  "copilotTriggerMode"?: string (enum: manual, every_incoming) // * `manual` - Manual
* `every_incoming` - Every Incoming (Optional)
  "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. (Optional)
  "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`. (Optional)
}
```

**Example Request Values**

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

#### Code Examples

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

```bash
# API call example (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": "Updated name"
  }'

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request body (payload)
const data = {
    "chatbot": {
      "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000"
      }
    ],
    "name": "Updated name"
  };

axios.patch("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request body (payload)
data = {
    "chatbot": {
        "id": "80f3170d-eed7-4651-a8da-6b7e6bdbef8b"
    },
    "groups": [
        {
            "id": "550e8400-e29b-41d4-a716-446655440000"
        }
    ],
    "name": "Updated name"
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Updated name'
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response

**Status code: 200**

**Example Response Schema**

```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 // Optional
  "signAuth"?:  // Optional
  {
    "id": string (uuid)
    "signSource": string (uuid)
    "signParams": {
    {
      "keycloak": 
      {
        "clientId": string
        "url": string
        "realm": string
      }
      "line": 
      {
        "liffId": string
      }
      "ad": 
      {
        "saml": string
      }
      "google"?:  // Optional
      {
        "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. (Optional)
    "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 (Optional)
    {
    }
    "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 (Optional)
    {
    }
    "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. (Optional)
    "keycloakTokenPassthroughAllowedHosts"?: [ // Hostnames (or "*.example.com" wildcards) of the tools the visitor Keycloak token may be sent to (Optional)
      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 // Optional
}
```

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "channelType": "line",
  "unreadConversationsCount": 456,
  "signAuth": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "signSource": "550e8400-e29b-41d4-a716-446655440000",
    "signParams": {
      "keycloak": {
        "clientId": "Response string",
        "url": "Response string",
        "realm": "Response string"
      },
      "line": {
        "liffId": "Response string"
      },
      "ad": {
        "saml": "Response string"
      },
      "google": {
        "enabled": false
      }
    },
    "sourceIdAccessEnabled": false,
    "sourceIdVerifyMode": {},
    "sourceIdSignatureTtlMinutes": {},
    "keycloakTokenPassthrough": false,
    "keycloakTokenPassthroughAllowedHosts": [
      "Response string"
    ],
    "organizationLogin": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Example response name",
      "description": "Example response description"
    }
  },
  "enableAnalysis": false
}
```

***

### Delete a Conversation Platform <a href="#inboxes-destroy" id="inboxes-destroy"></a>

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

#### Parameters

| Parameter name | Required | Type   | Description                           |
| -------------- | -------- | ------ | ------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Inbox. |

#### Code examples

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

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

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request body (payload)
const data = null;

axios.delete("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response body

| Status Code | Description      |
| ----------- | ---------------- |
| 204         | No response body |

***

### List Webhooks for an Inbox <a href="#inboxes-webhooks-list" id="inboxes-webhooks-list"></a>

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

#### Parameters

| Parameter Name | Required | Type    | Description                                    |
| -------------- | -------- | ------- | ---------------------------------------------- |
| `inboxPk`      | ✅        | string  |                                                |
| `page`         | ❌        | integer | A page number within the paginated result set. |
| `pageSize`     | ❌        | integer | Number of results to return per page.          |

#### Code Examples

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

```bash
# Example API call (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"

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```typescript
{
  "count": integer
  "next"?: string (uri) // Optional
  "previous"?: string (uri) // Optional
  "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 // Optional
      "url": string (uri)
      "method"?:  // Optional
      {
      }
      "headersMasked": object
      "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (Optional)
      "templatePresetLabel": string
      "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (Optional)
      "payloadPreset"?: // May have different types (Optional)
      string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

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

**Example Response Values**

```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": "Response string",
      "direction": {},
      "directionLabel": "Response string",
      "isEnabled": false,
      "url": "https://example.com/file.jpg",
      "method": {},
      "headersMasked": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Example response name",
        "description": "Example response description"
      },
      "templatePreset": "maiagent_standard",
      "templatePresetLabel": "Response string",
      "customTemplate": "Response string",
      "payloadPreset": "genesys_cloud",
      "payloadPresetLabel": "Response string",
      "receiveUrl": "Response string",
      "createdAt": "Response string",
      "updatedAt": "Response string"
    }
  ]
}
```

***

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

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

{% hint style="info" %}
Set `direction` to `incoming` (triggered when a user message arrives) or `outgoing` (triggered when the Agent replies); select `maiagent_standard` for `template_preset` to use the MaiAgent standard payload.
{% endhint %}

#### Parameters

| Parameter Name | Required | Type   | Description |
| -------------- | -------- | ------ | ----------- |
| `inboxPk`      | ✅        | string |             |

#### Request Body

**Request Parameters**

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

**Example Request Schema**

```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 // Optional
  "url"?: string (uri) // Optional
  "method"?:  // Optional
  {
  }
  "headers"?: object // Custom HTTP headers as JSON object (Optional)
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (Optional)
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (Optional)
  "secretToken"?: string // Secret token for webhook signature verification (Optional)
  "payloadPreset"?: // May have different types (Optional)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (Optional)
}
```

**Example Request Values**

```json
{
  "name": "Example name",
  "direction": {},
  "isEnabled": true,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headers": null,
  "templatePreset": "maiagent_standard",
  "customTemplate": "Example string",
  "secretToken": "Example string",
  "payloadPreset": null
}
```

#### Code Examples

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

```bash
# Example API call (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": "Example name",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "payloadPreset": null
  }'

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "name": "Example name",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "payloadPreset": null
  };

axios.post("https://api.maiagent.ai/api/v1/inboxes/550e8400-e29b-41d4-a716-446655440000/webhooks/", data, config)
  .then(response => {
    console.log('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "name": "Example name",
    "direction": {},
    "isEnabled": True,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": None,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "payloadPreset": None
}

response = requests.post(url, json=data, headers=headers)
try:
    print("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Example name',
            'direction' => new \stdClass(),
            'isEnabled' => true,
            'url' => 'https://example.com/file.jpg',
            'method' => new \stdClass(),
            'headers' => null,
            'templatePreset' => 'maiagent_standard',
            'customTemplate' => 'Example string',
            'secretToken' => 'Example string',
            'payloadPreset' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 201**

**Example Response Schema**

```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 // Optional
  "url": string (uri)
  "method"?:  // Optional
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (Optional)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (Optional)
  "payloadPreset"?: // May have different types (Optional)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

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

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "direction": {},
  "directionLabel": "Response string",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "Response string",
  "customTemplate": "Response string",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "Response string",
  "receiveUrl": "Response string",
  "createdAt": "Response string",
  "updatedAt": "Response string"
}
```

***

### Retrieve a Specific Webhook <a href="#inboxes-webhooks-retrieve" id="inboxes-webhooks-retrieve"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                   |
| -------------- | -------- | ------ | --------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk`      | ✅        | string |                                               |

#### Code Examples

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

```bash
# Example API call (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"

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request error:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```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 // Optional
  "url": string (uri)
  "method"?:  // Optional
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (Optional)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (Optional)
  "payloadPreset"?: // May have different types (Optional)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

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

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "direction": {},
  "directionLabel": "Response string",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "Response string",
  "customTemplate": "Response string",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "Response string",
  "receiveUrl": "Response string",
  "createdAt": "Response string",
  "updatedAt": "Response string"
}
```

***

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

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

#### Parameters

| Parameter Name | Required | Type   | Description                                   |
| -------------- | -------- | ------ | --------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk`      | ✅        | string |                                               |

#### Request Body

**Request Parameters**

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

**Example Request Schema**

```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 // Optional
  "url"?: string (uri) // Optional
  "method"?:  // Optional
  {
  }
  "headers"?: object // Custom HTTP headers as JSON object (Optional)
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (Optional)
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (Optional)
  "secretToken"?: string // Secret token for webhook signature verification (Optional)
  "payloadPreset"?: // May have different types (Optional)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

* `genesys_cloud` - Genesys Cloud (Optional)
}
```

**Example Request Values**

```json
{
  "name": "Example name",
  "direction": {},
  "isEnabled": true,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headers": null,
  "templatePreset": "maiagent_standard",
  "customTemplate": "Example string",
  "secretToken": "Example string",
  "payloadPreset": null
}
```

#### Code Examples

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

```bash
# Example API call (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": "Example name",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "payloadPreset": null
  }'

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "name": "Example name",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "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('Successfully received response:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "name": "Example name",
    "direction": {},
    "isEnabled": True,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": None,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "payloadPreset": None
}

response = requests.put(url, json=data, headers=headers)
try:
    print("Successfully received response:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Example name',
            'direction' => new \stdClass(),
            'isEnabled' => true,
            'url' => 'https://example.com/file.jpg',
            'method' => new \stdClass(),
            'headers' => null,
            'templatePreset' => 'maiagent_standard',
            'customTemplate' => 'Example string',
            'secretToken' => 'Example string',
            'payloadPreset' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Successfully received response:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```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 // Optional
  "url": string (uri)
  "method"?:  // Optional
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (Optional)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (Optional)
  "payloadPreset"?: // May have different types (Optional)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

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

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "direction": {},
  "directionLabel": "Response string",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "Response string",
  "customTemplate": "Response string",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "Response string",
  "receiveUrl": "Response string",
  "createdAt": "Response string",
  "updatedAt": "Response string"
}
```

***

### Partially Update Webhook <a href="#inboxes-webhooks-partial-update" id="inboxes-webhooks-partial-update"></a>

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

#### Parameters

| Parameter Name | Required | Type   | Description                                   |
| -------------- | -------- | ------ | --------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk`      | ✅        | string |                                               |

#### Request Body

**Request Parameters**

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

**Example Request Schema**

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

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

* `genesys_cloud` - Genesys Cloud (Optional)
}
```

**Example Request Values**

```json
{
  "name": "Example name",
  "direction": {},
  "isEnabled": true,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headers": null,
  "templatePreset": "maiagent_standard",
  "customTemplate": "Example string",
  "secretToken": "Example string",
  "payloadPreset": null
}
```

#### Code Examples

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

```bash
# API call example (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": "Example name",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "payloadPreset": null
  }'

# Before running, replace YOUR_API_KEY and verify the request data.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Set request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
};

// Request Body (payload)
const data = {
    "name": "Example name",
    "direction": {},
    "isEnabled": true,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": null,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "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('Successfully received response:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request 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"
}

# Request Body (payload)
data = {
    "name": "Example name",
    "direction": {},
    "isEnabled": True,
    "url": "https://example.com/file.jpg",
    "method": {},
    "headers": None,
    "templatePreset": "maiagent_standard",
    "customTemplate": "Example string",
    "secretToken": "Example string",
    "payloadPreset": None
}

response = requests.patch(url, json=data, headers=headers)
try:
    print("Successfully received response:")
    print(response.json())
except Exception as e:
    print("Request error:", 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' => 'Example name',
            'direction' => new \stdClass(),
            'isEnabled' => true,
            'url' => 'https://example.com/file.jpg',
            'method' => new \stdClass(),
            'headers' => null,
            'templatePreset' => 'maiagent_standard',
            'customTemplate' => 'Example string',
            'secretToken' => 'Example string',
            'payloadPreset' => null
        ]
    ]);
    
    $data = json_decode($response->getBody(), true);
    echo "Successfully received response:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request error: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

**Status Code: 200**

**Example Response Schema**

```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 // Optional
  "url": string (uri)
  "method"?:  // Optional
  {
  }
  "headersMasked": object
  "templatePreset"?: string (enum: maiagent_standard, genesys_cloud, custom) // * `maiagent_standard` - MaiAgent Standard
* `genesys_cloud` - Genesys Cloud
* `custom` - Custom (Optional)
  "templatePresetLabel": string
  "customTemplate"?: string // Jinja2 template for custom payload format. Required when template_preset is "custom". (Optional)
  "payloadPreset"?: // May have different types (Optional)
  string (enum: genesys_cloud) // Preset for parsing incoming webhook payloads (used with direction=receive)

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

**Example Response Values**

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "inbox": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Response string",
  "direction": {},
  "directionLabel": "Response string",
  "isEnabled": false,
  "url": "https://example.com/file.jpg",
  "method": {},
  "headersMasked": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Example response name",
    "description": "Example response description"
  },
  "templatePreset": "maiagent_standard",
  "templatePresetLabel": "Response string",
  "customTemplate": "Response string",
  "payloadPreset": "genesys_cloud",
  "payloadPresetLabel": "Response string",
  "receiveUrl": "Response string",
  "createdAt": "Response string",
  "updatedAt": "Response string"
}
```

***

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

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

#### Parameters

| Parameter Name | Required | Type   | Description                                   |
| -------------- | -------- | ------ | --------------------------------------------- |
| `id`           | ✅        | string | A UUID string identifying this Inbox Webhook. |
| `inboxPk`      | ✅        | string |                                               |

#### Code Examples

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

```bash
# API Call Example (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"

# Replace YOUR_API_KEY and verify the request data before running.
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Configure request headers
const config = {
  headers: {
    'Authorization': 'Api-Key YOUR_API_KEY'
  }
};

// Request body (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('Response received successfully:');
    console.log(response.data);
  })
  .catch(error => {
    console.error('Request failed:');
    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("Response received successfully:")
    print(response.json())
except Exception as e:
    print("Request failed:", 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 "Response received successfully:\n";
    print_r($data);
} catch (Exception $e) {
    echo 'Request failed: ' . $e->getMessage();
}
?>
```

{% endtab %}
{% endtabs %}

#### Response Body

| Status Code | Description      |
| ----------- | ---------------- |
| 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/en/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.
