Формула ИИ для разработчиков Справочник API Каталог ошибок OpenAPI
Разделы

Диалоги

Методов в разделе: 5. Все методы

МетодПутьОписаниеОбластиСтатус
GET/conversationsСписок диалоговconversations:readДоступно ПДн
POST/conversationsНайти или завести диалогconversations:writeДоступно ПДн
GET/conversations/{id}Получить диалогconversations:readДоступно ПДн
GET/conversations/{id}/messagesСообщения диалогаconversations:readДоступно ПДн
POST/conversations/{id}/messagesСообщение клиента и ответ ИИconversations:writeДоступно ПДн
GET /conversations Доступно ПДн

#Список диалогов

Диалоги арендатора по возрастанию updated_at, постранично по курсору: чтобы забрать изменения, храните updated_at последнего увиденного и передавайте его в updated_after. Диалогов с мягким удалением нет, поэтому include_deleted сейчас ничего не добавляет. Ответ содержит персональные данные клиентов: каждая выдача записывается в журнал выдач, на RU нужны список разрешённых IP и страна получателя RU (иначе 403 pii_transfer_not_allowed). Диалоги личных ящиков и чаты кабинета ученика не отдаются. Поля с персональными данными (у диалога — external_customer_id, у сообщения — content и attachments) приходят, только если названы в fields=.

Области
conversations:read
Предел частоты
чтение
Идемпотентность
не требуется
Успешный ответ
200 Страница диалогов.

Параметры

ПолеТипОписание
limitinteger
необязательное
Где: query. Размер страницы: от 1 до 100, по умолчанию 25.
cursorstring
необязательное
Где: query. Значение next_cursor из предыдущего ответа. Живёт 24 часа; при смене фильтров начинайте заново.
channelstring
необязательное
Где: query. Тип канала: api, telegram, website …
statusstring
необязательное
Где: query. Состояние диалога, например open.
modestring
необязательное
Где: query. ai — ведёт ИИ, operator — ведёт человек.
updated_afterstring
необязательное
Где: query. Диалоги, изменённые строго позже момента. ISO 8601 с поясом.
include_deletedboolean
необязательное
Где: query. Принимается для единообразия; сейчас ничего не меняет.
fieldsstring
необязательное
Где: query. Через запятую — какие поля вернуть (id есть всегда). Без параметра возвращаются все поля, КРОМЕ полей с персональными данными; поле с персональными данными приходит, только если названо явно: верхнее (title, content) или вложенное (contact.email, score.reason). Неизвестное имя — 422. В журнал выдач попадают только выданные поля.

Тело ответа

ПолеТипОписание
dataarray<Conversation>
обязательное
next_cursorstring
обязательное, может быть null
Курсор следующей страницы; null — список закончился. Живёт 24 часа.

Примеры

Запрос
curl -X GET 'https://formula-cream.pro/api/public/v1/conversations' \
  -H 'Authorization: Bearer '"$API_KEY"
Ответ 200
{
  "data": [
    {
      "id": "EXAMPLE_ID",
      "channel": null,
      "contact_id": null,
      "external_customer_id": null,
      "status": "string",
      "mode": "ai",
      "language": null,
      "created_at": null,
      "updated_at": "2026-10-11T09:00:00Z"
    }
  ],
  "next_cursor": "EXAMPLE_CURSOR"
}
Пример ошибки
{
  "type": "https://formula-cream.pro/developers/errors#scope_missing",
  "title": "Scope is missing",
  "status": 403,
  "code": "scope_missing",
  "detail": "EXAMPLE",
  "request_id": "req_EXAMPLE"
}

Примеры иллюстративны: ключ в них условный (EXAMPLE), значения полей выдуманы.

Возможные ошибки

invalid_api_key wrong_cell integration_inactive tenant_inactive ip_not_allowed feature_not_in_plan rate_limited wallet_suspended service_unavailable internal_error scope_missing pii_transfer_not_allowed validation_failed encryption_key_required

POST /conversations Доступно ПДн

