Документация
API
Формат запросов, ответов и справочник полей для интеграций.
Записи
Запись — клиентский визит, связанный с событием календаря. Через API записей можно читать данные визита и сохранять его кастомные поля; создать запись или изменить время, клиента, услуги, персонал и ресурсы нужно через событие календаря.
Получение записи и кастомные поля
Список содержит неудалённые записи текущей организации и сортируется по времени начала, затем по id. Участник без права Events видит только записи, где он назначен сотрудником. Параметр custom_fields_full=true возвращает в списке все определения кастомных полей вместо полей с признаком показа в карточке.
| Метод | URL | Описание |
|---|---|---|
GET | /api/?mod=data&data=booking | Получить список клиентских записей вместе с определениями кастомных полей. |
GET | /api/?mod=data&data=booking&id=ID | Получить одну запись по id. Если запись недоступна, data будет пустым объектом. |
POST | /api/?mod=save_data&data=booking | Сохранить custom_fields существующей записи. id обязателен; обычные поля записи этот endpoint не изменяет. |
Поля записи
Каждое поле типа datetime дополнительно возвращается с суффиксами _iso_string и _timezone. Время приводится к часовому поясу организации. Те же три значения добавляются для booking_snapshot.start и booking_snapshot.end.
Верхнеуровневый custom_fields содержит определения полей, а data[].customFields или data.customFields — значения по uid. Публичный UID формы отзыва в этом API не возвращается.
| Поле | Тип | Описание |
|---|---|---|
id | number | Внутренний идентификатор материализованной записи. |
uid | string | Публичный UID записи. Это не UID формы обратной связи. |
event_id | number | Идентификатор связанного события календаря или правила серии. |
client_id | number | Идентификатор клиента в справочнике текущей организации. |
title | string | Название записи, синхронизированное со связанным событием. |
dt_start | datetime | Начало конкретного визита. |
dt_end | datetime | Окончание конкретного визита. |
client_comment | string|null | Неизменяемый снимок комментария клиента при самостоятельной записи. Внутренняя заметка события сюда не попадает. |
cancellation_comment | string|null | Причина отмены, если она была передана. |
availability | number | Режим доступности, скопированный из события. |
target_type | number | Тип связанного события календаря. |
status | string | Текущий бизнес-статус записи. Отмена устанавливает cancelled; состоявшийся визит определяется отдельно по visit_completed_at. |
series_sync_status | string | Техническое состояние записи относительно синхронизации регулярной серии. |
new_booking_notice_sent_at | datetime|null | Время фиксации уведомления о создании записи. |
client_confirmed_at | datetime|null | Время явного подтверждения записи клиентом. |
visit_completed_at | datetime|null | Время необратимой отметки «Визит состоялся». |
visit_completed_by_user_id | number | Идентификатор пользователя кабинета, отметившего визит; до завершения равен 0. |
cancelled_at | datetime|null | Дата и время отмены. |
cancelled_by_type | string | Тип инициатора отмены: user или client; до отмены — пустая строка. |
cancelled_by_id | number | Идентификатор пользователя кабинета или глобального клиента в зависимости от cancelled_by_type; до отмены равен 0. |
services_ids | array | Массив id основных услуг визита. |
additional_services_ids | array | Массив id дополнительных услуг. |
resource_requirements | array | Снимок требований к ресурсам в JSON. |
staff_ids | array | Массив id назначенных сотрудников. |
booking_snapshot | object|null | Витринный снимок организации, клиента, услуг, сотрудников, ресурсов, цены и локального времени на момент синхронизации записи. |
feedback_eligible | boolean | Признак существования состояния обратной связи для этой записи. |
feedback | object | Возвращается только при feedback_eligible=true. Безопасный объект содержит id, rating, comment, кабинетный срок account_expires_at, время submitted_at и boolean submitted. До отправки rating равен 0. |
customFields | object | Значения кастомных полей записи по uid. |
deletedData | object | Необязательные витринные данные удалённых связанных справочников и тегов, если они нужны для отображения старой записи. |
GET /api/?mod=data&data=booking&id=42
{
"ok": true,
"data": {
"id": 42,
"uid": "d8fd3975f8df4e849290606cd48b6f68",
"event_id": 18,
"client_id": 31,
"title": "Стрижка",
"dt_start": "2026-09-21 14:00:00",
"dt_start_iso_string": "2026-09-21T14:00:00+03:00",
"dt_start_timezone": "Europe/Moscow",
"dt_end": "2026-09-21 15:00:00",
"dt_end_iso_string": "2026-09-21T15:00:00+03:00",
"dt_end_timezone": "Europe/Moscow",
"status": "active",
"visit_completed_at": "2026-09-21 15:05:00",
"visit_completed_at_iso_string": "2026-09-21T15:05:00+03:00",
"visit_completed_at_timezone": "Europe/Moscow",
"feedback_eligible": true,
"feedback": {
"id": 9,
"rating": 5,
"comment": "Всё понравилось",
"account_expires_at": "2026-12-21 15:00:00",
"account_expires_at_iso_string": "2026-12-21T15:00:00+03:00",
"account_expires_at_timezone": "Europe/Moscow",
"submitted_at": "2026-09-21 16:12:00",
"submitted_at_iso_string": "2026-09-21T16:12:00+03:00",
"submitted_at_timezone": "Europe/Moscow",
"submitted": true
},
"customFields": {
"result": "Повторный визит через месяц"
}
},
"custom_fields": [
{
"id": 5,
"uid": "result",
"target": "bookings",
"name": "Результат визита",
"type": "textarea",
"required": false,
"show_in_card": true,
"show_to_clients": false
}
]
}POST /api/?mod=save_data&data=booking
{
"id": 42,
"custom_fields": {
"result": "Повторный визит через месяц"
}
}Действия с записью
Все действия выполняются методом POST. Параметр id можно передать в строке запроса или JSON-теле.
| Метод | URL | Описание |
|---|---|---|
POST | /api/?mod=bookings&action=cancel&id=ID | Отменить запись, сохранить её в истории и убрать связанное событие или вхождение из календаря. |
POST | /api/?mod=bookings&action=complete&id=ID | Необратимо отметить визит состоявшимся. При включённой обратной связи создаётся состояние будущего отзыва. |
POST | /api/?mod=bookings&action=delete&id=ID | Физически удалить запись и её кастомные поля. Запись исчезнет из раздела записей и календаря. |
Параметры действий
Для JSON-запроса передавайте параметры в теле. Значение cancellation_comment не используется действиями complete и delete.
| Поле | Тип | Обязательное | Действия | Описание |
|---|---|---|---|---|
id | number | Да | cancel, complete, delete | Идентификатор конкретной записи, включая конкретное материализованное вхождение регулярной серии. |
cancellation_comment | string | Нет | cancel | Необязательный комментарий к отмене. Пробелы и переводы строк по краям удаляются, максимальная длина — 1000 символов. |
Права и поведение действий
Доступ. Владелец, администратор и пользователь с правом Events могут выполнять все действия в своей организации. Участник без этого права может отменить или удалить только созданное им событие, но не может выполнить complete. Назначение мастером само по себе не даёт права отметить визит.
Состоявшийся визит. complete доступен начиная с трёх часов до dt_start и не имеет верхнего ограничения по времени. Отменённую запись завершить нельзя. Завершение хранится в visit_completed_at; поле status при этом не обязано меняться на completed.
Повторные запросы. Повторные cancel и complete возвращают уже сохранённый результат без второго уведомления, отзыва или веб-хука. Повторный delete вернёт ошибку недоступной записи.
Обратная связь. Если organizations.collect_feedback=true в момент первого complete, создаётся единственный объект отзыва. До dt_end + 1 час сообщение планируется ровно на этот момент; при более поздней отметке в пределах 24 часов — сразу. После 24 часов автоматическая доставка и публичная ссылка не создаются, но отзыв остаётся доступен клиенту в кабинете до трёх календарных месяцев после окончания визита. Публичный токен никогда не возвращается.
Отмена и удаление. cancel переводит запись в cancelled и сохраняет метаданные отмены. delete физически удаляет запись и её кастомные поля; разовое событие получает dt_delete. После complete отмена запрещена. Восстановление отдельным действием модуля bookings не предусмотрено.
Регулярная серия. cancel и delete относятся только к записи с переданным id. Дата вхождения добавляется в recurrence_exdates родительского события; серия и соседние даты не меняются. complete изменяет только выбранную запись и не исключает дату из серии.
Побочные эффекты. Действия синхронно меняют связанную запись и событие, публикуют booking-веб-хук с причиной cancel, complete или delete. Отмена запускает стандартное уведомление сотрудникам, а завершение будит очередь клиентской обратной связи.
Поля успешных ответов действий
Для datetime-полей также возвращаются варианты _iso_string и _timezone. Необязательные объекты и поля добавляются только когда они существуют: например, cancellation_comment — только для непустого комментария, feedback — только при feedback_eligible=true.
| Поле | Тип | Действия | Описание |
|---|---|---|---|
id | number | cancel, complete, delete | Идентификатор обработанной записи. |
event_id | number | cancel, complete, delete | Идентификатор связанного календарного события. |
status | string | cancel, complete | Актуальный статус записи после действия. |
cancelled_at | datetime | cancel | Время отмены с ISO-строкой и часовым поясом. |
cancelled_by_type | string | cancel | Тип инициатора отмены. В модуле кабинета это user. |
cancelled_by_id | number | cancel | Идентификатор инициатора отмены. |
cancellation_comment | string | cancel | Нормализованный непустой комментарий к отмене. |
visit_completed_at | datetime | complete | Время первой отметки визита с ISO-строкой и часовым поясом. |
visit_completed_by_user_id | number | complete | Пользователь, первым отметивший визит. |
feedback_eligible | boolean | complete | Создано ли состояние обратной связи. |
feedback | object | complete | Состояние отзыва с id, оценкой, комментарием, сроками сообщения, публичной формы и кабинета и временем отправки. Публичный UID не возвращается. |
recurring | boolean | cancel, delete | Относилась ли запись к регулярному событию. |
occurrence_start | datetime | cancel, delete | Дата и время обработанного вхождения с ISO-строкой и часовым поясом. |
occurrence_key | string | cancel, delete | Стабильный ключ обработанного вхождения серии. |
deleted | boolean | delete | Всегда true после успешного физического удаления. |
POST /api/?mod=bookings&action=complete&id=42
{
"ok": true,
"data": {
"id": 42,
"event_id": 18,
"status": "active",
"visit_completed_at": "2026-09-21 15:05:00",
"visit_completed_at_iso_string": "2026-09-21T15:05:00+03:00",
"visit_completed_at_timezone": "Europe/Moscow",
"visit_completed_by_user_id": 7,
"feedback_eligible": true,
"feedback": {
"id": 9,
"rating": 0,
"comment": null,
"message_due_at": "2026-09-21 16:00:00",
"message_due_at_iso_string": "2026-09-21T16:00:00+03:00",
"message_due_at_timezone": "Europe/Moscow",
"public_expires_at": "2026-09-28 16:00:00",
"public_expires_at_iso_string": "2026-09-28T16:00:00+03:00",
"public_expires_at_timezone": "Europe/Moscow",
"account_expires_at": "2026-12-21 15:00:00",
"account_expires_at_iso_string": "2026-12-21T15:00:00+03:00",
"account_expires_at_timezone": "Europe/Moscow",
"submitted_at": null,
"submitted_at_iso_string": null,
"submitted_at_timezone": "Europe/Moscow"
}
}
}POST /api/?mod=bookings&action=cancel&id=42
{
"cancellation_comment": "Клиент попросил перенести визит"
}
{
"ok": true,
"data": {
"id": 42,
"event_id": 18,
"status": "cancelled",
"cancelled_at": "2026-09-21 12:30:00",
"cancelled_at_iso_string": "2026-09-21T12:30:00+03:00",
"cancelled_at_timezone": "Europe/Moscow",
"cancelled_by_type": "user",
"cancelled_by_id": 7,
"cancellation_comment": "Клиент попросил перенести визит",
"recurring": true,
"occurrence_start": "2026-09-21 14:00:00",
"occurrence_start_iso_string": "2026-09-21T14:00:00+03:00",
"occurrence_start_timezone": "Europe/Moscow",
"occurrence_key": "20260921140000"
}
}Ответы с ошибками
Data-endpoints используют общие коды сохранения, а действия — диапазон 551–557. Ошибка доступа к конкретной записи в действии намеренно не отличима от отсутствующей записи.
| Код | Когда возникает | Ответ |
|---|---|---|
11-14 | Нет сессии, организации, прав чтения или права сохранить кастомные поля записи. | Один из общих кодов 11–14 с локализованным message. |
16-17 | Не заполнено обязательное кастомное поле или значение кастомного поля невалидно. | required для кода 16 либо errors для кода 17. |
18 | Попытка удалить запись через общий delete_data вместо mod=bookings&action=delete. | message о невозможности удаления. |
551 | Передано неизвестное действие с клиентской записью. | message с описанием неизвестного действия. |
552 | Запись не найдена, удалена, недоступна или относится к другой организации. | message о недоступной записи. |
553 | Связанное календарное событие не найдено. | message об отсутствующем событии. |
554 | Вхождение не подтверждено правилами регулярной серии. | message о недоступном вхождении серии. |
555 | Запись отменена, визит уже завершён для несовместимого действия или текущее состояние иначе запрещает действие. | message о недопустимом состоянии. |
556 | Комментарий к отмене после trim длиннее 1000 символов. | message о максимальной длине комментария. |
557 | Визит отмечают состоявшимся раньше чем за три часа до начала. | message о допустимом времени действия. |