Обзор API
Каждый REST-эндпоинт RolChat следует одному контракту: тот же базовый URL, тот же конверт ответа, та же пагинация, та же форма ошибок. Разберитесь в нём один раз, и любое семейство эндпоинтов из справочника эндпоинтов будет читаться одинаково.
Базовый URL и версионирование
Заголовок раздела «Базовый URL и версионирование»https://api.rolchat.com/api/v1/Версия указывается в пути. Добавление необязательных полей, новых эндпоинтов или новых параметров запроса со значениями по умолчанию не считается несовместимым изменением и не меняет версию. Несовместимые изменения выходят как v2, а устаревшие эндпоинты v1 продолжают работать не менее шести месяцев после объявления (см. Вывод из эксплуатации).
Аутентификация
Заголовок раздела «Аутентификация»| Метод | Заголовок | Для чего |
|---|---|---|
| JWT bearer | Authorization: Bearer <access_token> |
Интерактивные сессии (веб-приложение, мобильные приложения) |
| API-ключ | Authorization: Bearer rcp_<secret> |
Вызовы между системами, API-ключи плагинов |
| Подпись HMAC | X-RolChat-Signature: sha256=… |
Входящие вебхуки из ваших систем, см. Вебхуки |
| Нет | - | Публичные эндпоинты виджета (/widget/…, /forms/…), ограниченные сайтом и источником |
Для интеграций используйте API-ключ (персональный токен доступа). Ключи создаются в разделе Настройки → Плагины → API-ключи RolChat, показываются один раз и хранятся только в виде хеша. Ключ никогда не может сделать больше, чем создавший его участник: его области доступа сверяются с текущими разрешениями этого участника при каждом вызове. Срок жизни JWT, заголовок X-Account-Id и сессии в нескольких компаниях описаны на странице Аутентификация.
Конверт ответа
Заголовок раздела «Конверт ответа»Один ресурс:
{ "data": { "id": "cnt_01HK…", "email": "ada@example.com" }, "meta": { "request_id": "req_01HK…" }}Список:
{ "data": [ { … }, { … } ], "meta": { "request_id": "req_01HK…", "count": 50, "next_cursor": "cur_01HK…", "prev_cursor": "cur_01HK…", "has_more": true }}Ответы без тела (204 No Content после удаления) всё равно содержат заголовок X-Request-Id.
Ошибка:
{ "errors": [ { "code": "validation_failed", "message": "Email must be valid.", "field": "email", "details": { "received": "not-an-email" } } ], "meta": { "request_id": "req_01HK…" }}code - машиночитаемое значение в snake_case, именно по нему стоит ветвить логику; message написан по-английски и предназначен для логов. field и details присутствуют, когда они полезны, и никогда не содержат персональных данных. API никогда не отвечает 200 с массивом errors: если есть ошибки, статус 400 или выше. Полный список кодов - на странице Ошибки.
Пагинация
Заголовок раздела «Пагинация»Эндпоинты списков, которые могут расти, используют курсорную пагинацию. Запросите первую страницу без курсора, затем передавайте полученный next_cursor без изменений:
GET /api/v1/contacts?limit=50GET /api/v1/contacts?limit=50&cursor=eyJrIjoi…limitпо умолчанию равен 50, максимум 200; большие значения отклоняются с400 validation_failed.- Курсоры непрозрачны и истекают через 24 часа (
400 validation_failedсcode: cursor_expired). - Результаты согласованы со снимком, сделанным на первой странице: записи, удалённые между страницами, исчезают, а новые появляются, только когда вы начинаете заново без курсора.
- Для клиентов, которым так удобнее, также отправляется заголовок
Linkсrel="next"иrel="prev".
Идемпотентность
Заголовок раздела «Идемпотентность»Отправляйте заголовок Idempotency-Key (UUID или ULID, до 255 символов) с любым POST, PATCH или DELETE:
- Первый запрос с ключом выполняется, а его статус и тело сохраняются на 24 часа.
- Повтор с тем же ключом и тем же телом возвращает сохранённый ответ без повторных побочных эффектов.
- Повтор с тем же ключом, но другим телом отклоняется с
409 idempotency_key_conflict.
Используйте его для каждого вызова, который создаёт что-то с побочными эффектами: отправка сообщения, e-mail или SMS, звонок, всё, за что выставляется счёт. Запросы GET всегда идемпотентны и игнорируют этот заголовок.
Лимиты запросов
Заголовок раздела «Лимиты запросов»Лимиты считаются за минуту и привязаны к аккаунту, API-ключу или пользователю (по IP-адресу на маршрутах без входа). Предельные значения по умолчанию:
| Ведро | Лимит по умолчанию | В минуту |
|---|---|---|
| Запросы без входа (по IP) | 60 | на IP |
| Пользователь со входом (панель) | 1 000 | на пользователя |
| API-ключ | 1 000 | на ключ |
| Публичные эндпоинты виджета | 60 на посетителя и 600 на сетевой адрес | в минуту |
Вход (/auth/login) |
5 | на IP |
| Входящие вебхуки | 300 | в минуту |
| MCP-сервер | 600 | в минуту |
| Эндпоинты OAuth | 600 | в минуту |
Это значения платформы по умолчанию, оператор может их изменить; тариф их не умножает, а лимиты Enterprise согласовываются в договоре. Эндпоинты с лимитами возвращают:
X-RateLimit-Limit: 1000X-RateLimit-Remaining: 543При превышении лимита ответ - 429 с code: rate_limited в массиве errors и заголовком Retry-After в секундах. Подождите это время перед следующим вызовом. Десять неудачных попыток входа блокируют аккаунт на 30 минут.
Размеры и тайм-ауты
Заголовок раздела «Размеры и тайм-ауты»| Категория | Макс. тело запроса | Тайм-аут сервера |
|---|---|---|
| По умолчанию | 1 MB | 30 s |
| Сообщение с вложениями | 25 MB | 30 s |
| Импорт CSV | 50 MB | возвращает 202 и выполняется в фоне |
| Изображения базы знаний | 10 MB | 30 s |
| Bulk API | 10 MB | 30 s |
| Поиск | 1 MB | 10 s |
| Запросы к ИИ | 1 MB | 60 s |
| Эндпоинты виджета | 100 KB | 30 s |
Слишком большие тела получают 413 payload_too_large. Если вышестоящий сервис не ответил вовремя, возвращается 504 с code: upstream_timeout и подсказкой retry_after, когда повтор может помочь.
Типы содержимого, даты и идентификаторы
Заголовок раздела «Типы содержимого, даты и идентификаторы»- Запросы и ответы -
application/json; charset=utf-8. Загрузка файлов используетmultipart/form-data; экспорт CSV возвращаетtext/csv. Некорректный UTF-8 отклоняется с400 validation_failed. - Метки времени - ISO-8601 в UTC с точностью до миллисекунд:
2026-04-20T14:23:45.123Z. На входе принимается любое смещение ISO-8601, оно приводится к UTC. - Идентификаторы - непрозрачные ULID или UUID. Числовых ID нет, а адреса e-mail и номера телефонов никогда не появляются в URL.
Изоляция клиентов и разрешения
Заголовок раздела «Изоляция клиентов и разрешения»Каждый аутентифицированный запрос выполняется в рамках одного аккаунта. Ресурс, принадлежащий другому аккаунту или сайту, на который не распространяется роль вызывающего, возвращает 404 not_found, а не 403, чтобы само существование записей никогда не раскрывалось. Действительный токен без нужного разрешения (например, contacts.delete) получает 403 forbidden. Некоторые разрешения имеют суффикс области (conversations.read:own, :team, :all), который сужает то, что возвращает список.
PATCH принимает только изменяемые поля. id, account_id, created_at, updated_at и поля состояния, такие как resolved_at, доступны только для чтения; их отправка возвращает 400 validation_failed с details.forbidden_fields. Смена состояния выполняется через отдельные действия, например POST /tickets/:id/resolve.
Каждая запись фиксируется в журнале аудита аккаунта.
Заголовки наблюдаемости
Заголовок раздела «Заголовки наблюдаемости»Каждый ответ содержит:
X-Request-Id: req_01HK…Записывайте X-Request-Id в лог. Это первое, о чём спросит поддержка.
Источник браузерной панели управления - https://app.rolchat.com. Публичные эндпоинты виджета разрешают любой источник или только источники, подтверждённые для сайта. Вызовы между серверами с API-ключом не подпадают под CORS.
Вывод из эксплуатации
Заголовок раздела «Вывод из эксплуатации»- Изменение объявляется в журнале изменений, и затронутый эндпоинт начинает отправлять
Deprecation: trueи заголовокSunsetс датой удаления. - Публичные эндпоинты продолжают работать не менее шести месяцев после объявления.
- Удаление происходит только в новой мажорной версии. Внутри
v1изменения только добавляются.
Состояние сервисов
Заголовок раздела «Состояние сервисов»Каждый сервис предоставляет /healthz (живость) и /readyz (готовность).