#Найти или завести диалог

Диалог клиента вашего канала (канал api интеграции) по внешнему идентификатору: есть активный — он же (200), нет — новый (201) и событие conversation.created. Один и тот же external_customer_id двух разных интеграций — разные клиенты. Имя, почта и телефон пишутся только в пустые поля контакта. Канал подключается в кабинете (Настройки → API); без него — 409 channel_not_configured. Повтор с тем же Idempotency-Key — тот же диалог. Ответ содержит персональные данные клиентов: каждая выдача записывается в журнал выдач, на RU нужны список разрешённых IP и страна получателя RU (иначе 403 pii_transfer_not_allowed). Диалоги личных ящиков и чаты кабинета ученика не отдаются.

Области
conversations:write
Предел частоты
запись
Идемпотентность
обязателен Idempotency-Key
Успешный ответ
201 Диалог (новый — 201, найденный — 200).

Параметры

ПолеТипОписание
Idempotency-Keystring
обязательное
Где: header. Уникальная строка (обычно UUID v4), новая для каждой новой операции. Повтор с тем же ключом и телом даёт тот же результат.

Тело запроса Клиент вашего канала.

ПолеТипОписание
external_customer_idstring
обязательное
Стабильный идентификатор клиента в вашей системе (не телефон и не почта). По нему платформа находит или заводит контакт и диалог; идентификаторы разных интеграций не смешиваются.
namestring
необязательное
Имя клиента. Пишется только в пустое поле контакта.
emailstring
необязательное
Почта клиента. Пишется только в пустое поле контакта.
phonestring
необязательное
Телефон в международном формате (+…). Пишется только в пустое поле контакта.
languagestring
необязательное
Язык нового диалога (ISO 639-1). Язык ответа ИИ ограничен языками ячейки.

Тело ответа

ПолеТипОписание
idstring
обязательное
Идентификатор диалога (uuid).
channelstring
обязательное, может быть null
Тип канала: api, telegram, website …
contact_idstring
обязательное, может быть null
Идентификатор контакта (клиента) на платформе.
external_customer_idstring
необязательное, может быть null
Идентификатор клиента в вашей системе. Только у канала api; у остальных каналов null (внешний идентификатор мессенджера не раскрывается). Персональные данные: в чтении приходит, только если названо в fields=.
statusstring
обязательное
Состояние диалога: open, handoff_pending, resolved, closed … Набор значений может расширяться — не считайте список закрытым.
modestring
обязательное
Кто ведёт диалог: ai — отвечает ИИ (режимы auto и supervised), operator — отвечает человек (copilot и manual).
Значения: ai operator
languagestring
обязательное, может быть null
Язык диалога (ISO 639-1); null — не определён.
created_atstring
обязательное, может быть null
Начало диалога, ISO 8601 UTC.
updated_atstring
обязательное
Последнее изменение или сообщение, ISO 8601 UTC. По нему идёт обход. Счётчик непрочитанного его не меняет.

Примеры

Запрос
curl -X POST 'https://formula-cream.pro/api/public/v1/conversations' \
  -H 'Authorization: Bearer '"$API_KEY" \
  -H 'Idempotency-Key: '"$(uuidgen)" \
  -H 'Content-Type: application/json' \
  -d '{
  "external_customer_id": "EXAMPLE_ID",
  "name": "string",
  "email": "user@example.com",
  "phone": "string",
  "language": "string"
}'
Ответ 201
{
  "id": "EXAMPLE_ID",
  "channel": "string",
  "contact_id": "EXAMPLE_ID",
  "external_customer_id": "EXAMPLE_ID",
  "status": "string",
  "mode": "ai",
  "language": "string",
  "created_at": "2026-10-11T09:00:00Z",
  "updated_at": "2026-10-11T09:00:00Z"
}
Пример ошибки
{
  "type": "https://formula-cream.pro/developers/errors#scope_missing",
  "title": "Scope is missing",
  "status": 403,
  "code": "scope_missing",
  "detail": "EXAMPLE",
  "request_id": "req_EXAMPLE"
}

