> ## Documentation Index
> Fetch the complete documentation index at: https://docs.acedata.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Chat v2 API інтеграційна інструкція

> AI Dialogue API guide - Ace Data Cloud

AI Chat v2 API (`/aichat2/conversations`) є новим поколінням діалогового інтерфейсу, що є повним оновленням [AI Chat API](https://platform.acedata.cloud/documents/aichat-conversations). Він розширює v1, що є простим і підтримує багатократні діалоги, наступними можливостями:

* **Багатомодальний ввід користувача**: через структуроване поле `message` можна безпосередньо передавати текст + зображення + файли, без необхідності спочатку використовувати `references` для непрямого додавання.
* **Інструменти для виклику агентів**: вбудований набір інструментів для пошуку в Інтернеті, веб-скрапінгу, читання файлів тощо, а також можливість підключення до серверів MCP, авторизованих користувачем (Google Drive, Notion, Slack, GitHub тощо), модель може самостійно викликати інструменти для виконання складних завдань в одному запиті.
* **Структуровані потокові події**: через `accept: text/event-stream` або `application/x-ndjson` можна отримати події `text_delta`, `tool_use`, `tool_result`, `thinking`, `citation`, `card`, `artifact` тощо, що полегшує рендеринг на фронтенді за відповідними типами.
* **Можливість переривання / відновлення**: модель надсилає подію `ask_user_question` і призупиняється, коли їй потрібна додаткова інформація від користувача, наступний виклик може продовжити через `tool_results`, заповнивши відповідь.
* **Нові CRUD дії**: на одному й тому ж кінцевому пункті через поле `action` можна виконати `retrieve` / `retrieve_batch` / `update` / `delete`, без необхідності додаткового API для управління сесіями.
* **Постійно оновлюваний список моделей**: за замовчуванням підключено GPT-5.4, Claude Opus 4.8, Claude Sonnet 4.6, Gemini 3.1 Pro, GLM 5.1, DeepSeek V4, Kimi K3 та інші сучасні моделі.

Водночас на рівні тіла запиту **повністю зберігається зворотна сумісність з v1**: достатньо передати `model` + `question` (+ необов'язкові `stateful` / `id` / `references` / `preset`), щоб отримати еквівалентну `{answer, id}` JSON відповідь, тому для міграції з `/aichat/conversations` не потрібно переписувати клієнт, достатньо змінити шлях на `/aichat2/conversations`.

> Якщо ви наразі використовуєте `/aichat/conversations`, старий інтерфейс залишиться доступним, ви можете мігрувати у своєму темпі.

## Процес подачі заявки

Щоб використовувати AI Chat v2 API, спочатку перейдіть до [консолі Ace Data Cloud](https://platform.acedata.cloud/console/applications), щоб отримати ваш API Token, зберігайте його на всяк випадок.

![](https://cdn.acedata.cloud/5hmkdg.jpg)

Якщо ви ще не увійшли в систему або не зареєстровані, вас автоматично перенаправлять на сторінку входу, щоб запросити реєстрацію та вхід, після чого ви будете автоматично повернені на поточну сторінку.

**Один API Token дозволяє викликати всі послуги платформи, не потрібно окремо подавати заявку на кожну послугу.** Перший запит на отримання токена надає безкоштовний ліміт, щоб ви могли безкоштовно протестувати; при недостатньому ліміті ви можете поповнити загальний баланс в [консолі](https://platform.acedata.cloud/console/coin).

> 📘 Повна документація: [AI Chat v2 API →](https://platform.acedata.cloud/documents/aichat2-conversations)

## Основне використання

Найпростіший спосіб використання повністю ідентичний v1: передайте `model` + `question`, отримайте `{answer, id}`.

CURL приклад:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "question": "Розкажіть одним реченням про AceDataCloud."
  }'
```

Повернене значення:

```json theme={null}
{
  "answer": "AceDataCloud - це об'єднана API платформа, що агрегує основні AI моделі та багатократні послуги, розробники можуть викликати GPT, Claude, Gemini, Midjourney, Suno, Veo та інші послуги за допомогою одного ключа.",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

Python приклад:

```python theme={null}
import requests

url = "https://api.acedata.cloud/aichat2/conversations"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json",
}

payload = {
    "model": "gpt-5.4",
    "question": "Розкажіть одним реченням про AceDataCloud.",
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())
```

Доступні значення `model` можна безпосередньо побачити у випадаючому меню панелі спроби праворуч, поширені категорії включають:

* OpenAI: `gpt-5.4-mini`, `gpt-5.4-nano`, `gpt-5.2-pro`, `gpt-5.1-all`, `gpt-5-all`, `gpt-4.1`, `gpt-4o`, `gpt-4o-image`, `o3`, `o4-mini` тощо
* Anthropic: `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6`, `claude-opus-4-5-20251101`, `claude-sonnet-4-6`, `claude-sonnet-4-5-20250929`, `claude-haiku-4-5-20251001` тощо
* Google: `gemini-3.1-pro`, `gemini-3.1-pro-preview`, `gemini-3.1-flash-image-preview`, `gemini-3-pro-preview`, `gemini-2.5-flash-lite` тощо
* xAI: `grok-4` тощо
* DeepSeek: `deepseek-v4-flash`, `deepseek-v3.2-exp`, `deepseek-r1-0528` тощо
* Moonshot: `kimi-k3`, `kimi-k2.6`, `kimi-k2.5` тощо
* Zhipu: `glm-5.1`, `glm-5`, `glm-5-turbo`, `glm-4.7`, `glm-4.5v` тощо

Конкретні правила тарифікації дивіться на картці Pricing на сторінці послуг.

## Багатократні діалоги

Як і в v1, передайте `stateful: true`, щоб увімкнути збереження сесії, API поверне `id`; подальші запити просто передайте `id`, щоб продовжити діалог, без необхідності самостійно підтримувати історію повідомлень.

Перше запит:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "question": "Запам'ятай число: 42."
  }'
```

Повернене:

```json theme={null}
{
  "answer": "Добре, я вже запам'ятав 42. Що мені з ним зробити?",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

Друге запит, передайте той же `id`:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
    "question": "Яка цифра, яку я щойно попросив тебе запам'ятати?"
  }'
```

```json theme={null}
{
  "answer": "Цифра, яку ти попросив мене запам'ятати, це 42.",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

> `stateful` за замовчуванням є `true`, пропуск і явна передача `true` є еквівалентними. Якщо ви не хочете, щоб сервер зберігав цей раунд розмови, ви можете явно встановити `stateful: false`.

## Потокова відповідь

v2 підтримує два формати потокового обміну, вибираючи за заголовком `accept`:

| Сцена                               | `accept`                              | Форма даних                                           |
| ----------------------------------- | ------------------------------------- | ----------------------------------------------------- |
| Веб-фронт / EventSource             | `text/event-stream`                   | `data: {json}\n\n`, останній рядок `data: [DONE]\n\n` |
| Сервер / CLI / Node потокове розбор | `application/x-ndjson`                | Кожен рядок — один JSON об'єкт                        |
| Не потрібно потокове                | `application/json` (за замовчуванням) | Одноразове повернення `{answer, id}`                  |

### Приклад NDJSON

```python theme={null}
import json
import requests

url = "https://api.acedata.cloud/aichat2/conversations"

headers = {
    "accept": "application/x-ndjson",
    "authorization": "Bearer {token}",
    "content-type": "application/json",
}

payload = {
    "model": "gpt-5.4",
    "stateful": True,
    "question": "Представте Ханчжоу трьома реченнями.",
}

with requests.post(url, json=payload, headers=headers, stream=True) as resp:
    answer = ""
    for line in resp.iter_lines():
        if not line:
            continue
        event = json.loads(line)
        if event.get("type") == "text_delta":
            # Для сумісності з v1: інкрементальні фрагменти також надаються через поле delta_answer
            answer += event["content"]
            print(event["delta_answer"], end="", flush=True)
        elif event.get("type") == "done":
            print()
            print("використання =", event.get("usage"))
```

Кожен рядок NDJSON є структурованою подією, найпоширенішою є `text_delta`:

```json theme={null}
{"type":"text_delta","content":"Хан","delta_answer":"Хан","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"чжоу","delta_answer":"чжоу","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"є","delta_answer":"є","id":"f2f4b3e8-..."}
...
{"type":"done","conversation_id":"f2f4b3e8-...","usage":{"prompt_tokens":21,"completion_tokens":58,"total_tokens":79},"terminal_reason":"natural_stop"}
```

### Приклад SSE

На стороні браузера використання `EventSource` не підтримує налаштування тіла запиту, рекомендується використовувати `fetch` + ручне розділення за `\n\n`:

```javascript theme={null}
const resp = await fetch("https://api.acedata.cloud/aichat2/conversations", {
  method: "POST",
  headers: {
    accept: "text/event-stream",
    authorization: "Bearer {token}",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    model: "gpt-5.4",
    stateful: true,
    question: "Представте Ханчжоу трьома реченнями.",
  }),
});

const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const blocks = buffer.split("\n\n");
  buffer = blocks.pop() ?? "";
  for (const block of blocks) {
    const dataLine = block.split("\n").find((l) => l.startsWith("data: "));
    if (!dataLine) continue;
    const payload = dataLine.slice(6);
    if (payload === "[DONE]") return;
    const event = JSON.parse(payload);
    if (event.type === "text_delta") process.stdout.write(event.content);
  }
}
```

### Типи потокових подій

| `type`              | Значення                                                                                                                                                                                                                |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text_delta`        | Інкрементальні текстові фрагменти відповіді помічника. `content` є новим вмістом; для сумісності з v1, одна й та ж подія також містить `delta_answer` (дорівнює `content`) та `id`.                                     |
| `thinking`          | Процес мислення моделі (з'являється лише тоді, коли обрані моделі відкривають reasoning).                                                                                                                               |
| `tool_use`          | Модель вирішує викликати інструмент, подія містить `tool_id`, `tool_name`, `input`.                                                                                                                                     |
| `tool_result`       | Результат виконання інструменту, пов'язаний з попереднім `tool_use` через `tool_id`, `is_error` вказує, чи сталася помилка.                                                                                             |
| `card`              | Структурована картка, створена інструментом (наприклад, зображення, попередній перегляд посилання), підходить для безпосереднього рендерингу.                                                                           |
| `citation`          | Використовується для доповнення джерела URL відповідного фрагмента тексту.                                                                                                                                              |
| `ask_user_question` | Модель надсилає запит, коли їй потрібна додаткова інформація від користувача, розмова переходить у стан `awaiting_user_input`, деталі див. нижче [Відновлення призупиненої розмови](#відновлення-призупиненої-розмови). |
| `artifact`          | Незалежний продукт, створений моделлю (наприклад, блоки коду, документи), які можна зберегти або завантажити.                                                                                                           |
| `system_message`    | Системне повідомлення (не вміст користувача та помічника), використовується лише для підказок UI.                                                                                                                       |
| `compact`           | Подія, в якій внутрішній контекст був стиснутий, не потребує спеціальної обробки.                                                                                                                                       |
| `error`             | Помилка, що сталася в цьому раунді, `message` описує вміст помилки.                                                                                                                                                     |
| `done`              | Кінець потокової відповіді, містить `usage` (включаючи `prompt_tokens` / `completion_tokens` / `total_tokens`) та `terminal_reason`.                                                                                    |

Для клієнтів, які цікавляться лише остаточною відповіддю, об'єднання всіх `text_delta` `content` буде еквівалентним `answer` в режимі `application/json`.

## Багатомодальний вхід

Якщо вхід користувача містить зображення або файл, передайте `message` (масив) замість `question`. Кожен елемент масиву є блоком вмісту:

```json theme={null}
{
  "model": "gpt-5.4",
  "stateful": true,
  "message": [
    { "type": "text", "text": "Скільки котів на цьому зображенні?" },
    { "type": "image_url", "image_url": { "url": "https://cdn.acedata.cloud/cats.jpg" } }
  ]
}
```

Підтримувані типи блоків:

* `text` — звичайний текст, обов'язкове поле `text`.
* `image_url` — зображення, обов'язкове поле `image_url.url`.
* `file_url` — файл (PDF, CSV, TXT тощо), обов'язкове поле `file_url.url`.

### Взаємозв'язок з v1 `references`

Для сумісності зі старими клієнтами, v2 все ще розпізнає поле `references: ["https://...", ...]`:

* URL закінчення `jpg / jpeg / png / gif / bmp / webp / svg / heic / heif`, автоматично перетворюється на блок `image_url`;
* Інші розширення перетворюються на блок `file_url`;
* Якщо також надано `question`, то його слід розглядати як блок `text` попередньо.

Отже, якщо ви хочете мігрувати з v1, але не хочете змінювати тіло запиту, просто змініть шлях на `/aichat2/conversations`, оригінальне використання `references` працює як зазвичай.

Для більш детального контролю (наприклад, щоб розмістити кілька зображень між текстами або порядок був важливим) використовуйте масив `message`.

## Виклик інструментів та MCP

Основна перевага v2 полягає в тому, що модель може самостійно викликати інструменти для виконання багатоступеневих завдань, **це за замовчуванням увімкнено**, клієнту не потрібно робити жодних додаткових налаштувань у запиті. Звичайні сценарії:

* Користувач запитує «Допоможи мені знайти нові виставки в Шанхаї» → модель викликає вбудований веб-пошук → організовує результати у відповідь.
* Користувач запитує «Прочитай цей PDF, а потім напиши резюме» → модель викликає file\_read → пише резюме.
* Користувач вже авторизував Google Drive / GitHub / Notion тощо в [Connections](https://platform.acedata.cloud/connections) → модель може викликати відповідні інструменти MCP для читання та запису його даних.

У NDJSON / SSE потоці виклики інструментів представлені через події `tool_use` та `tool_result`, наприклад:

```json theme={null}
{"type":"tool_use","tool_id":"toolu_01ABCDEF","tool_name":"web_search","input":{"query":"Шанхай 2026 весняна виставка"},"id":"f2f4b3e8-..."}
{"type":"tool_result","tool_id":"toolu_01ABCDEF","output":"...","is_error":false,"id":"f2f4b3e8-..."}
{"type":"text_delta","content":"зараз","delta_answer":"зараз","id":"f2f4b3e8-..."}
{"type":"text_delta","content":"Шанхай","delta_answer":"Шанхай","id":"f2f4b3e8-..."}
...
```

Якщо ви не хочете відображати деталі виклику інструментів на фронтенді, просто ігноруйте події `tool_use` / `tool_result` / `card` / `citation`, модель виведе остаточний результат через `text_delta`.

`max_turns` може обмежити, скільки разів модель може самостійно викликати інструменти в цьому запиті, максимальний ліміт визначається платформою. Зменшивши його (наприклад, `max_turns: 1`), ви можете примусити одноразову відповідь, не дозволяючи жодних викликів інструментів.

## Асинхронне виконання та безлюдне авторизація

Якщо ваш виклик походить з вебхука сповіщень, CI/CD, систем моніторингу або інших фонових завдань, ви можете встановити `async: true`, щоб інтерфейс негайно повернув ID завдання, а фонова частина продовжила виконання:

```json theme={null}
{
  "model": "gpt-5.5",
  "async": true,
  "question": "Моя служба сповіщає, використайте особистий WeChat для сповіщення групи «AceDataCloud команда»……"
}
```

Приклад відповіді:

```json theme={null}
{
  "task_id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "conversation_id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "status": "queued"
}
```

Потім можна використовувати `action: retrieve` + `id` для запиту результату сесії; також можна надати `callback_url`, після завершення завдання платформа надішле `{ status, answer, usage, error }` на вашу адресу зворотного виклику. `callback_url` повинен використовувати `http` / `https`, і не може бути безпосередньо вказаним як `localhost` або приватна IP адреса.

Фонові завдання зазвичай не мають можливості натискати підтвердження. Якщо ви хочете, щоб деякі навички або MCP сервери виконували дії надсилання, публікації, запису тощо в безлюдному режимі, будь ласка, явно передайте список попередньої авторизації в тілі запиту:

```json theme={null}
{
  "model": "gpt-5.5",
  "async": true,
  "allowed_skills": ["acedatacloud/personal-wechat"],
  "allowed_mcp_servers": [],
  "question": "Моя служба сповіщає, використайте особистий WeChat для сповіщення групи «AceDataCloud команда»……"
}
```

Значення в `allowed_skills` - це slug підключеної навички; значення в `allowed_mcp_servers` - це slug підключеного MCP сервера. Навички / MCP сервери, які не включені до попередньої авторизації, в безлюдному режимі можуть лише переглядати, виконувати dry-run або відмовлятися від виконання запису.

Якщо потрібен більш детальний контроль, також можна використовувати еквівалентний об'єкт `unattended_policy`:

```json theme={null}
{
  "unattended_policy": {
    "allowed_skills": ["acedatacloud/personal-wechat"],
    "allowed_mcp_servers": [],
    "expires_at": 1790000000
  }
}
```

Попередня авторизація - це ці два списки: порожній список означає, що жодні можливості не авторизовані, без необхідності додаткових перемикачів.

Зверніть увагу: попередня авторизація лише означає «цей запит дозволяє цим можливостям у безлюдному режимі пропустити ручне підтвердження». Конкретна навичка все ще повинна підтримувати `--unattended-confirm` або відповідний механізм безпеки; в іншому випадку вона продовжить dry-run, не виконуючи безпосередньо операцію запису.

## Відновлення призупиненої розмови

Деякі інструменти можуть змусити модель «запитати користувача», у цей момент модель видасть подію `ask_user_question`, розмова буде призупинена в стані `awaiting_user_input`:

```json theme={null}
{
  "type": "ask_user_question",
  "tool_id": "toolu_01XYZW",
  "tool_name": "ask_user_question",
  "question": "Якою мовою ви хочете, щоб звіт був: китайською чи англійською?",
  "options": ["китайською", "англійською"],
  "id": "f2f4b3e8-..."
}
```

На фронтенді відобразіть цю подію як картку, щоб користувач міг вибрати відповідь, а потім використовуйте той же `id`, щоб надіслати наступний запит, заповнивши відповідь через `tool_results`:

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: text/event-stream' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "gpt-5.4",
    "stateful": true,
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
    "tool_results": [
      {
        "tool_use_id": "toolu_01XYZW",
        "output": "китайською"
      }
    ]
  }'
```

У тілі запиту `tool_use_id` **повинен** повністю збігатися з `tool_id` під час призупинення; невідповідність призведе до помилки 400. Коли в запиті одночасно присутні `tool_results`, `question` / `message` / `references` будуть проігноровані.

Якщо користувач вирішить відмовитися від цього питання, просто передайте нове `question` / `message`, платформа автоматично позначить призупинений виклик інструменту як «пропущений користувачем».

## Управління сесією (CRUD)

v2 на тому ж кінцевому пункті пропонує легке управління сесією через поле `action`, без необхідності відкривати додатковий API.

### `action: retrieve` — отримати сесію

```shell theme={null}
curl -X POST 'https://api.acedata.cloud/aichat2/conversations' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "action": "retrieve",
    "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
  }'
```

Повертає повний документ розмови (включаючи історію `messages`, `model`, `title`, `tools_used` тощо).

### `action: retrieve_batch` —— Перелік підсумків розмов

```json theme={null}
{
  "action": "retrieve_batch",
  "model_group": "chatgpt",
  "limit": 20,
  "offset": 0
}
```

Повертає `{ items: [...], total }`. **Підсумок не містить `messages`**, підходить для списку в бічній панелі; якщо користувач відкриє певну розмову, то знову використовуйте `action: retrieve`, щоб окремо отримати її повні повідомлення.

Додаткові параметри фільтрації: `user_id`, `application_id`, `model_group`, `model`.

### `action: update` —— Змінити заголовок або переписати історію

```json theme={null}
{
  "action": "update",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44",
  "title": "План подорожі до Ханчжоу"
}
```

`messages` також можна передати, але сервер проведе сувору перевірку схеми (повинен бути у формі згорнутого `ToolUseContent`), невідповідність призведе до повернення 400. Зазвичай рекомендується використовувати лише для зміни `title`.

### `action: delete` —— Видалити розмову

```json theme={null}
{
  "action": "delete",
  "id": "f2f4b3e8-0c0a-4d3a-aaa2-7ff80c0a1c44"
}
```

Повертає `{ id, success: true }`. Після видалення відновити не можна, будь ласка, підтвердіть перед викликом.

## Плавний перехід з v1

Якщо ви вже використовуєте [`/aichat/conversations`](https://platform.acedata.cloud/documents/aichat-conversations), перехід на v2 майже не потребує змін у коді:

1. Змініть URL з `https://api.acedata.cloud/aichat/conversations` на `https://api.acedata.cloud/aichat2/conversations`.
2. Якщо ви раніше передавали назви моделей v1 (наприклад, `gpt-3.5`, `gpt-4-browsing` тощо), при переході на v2 рекомендується оновити до сучасних моделей (наприклад, `gpt-5.4`, `claude-opus-4-8`, `gemini-3.1-pro` тощо).
3. Поля потоку NDJSON залишаються зворотно сумісними: кожна подія `text_delta` все ще містить `delta_answer` та `id`, тому клієнти, які раніше аналізували `delta_answer` по рядках, не потребують змін.

Після переходу можна за потреби активувати нові можливості v2 (багатомодальні `message`, SSE, виклики інструментів, CRUD `action`), просуваючись у своєму темпі.

## Обробка помилок

Помилки відповіді єдині:

```json theme={null}
{
  "error": {
    "code": "chat_error",
    "message": "upstream LLM returned an error"
  },
  "trace_id": "2cf86e86-22a4-46e1-ac2f-032c0f2a4e89"
}
```

Поширені помилки:

* `400 bad_request`: відсутні обов'язкові поля, `tool_use_id` не відповідає, схема `messages` недійсна тощо.
* `401 invalid_token`: заголовок `authorization` неправильний.
* `404 not_found`: під час `action: retrieve / update / delete` розмова з відповідним `id` не існує.
* `429 too_many_requests`: спрацьовує обмеження швидкості.
* `500 chat_error`: помилка на стороні LLM або в цьому раунді `completion_tokens=0` (обробляється як не спожите, не буде стягнено плату).

У потокових відповідях помилки надсилаються як `{"type":"error","message":"..."}` подія, після чого потік закінчується.

## Висновок

AI Chat v2 API, зберігаючи зворотну сумісність з v1, оновлює розмови з «одинарного / багатократного запитання» до «агентного спостережуваного діалогу»: багатомодальний ввід, виклики інструментів, можливість призупинення / відновлення, структуровані події в потоці, вбудований CRUD. Рекомендується новим користувачам безпосередньо використовувати v2; вже інтегровані v1 можуть плавно перейти поетапно. Якщо у вас є будь-які питання, будь ласка, звертайтеся до нашої команди технічної підтримки.
