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

# Chatturncompleted

> Ход чата по ключу API закончился, история записана. Только по факту хода, начатого ключом; ход из кабинета события не шлёт. Текста ответа и персональных данных в теле нет — ответ читайте по dialog_url. Ответ на вопрос ИИ (stop_reason был awaiting_user) — новое событие с тем же turn_no.

Подпись: заголовки webhook-id, webhook-timestamp, webhook-signature — Standard Webhooks. Проверка: 1) подписанная строка — «webhook-id.webhook-timestamp.тело», тело — байты запроса как пришли, до разбора JSON; 2) ключ — часть секрета после whsec_, раскодированная из base64; 3) HMAC-SHA256 от строки этим ключом, в base64; 4) в webhook-signature одна или несколько подписей через пробел, каждая вида «v1,base64» (при смене секрета сутки приходят две) — должна совпасть хотя бы одна, сравнивать постоянным по времени сравнением; 5) webhook-timestamp — секунды Unix; расхождение с вашими часами больше 5 минут — отклонить. Готовая проверка: new Webhook(secret).verify(rawBody, headers) из npm standardwebhooks.

Доставка: POST JSON на адрес. Успех — любой ответ 2xx за 30 секунд. Иначе — повторы через 5 с, 5 мин, 30 мин, 2 ч, 5 ч, 10 ч, 10 ч, 10 ч, 10 ч, 10 ч, 10 ч, 5 ч: всего 13 попыток, окно 72 ч 35 мин 5 с от первой до последней. После этого событие можно отправить снова вручную (POST …/webhooks/messages/{id}/resend). Адрес, который не принимает ничего 5 суток подряд, отключается (enabled: false) — включите его PATCH …/endpoints/{id} после починки. Доставка «хотя бы раз»: одно событие может прийти дважды — отбрасывайте повторы по id (evt_…), он у повтора тот же. Порядок не гарантируется: события могут прийти не в той последовательности, в какой случились, — сверяйте created_at и читайте актуальное состояние через API. В месячное число бесплатных событий тарифа считаются только события, которые есть кому получить (включённый адрес с подходящим фильтром); сверх него события не отправляются (не копятся и потом не досылаются): сколько не ушло — over_limit в GET …/webhooks/usage.



## OpenAPI