Примеры иллюстративны: ключ в них условный (EXAMPLE), значения полей выдуманы.

Возможные ошибки

invalid_api_key wrong_cell integration_inactive tenant_inactive ip_not_allowed feature_not_in_plan rate_limited wallet_suspended service_unavailable internal_error scope_missing pii_transfer_not_allowed validation_failed bad_request payload_too_large channel_not_configured idempotency_key_required idempotency_conflict operation_in_progress invalid_state

GET /conversations/{id} Доступно ПДн

#Получить диалог

Один диалог. Чужой, несуществующий и недоступный публичному API диалог одинаково отвечает not_found. Ответ содержит персональные данные клиентов: каждая выдача записывается в журнал выдач, на RU нужны список разрешённых IP и страна получателя RU (иначе 403 pii_transfer_not_allowed). Диалоги личных ящиков и чаты кабинета ученика не отдаются. Поля с персональными данными (у диалога — external_customer_id, у сообщения — content и attachments) приходят, только если названы в fields=.

Области
conversations:read
Предел частоты
чтение
Идемпотентность
не требуется
Успешный ответ
200 Диалог.

Параметры

ПолеТипОписание
idstring
обязательное
Где: path. Идентификатор диалога (uuid).
fieldsstring
необязательное
Где: query. Через запятую — какие поля вернуть (id есть всегда). Без параметра возвращаются все поля, КРОМЕ полей с персональными данными; поле с персональными данными приходит, только если названо явно: верхнее (title, content) или вложенное (contact.email, score.reason). Неизвестное имя — 422. В журнал выдач попадают только выданные поля.

Тело ответа

ПолеТипОписание
idstring
обязательное
Идентификатор диалога (uuid).
channelstring
обязательное, может быть null
Тип канала: api, telegram, website …
contact_idstring
обязательное, может быть null
Идентификатор контакта (клиента) на платформе.
external_customer_idstring
необязательное, может быть null
Идентификатор клиента в вашей системе. Только у канала api; у остальных каналов null (внешний идентификатор мессенджера не раскрывается). Персональные данные: в чтении приходит, только если названо в fields=.
statusstring
обязательное
Состояние диалога: open, handoff_pending, resolved, closed … Набор значений может расширяться — не считайте список закрытым.
modestring
обязательное
Кто ведёт диалог: ai — отвечает ИИ (режимы auto и supervised), operator — отвечает человек (copilot и manual).
Значения: ai operator
languagestring
обязательное, может быть null
Язык диалога (ISO 639-1); null — не определён.
created_atstring
обязательное, может быть null
Начало диалога, ISO 8601 UTC.
updated_atstring
обязательное
Последнее изменение или сообщение, ISO 8601 UTC. По нему идёт обход. Счётчик непрочитанного его не меняет.

Примеры

Запрос
curl -X GET 'https://formula-cream.pro/api/public/v1/conversations/EXAMPLE_ID' \
  -H 'Authorization: Bearer '"$API_KEY"
Ответ 200
{
  "id": "EXAMPLE_ID",
  "channel": "string",
  "contact_id": "EXAMPLE_ID",
  "external_customer_id": "EXAMPLE_ID",
  "status": "string",
  "mode": "ai",
  "language": "string",
  "created_at": "2026-10-11T09:00:00Z",
  "updated_at": "2026-10-11T09:00:00Z"
}
Пример ошибки
{
  "type": "https://formula-cream.pro/developers/errors#scope_missing",
  "title": "Scope is missing",
  "status": 403,
  "code": "scope_missing",
  "detail": "EXAMPLE",
  "request_id": "req_EXAMPLE"
}

Примеры иллюстративны: ключ в них условный (EXAMPLE), значения полей выдуманы.

Возможные ошибки

invalid_api_key wrong_cell integration_inactive tenant_inactive ip_not_allowed feature_not_in_plan rate_limited wallet_suspended service_unavailable internal_error scope_missing pii_transfer_not_allowed not_found validation_failed encryption_key_required

