Диалоги
Методов в разделе: 5. Все методы
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 Страница диалогов.
Параметры
| Поле | Тип | Описание |
|---|
limit | integer необязательное | Где: query. Размер страницы: от 1 до 100, по умолчанию 25. |
cursor | string необязательное | Где: query. Значение next_cursor из предыдущего ответа. Живёт 24 часа; при смене фильтров начинайте заново. |
channel | string необязательное | Где: query. Тип канала: api, telegram, website … |
status | string необязательное | Где: query. Состояние диалога, например open. |
mode | string необязательное | Где: query. ai — ведёт ИИ, operator — ведёт человек. |
updated_after | string необязательное | Где: query. Диалоги, изменённые строго позже момента. ISO 8601 с поясом. |
include_deleted | boolean необязательное | Где: query. Принимается для единообразия; сейчас ничего не меняет. |
fields | string необязательное | Где: query. Через запятую — какие поля вернуть (id есть всегда). Без параметра возвращаются все поля, КРОМЕ полей с персональными данными; поле с персональными данными приходит, только если названо явно: верхнее (title, content) или вложенное (contact.email, score.reason). Неизвестное имя — 422. В журнал выдач попадают только выданные поля. |
Тело ответа
| Поле | Тип | Описание |
|---|
data | array<Conversation> обязательное | |
next_cursor | string обязательное, может быть 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-Key | string обязательное | Где: header. Уникальная строка (обычно UUID v4), новая для каждой новой операции. Повтор с тем же ключом и телом даёт тот же результат. |
Тело запроса Клиент вашего канала.
| Поле | Тип | Описание |
|---|
external_customer_id | string обязательное | Стабильный идентификатор клиента в вашей системе (не телефон и не почта). По нему платформа находит или заводит контакт и диалог; идентификаторы разных интеграций не смешиваются. |
name | string необязательное | Имя клиента. Пишется только в пустое поле контакта. |
email | string необязательное | Почта клиента. Пишется только в пустое поле контакта. |
phone | string необязательное | Телефон в международном формате (+…). Пишется только в пустое поле контакта. |
language | string необязательное | Язык нового диалога (ISO 639-1). Язык ответа ИИ ограничен языками ячейки. |
Тело ответа
| Поле | Тип | Описание |
|---|
id | string обязательное | Идентификатор диалога (uuid). |
channel | string обязательное, может быть null | Тип канала: api, telegram, website … |
contact_id | string обязательное, может быть null | Идентификатор контакта (клиента) на платформе. |
external_customer_id | string необязательное, может быть null | Идентификатор клиента в вашей системе. Только у канала api; у остальных каналов null (внешний идентификатор мессенджера не раскрывается). Персональные данные: в чтении приходит, только если названо в fields=. |
status | string обязательное | Состояние диалога: open, handoff_pending, resolved, closed … Набор значений может расширяться — не считайте список закрытым. |
mode | string обязательное | Кто ведёт диалог: ai — отвечает ИИ (режимы auto и supervised), operator — отвечает человек (copilot и manual). Значения: ai operator |
language | string обязательное, может быть null | Язык диалога (ISO 639-1); null — не определён. |
created_at | string обязательное, может быть null | Начало диалога, ISO 8601 UTC. |
updated_at | string обязательное | Последнее изменение или сообщение, 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 Диалог.
Параметры
| Поле | Тип | Описание |
|---|
id | string обязательное | Где: path. Идентификатор диалога (uuid). |
fields | string необязательное | Где: query. Через запятую — какие поля вернуть (id есть всегда). Без параметра возвращаются все поля, КРОМЕ полей с персональными данными; поле с персональными данными приходит, только если названо явно: верхнее (title, content) или вложенное (contact.email, score.reason). Неизвестное имя — 422. В журнал выдач попадают только выданные поля. |
Тело ответа
| Поле | Тип | Описание |
|---|
id | string обязательное | Идентификатор диалога (uuid). |
channel | string обязательное, может быть null | Тип канала: api, telegram, website … |
contact_id | string обязательное, может быть null | Идентификатор контакта (клиента) на платформе. |
external_customer_id | string необязательное, может быть null | Идентификатор клиента в вашей системе. Только у канала api; у остальных каналов null (внешний идентификатор мессенджера не раскрывается). Персональные данные: в чтении приходит, только если названо в fields=. |
status | string обязательное | Состояние диалога: open, handoff_pending, resolved, closed … Набор значений может расширяться — не считайте список закрытым. |
mode | string обязательное | Кто ведёт диалог: ai — отвечает ИИ (режимы auto и supervised), operator — отвечает человек (copilot и manual). Значения: ai operator |
language | string обязательное, может быть null | Язык диалога (ISO 639-1); null — не определён. |
created_at | string обязательное, может быть null | Начало диалога, ISO 8601 UTC. |
updated_at | string обязательное | Последнее изменение или сообщение, 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 Страница сообщений.
Параметры
| Поле | Тип | Описание |
|---|
id | string обязательное | Где: path. Идентификатор диалога (uuid). |
limit | integer необязательное | Где: query. Размер страницы: от 1 до 100, по умолчанию 25. |
cursor | string необязательное | Где: query. Значение next_cursor из предыдущего ответа. Живёт 24 часа; при смене фильтров начинайте заново. |
include_deleted | boolean необязательное | Где: query. true — вернуть и удалённые сообщения как «надгробия» (deleted: true, без текста). |
fields | string необязательное | Где: query. Через запятую — какие поля вернуть (id есть всегда). Без параметра возвращаются все поля, КРОМЕ полей с персональными данными; поле с персональными данными приходит, только если названо явно: верхнее (title, content) или вложенное (contact.email, score.reason). Неизвестное имя — 422. В журнал выдач попадают только выданные поля. |
Тело ответа
| Поле | Тип | Описание |
|---|
data | array<Message> обязательное | |
next_cursor | string обязательное, может быть 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).
Параметры
| Поле | Тип | Описание |
|---|
id | string обязательное | Где: path. Идентификатор диалога (uuid). |
Idempotency-Key | string обязательное | Где: header. Уникальная строка (обычно UUID v4), новая для каждой новой операции. Повтор с тем же ключом и телом даёт тот же результат. |
wait | integer необязательное | Где: query. Секунды ожидания ответа ИИ, 0–20. Не входит в ключ идемпотентности. |
Тело запроса Сообщение клиента.
| Поле | Тип | Описание |
|---|
content | string обязательное | Текст реплики клиента, до 4000 знаков. |
ai_reply | string обязательное | auto — запросить ответ ИИ-продажника (нужна область ai_seller:invoke; без неё сообщение только сохраняется); none — только сохранить сообщение. Значения: auto none |
Тело ответа
| Поле | Тип | Описание |
|---|
message_id | string обязательное | Идентификатор записанного сообщения клиента. |
conversation_id | string обязательное | Диалог. |
ai_reply | AiReply обязательное | |
reply | object необязательное | Только при replied: идентификатор ответа ИИ. Текста в ответе нет — прочитайте его GET /conversations/{id}/messages (выдача ПДн в журнале). |
reply.id | string обязательное | |
operation | Operation необязательное | Операция 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