````yaml https://api.tungo.kz/v1/openapi.json webhook chat.turn.completed
openapi: 3.1.0
info:
  title: Tungo Platform API
  version: 0.1.0
  description: >-
    ## Быстрый старт


    От ключа до первого ответа и проверки подписи вебхука. Суммы — в тиынах (1 ₸
    = 100 тиын).


    ```sh

    export TUNGO_API=<адрес из раздела servers этого описания>

    export TUNGO_KEY=tg_…   # шаг 1

    export WS=ws_…          # шаг 2

    export CO=co_…          # шаг 2

    ```


    ### 1. Получить ключ


    Ключ выпускает владелец или админ организации, войдя в кабинет: POST
    /v1/workspaces/{ws}/api-keys. По ключу этот адрес не работает. В теле —
    `name`, `company_ids` и `permissions`. Для примеров ниже нужны права
    `chat.use` и `webhooks.manage`; второе — только у ключа на все компании
    организации. Ключ целиком (`key`) показывается один раз. Держите его на
    своём сервере: из браузера API не вызывается.


    ### 2. Проверить ключ и узнать id


    ```sh

    curl "$TUNGO_API/v1/api-key" -H "x-api-key: $TUNGO_KEY"

    curl "$TUNGO_API/v1/companies" -H "x-api-key: $TUNGO_KEY"

    ```


    Id организации — `workspace` → `id` в первом ответе; id компаний — `data` →
    `id` во втором. Вместо `x-api-key` можно передать `Authorization: Bearer
    tg_…`.


    ### 3. Проверить баланс и цены


    У платформы свой баланс, отдельно от подписки чата.


    ```sh

    curl "$TUNGO_API/v1/workspaces/$WS/platform/account" -H "x-api-key:
    $TUNGO_KEY"

    curl "$TUNGO_API/v1/usage-rates"

    ```


    Первый ответ — `balance_tiyn`; пополняет владелец или админ из кабинета:
    POST /v1/workspaces/{ws}/platform/purchases, по ключу нельзя. Цены открыты
    без ключа: `input_per_mtok_tiyn` и `output_per_mtok_tiyn` — за 1 млн токенов
    каждой модели. Пустой баланс — 402 с кодом `platform_balance_exhausted`.


    ### 4. Прикинуть цену вопроса


    Бесплатно: модель не отвечает, с баланса ничего не списывается.


    ```sh

    curl -X POST "$TUNGO_API/v1/companies/$CO/chat/count-tokens" -H "x-api-key:
    $TUNGO_KEY" -H "Content-Type: application/json" -d '{"message":"Какой НДС у
    последней реализации?"}'

    ```


    В ответе — `input_tokens`, `max_output_tokens`, `input_cost_tiyn` и
    `max_cost_tiyn` (это один вызов модели; ход может сделать их несколько,
    настоящая цена — по факту).


    ### 5. Задать первый вопрос


    ```sh

    curl -X POST "$TUNGO_API/v1/companies/$CO/chat" -H "x-api-key: $TUNGO_KEY"
    -H "Content-Type: application/json" -H "Idempotency-Key: first-question-1"
    -d '{"message":"Какой НДС у последней реализации?","stream":false}'

    ```


    В ответе — `answer`, `dialog_id` (пришлите его в следующем вопросе, чтобы
    продолжить разговор) и `usage` с токенами и ценой. Если `stream` не false,
    ответ приходит потоком событий. Компании нужно подключение к 1С: без него —
    409. Не оплачено подключение компании — 402 с кодом `onboarding_unpaid`.
    Потерялся ответ — повторите запрос с тем же `Idempotency-Key`: второго хода
    не будет.


    ### 6. Получать события и проверять подпись


    ```sh

    curl -X POST "$TUNGO_API/v1/workspaces/$WS/webhooks/endpoints" -H
    "x-api-key: $TUNGO_KEY" -H "Content-Type: application/json" -d
    '{"url":"https://example.kz/tungo-events","event_types":["proposal.written"]}'

    ```


    В ответе — `id` адреса и `secret` (whsec_…): по ключу прочитать его больше
    негде. Вебхуков нет в тарифе — 403 с кодом `webhooks_not_in_plan`. Пробное
    событие: POST /v1/workspaces/{ws}/webhooks/endpoints/{id}/test. Заголовки
    `webhook-id`, `webhook-timestamp` и `webhook-signature` проверяются так:


    ```js

    import { createHmac, timingSafeEqual } from 'node:crypto'


    // secret — whsec_…; headers — заголовки запроса; rawBody — тело строкой,
    как пришло, до разбора JSON.

    function verifyWebhook(secret, headers, rawBody, nowSec = Date.now() / 1000)
    {
      const id = headers['webhook-id']
      const ts = headers['webhook-timestamp']
      if (Math.abs(nowSec - Number(ts)) > 300) return false // старше 5 минут: повтор чужого запроса
      const key = Buffer.from(secret.slice('whsec_'.length), 'base64')
      const want = createHmac('sha256', key).update(`${id}.${ts}.${rawBody}`).digest()
      // В заголовке подписи через пробел: v1,<base64>. После смены секрета их две.
      return headers['webhook-signature'].split(' ').some((s) => {
        const got = Buffer.from(s.split(',')[1] ?? '', 'base64')
        return got.length === want.length && timingSafeEqual(got, want)
      })
    }

    ```


    Подпись не сошлась — отвечайте 400 и ничего не делайте. Одно событие может
    прийти дважды: отбрасывайте повторы по `id` тела.


    ---



    API для разработчиков: ключи, вебхуки, автоматизации, ИИ-бухгалтер компаний
    ключа. Вход — ключом API workspace (`x-api-key: tg_…` / `Authorization:
    Bearer tg_…`); управление самими ключами и вебхуками — ещё и сессией в
    браузере. Без того и другого — 401 с code missing_credentials.


    По ключу доступны (x-api-key-access у каждой операции): ручки ИИ-бухгалтера
    компаний ключа, чтение их карточек, автоматизации (automations.read /
    automations.manage), состояние подключения 1С (GET …/onec/status), вебхуки
    организации ключа (webhooks.manage, ключ на все компании), её баланс, расход
    и журнал платформы (GET /v1/workspaces/{ws}/platform/account, …/ledger,
    …/usage, …/audit), цены моделей (GET /v1/usage-rates), а также сам ключ о
    себе: GET /v1/api-key, GET /v1/api-key/usage, GET /v1/workspaces, GET
    /v1/companies.


    Id в адресах — публичные (ws_…, co_…, key_…). Публичные id организаций даёт
    GET /v1/workspaces.


    Деньги и лимиты: отказ из-за денег — 402 payment_required_error с error.code
    (platform_balance_exhausted, platform_cap_reached, platform_disabled,
    key_cap_reached, onboarding_unpaid): ждать бесполезно, нужно действие
    владельца организации. Вызовы по ключу идут мимо окон тарифа; лимит окна —
    только при входе сессией: 429 limit_error, code plan_limit_reached, с
    error.resets_at и Retry-After. Частота запросов по ключу — 429, code
    rate_limited, Retry-After; у каждого ответа по ключу — заголовки
    x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset (секунд до
    нового окна). Одновременных ходов ИИ на ключ — не больше настройки платформы
    (429 concurrent_turns_limit).


    Вызовы из браузера (CORS) не поддерживаются: ключ — секрет, держите его на
    сервере. Предварительный запрос OPTIONS к /v1 отвечает 403 с code
    cors_not_supported.


    Ошибки — одним видом:
    `{"type":"error","error":{"type":"…","message":"…"},"request_id":"…"}`;
    клиент ветвится по error.type.
servers:
  - url: https://api.tungo.kz
    description: Адрес API Tungo
security: []
paths: {}

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.