GET /conversations/{id}/messages Доступно ПДн

#Сообщения диалога

Сообщения диалога от старых к новым, постранично по курсору (created_at, id). Внутренние заметки операторов не отдаются. Вложения — временные подписанные ссылки; внешние адреса файлов мессенджеров не раскрываются. Ответ содержит персональные данные клиентов: каждая выдача записывается в журнал выдач, на RU нужны список разрешённых IP и страна получателя RU (иначе 403 pii_transfer_not_allowed). Диалоги личных ящиков и чаты кабинета ученика не отдаются. Поля с персональными данными (у диалога — external_customer_id, у сообщения — content и attachments) приходят, только если названы в fields=.

Области
conversations:read
Предел частоты
чтение
Идемпотентность
не требуется
Успешный ответ
200 Страница сообщений.

Параметры

ПолеТипОписание
idstring
обязательное
Где: path. Идентификатор диалога (uuid).
limitinteger
необязательное
Где: query. Размер страницы: от 1 до 100, по умолчанию 25.
cursorstring
необязательное
Где: query. Значение next_cursor из предыдущего ответа. Живёт 24 часа; при смене фильтров начинайте заново.
include_deletedboolean
необязательное
Где: query. true — вернуть и удалённые сообщения как «надгробия» (deleted: true, без текста).
fieldsstring
необязательное
Где: query. Через запятую — какие поля вернуть (id есть всегда). Без параметра возвращаются все поля, КРОМЕ полей с персональными данными; поле с персональными данными приходит, только если названо явно: верхнее (title, content) или вложенное (contact.email, score.reason). Неизвестное имя — 422. В журнал выдач попадают только выданные поля.

Тело ответа

ПолеТипОписание
dataarray<Message>
обязательное
next_cursorstring
обязательное, может быть null
Курсор следующей страницы; null — список закончился. Живёт 24 часа.

Примеры

Запрос
curl -X GET 'https://formula-cream.pro/api/public/v1/conversations/EXAMPLE_ID/messages' \
  -H 'Authorization: Bearer '"$API_KEY"
Ответ 200
{
  "data": [
    {
      "id": "EXAMPLE_ID",
      "conversation_id": "EXAMPLE_ID",
      "sender": "customer",
      "content_type": "string",
      "content": null,
      "attachments": [
        null
      ],
      "cards": [
        null
      ],
      "deleted": false,
      "created_at": "2026-10-11T09:00:00Z"
    }
  ],
  "next_cursor": "EXAMPLE_CURSOR"
}
Пример ошибки
{
  "type": "https://formula-cream.pro/developers/errors#scope_missing",
  "title": "Scope is missing",
  "status": 403,
  "code": "scope_missing",
  "detail": "EXAMPLE",
  "request_id": "req_EXAMPLE"
}

Примеры иллюстративны: ключ в них условный (EXAMPLE), значения полей выдуманы.

Возможные ошибки

invalid_api_key wrong_cell integration_inactive tenant_inactive ip_not_allowed feature_not_in_plan rate_limited wallet_suspended service_unavailable internal_error scope_missing pii_transfer_not_allowed not_found validation_failed encryption_key_required

POST /conversations/{id}/messages Доступно ПДн

#Сообщение клиента и ответ ИИ

Записывает сообщение клиента в диалог канала интеграции (conversations:write) и, при ai_reply=auto и области ai_seller:invoke, запускает ответ ИИ-продажника асинхронно: 202 с message_id, ai_reply.status=queued и операцией conversation.ai_reply. ?wait=N (0–20 с) ждёт ТО ЖЕ задание: успело — 200 с итогом (ai_reply, reply.id, operation.usage.cost в валюте кошелька), нет — 202. Без ai_seller:invoke или с ai_reply=none — 201, ai_reply.status=skipped, reason=not_requested, ИИ не вызывается и ничего не списывается. Текста ответа ИИ здесь нет — читайте GET /conversations/{id}/messages или ждите message.created. Повтор того же Idempotency-Key во время выполнения — тот же 202, после — итог; повторно сообщение не пишется и не оплачивается. Платная часть: не больше 5 одновременных операций на интеграцию (429 concurrency_limit), максимум стоимости одной операции и суточный предел интеграции (402 spend_limit_reached) — проверяются до записи, отказ ничего не записывает и освобождает Idempotency-Key. Диалог другого канала или арендатора — 404, закрытый — 409 invalid_state.

Области
conversations:write
Предел частоты
запись
Идемпотентность
обязателен Idempotency-Key
Успешный ответ
202 Принято; ответ ИИ готовится (202), готов в пределах wait (200) или не запрашивался (201).

Параметры

ПолеТипОписание
idstring
обязательное
Где: path. Идентификатор диалога (uuid).
Idempotency-Keystring
обязательное
Где: header. Уникальная строка (обычно UUID v4), новая для каждой новой операции. Повтор с тем же ключом и телом даёт тот же результат.
waitinteger
необязательное
Где: query. Секунды ожидания ответа ИИ, 0–20. Не входит в ключ идемпотентности.

Тело запроса Сообщение клиента.

ПолеТипОписание
contentstring
обязательное
Текст реплики клиента, до 4000 знаков.
ai_replystring
обязательное
auto — запросить ответ ИИ-продажника (нужна область ai_seller:invoke; без неё сообщение только сохраняется); none — только сохранить сообщение.
Значения: auto none

Тело ответа

ПолеТипОписание
message_idstring
обязательное
Идентификатор записанного сообщения клиента.
conversation_idstring
обязательное
Диалог.
ai_replyAiReply
обязательное
replyobject
необязательное
Только при replied: идентификатор ответа ИИ. Текста в ответе нет — прочитайте его GET /conversations/{id}/messages (выдача ПДн в журнале).
reply.idstring
обязательное
operationOperation
необязательное
Операция conversation.ai_reply: при 202 — queued или running, при 200 — завершена (usage.cost — списано с кошелька в его валюте). Нет, если ответ ИИ не запрашивался.

Примеры

Запрос
curl -X POST 'https://formula-cream.pro/api/public/v1/conversations/EXAMPLE_ID/messages' \
  -H 'Authorization: Bearer '"$API_KEY" \
  -H 'Idempotency-Key: '"$(uuidgen)" \
  -H 'Content-Type: application/json' \
  -d '{
  "content": "string",
  "ai_reply": "auto"
}'
Ответ 202
{
  "message_id": "EXAMPLE_ID",
  "conversation_id": "EXAMPLE_ID",
  "ai_reply": {
    "status": "replied",
    "reason": "operator_active"
  },
  "reply": {
    "id": "EXAMPLE_ID"
  },
  "operation": {
    "id": "EXAMPLE_ID",
    "type": "string",
    "status": "queued",
    "created_at": "2026-10-11T09:00:00Z",
    "completed_at": "2026-10-11T09:00:00Z",
    "resource": {
      "type": "string",
      "id": "EXAMPLE_ID"
    },
    "error": {
      "code": "string",
      "message": "string"
    },
    "usage": {
      "cost": null,
      "model": null
    }
  }
}
Пример ошибки
{
  "type": "https://formula-cream.pro/developers/errors#scope_missing",
  "title": "Scope is missing",
  "status": 403,
  "code": "scope_missing",
  "detail": "EXAMPLE",
  "request_id": "req_EXAMPLE"
}

Примеры иллюстративны: ключ в них условный (EXAMPLE), значения полей выдуманы.

Возможные ошибки

invalid_api_key wrong_cell integration_inactive tenant_inactive ip_not_allowed feature_not_in_plan rate_limited wallet_suspended service_unavailable internal_error scope_missing pii_transfer_not_allowed validation_failed bad_request payload_too_large not_found channel_not_configured invalid_state idempotency_key_required idempotency_conflict operation_in_progress concurrency_limit spend_limit_reached upstream_unavailable