Версия 1. Доступ по индивидуальному ключу предприятия.
API журнала бронирований TGbot Cafe возвращает занятые интервалы всех подключённых залов предприятия. По ним сайт или другое приложение может показать календарь доступности. Метод только читает данные: создание брони, изменение записи, приём оплаты и резервирование времени не поддерживаются. Имена и телефоны клиентов, комментарии, услуги, суммы и внутренние номера документов в ответ не входят.
Скачать контракт OpenAPI 3.0.3
Метод и доступ
| Параметр | Значение |
|---|---|
| Метод | GET /api/v1/availability |
| Базовый адрес | https://tgbotcafe.assistbot.ru |
| Авторизация | Authorization: Bearer и индивидуальный ключ предприятия |
| Формат ответа | application/json |
| Лимит | 60 запросов в минуту на IP; лимит общий с другими запросами API |
Ключ выдаёт администратор API после подключения предприятия. Его формат — префикс arma_avail_ и 64 шестнадцатеричных символа. Это отдельный ключ TGbot Cafe; токены API отправки сообщений AssistBot для этого метода не подходят. Один ключ открывает только календарь закреплённого предприятия и не даёт доступа к админке или операциям оплаты.
Выполняйте запрос по HTTPS с сервера своего приложения. Храните ключ в закрытой серверной настройке; не размещайте его в HTML, браузерном JavaScript или адресе запроса. Если ключ раскрыт, попросите администратора отозвать его и выдать новый. Предприятие определяется ключом: переключить его параметрами запроса нельзя.
Параметры запроса
| Поле | Обязательно | Формат |
|---|---|---|
from | Да | Начало диапазона: 2026-10-15T00:00:00+03:00 |
to | Да | Конец диапазона: 2026-10-17T00:00:00+03:00 |
- Нужен RFC3339 с целыми секундами и явным часовым поясом: смещение, например
+03:00, илиZ. Максимальное смещение —±14:00. Дробные секунды, дата без времени и время без пояса не принимаются. - Диапазон имеет вид
[from, to): начало включено, конец исключён. Конец должен быть позже начала, длительность — не больше 31 × 24 часов, то есть 2 678 400 секунд. - Разрешены только
fromиto. Выбор предприятия и фильтры залов не поддерживаются: ответ содержит все настроенные залы предприятия. - Знак
+кодируйте как%2B. Для этого используйте построитель query или--data-urlencode.
Пример для подключённого предприятия. Переменная AVAILABILITY_KEY содержит выданный ключ:
curl --fail-with-body --get 'https://tgbotcafe.assistbot.ru/api/v1/availability' \
--header "Authorization: Bearer ${AVAILABILITY_KEY}" \
--header 'Accept: application/json' \
--data-urlencode 'from=2026-10-15T00:00:00+03:00' \
--data-urlencode 'to=2026-10-17T00:00:00+03:00'
Ответ и пример
Вымышленный пример предприятия с шестью залами. В другом подключении список залов и их коды могут отличаться. Первая запись переходит через полночь:
{
"version": 1,
"source": "admin_calendar",
"timezone": "Europe/Moscow",
"from": "2026-10-15T00:00:00+03:00",
"to": "2026-10-17T00:00:00+03:00",
"generated_at": "2026-10-13T13:20:00+03:00",
"data_updated_at": "2026-10-13T12:45:00+03:00",
"freshness": "live",
"complete": false,
"incomplete_reasons": ["calendar_not_authoritative"],
"halls": [
{"hall_id": "armaloft", "name": "Зал АрмаЛофт", "busy_intervals": [
{"starts_at": "2026-10-15T22:00:00+03:00", "ends_at": "2026-10-16T02:00:00+03:00"}
]},
{"hall_id": "mercury", "name": "Зал Меркури", "busy_intervals": []},
{"hall_id": "airplane", "name": "Зал Самолет", "busy_intervals": []},
{"hall_id": "rufer", "name": "Зал Руфер", "busy_intervals": []},
{"hall_id": "pulka", "name": "Зал Пулька", "busy_intervals": []},
{"hall_id": "boho", "name": "Зал Бохо", "busy_intervals": []}
]
}
| Поле | Смысл |
|---|---|
version, source | Версия 1, источник admin_calendar — календарь админки. |
timezone, from, to | Часовой пояс Europe/Moscow. Даты — в RFC3339 с московским смещением для соответствующей даты: сейчас +03:00, исторически оно может отличаться, например +04:00 в 2012 году. |
generated_at | Время начала чтения согласованного снимка календаря. |
data_updated_at | Последнее изменение сохранившихся записей календаря или описаний настроенных залов, включая отменённые записи и даты вне запроса. Может быть null. Это не номер ревизии и не время последней внешней синхронизации; удаление записи не создаёт новую такую отметку. |
freshness | live — текущий снимок базы без кеша ответа. Само значение не подтверждает полноту внешних источников. |
complete, incomplete_reasons | Полнота источника. При false причина — calendar_not_authoritative; при true массив причин пуст. |
halls[].hall_id, name | Стабильный публичный код зала и его текущее название. Переименование не меняет код. |
busy_intervals[].starts_at, ends_at | Начало и конец занятого интервала с датой и часовым поясом. |
Как определять свободное время
При complete=false отсутствие занятого интервала не означает, что зал свободен: часть броней может ещё находиться во внешнем источнике. Можно отмечать известную занятость, но нельзя подтверждать свободность остальных часов. Даже HTTP 200 и пустой массив в этом случае не являются подтверждением.
Перед показом свободного времени проверяйте HTTP 200, version=1, source=admin_calendar, freshness=live, complete=true и полный ожидаемый список залов. При ошибке или неполном календаре показывайте «Доступность временно не подтверждена»; не заменяйте такой ответ пустым календарём.
- Занятые интервалы отсортированы; пересекающиеся и соседние объединены. Границы остаются исходными, даже если запись началась до
fromили заканчивается послеto. - Запись включается при
starts_at < toиends_at > from. Соседняя запись может начаться точно в момент окончания предыдущей. - Отменённые записи исключены. Неявка, отсутствие оплаты и бесплатный просмотр сами по себе не освобождают время. Минуты и ночные интервалы сохраняются без округления до часов.
Ответы метода содержат директиву no-store в Cache-Control, например no-store, private; в заголовке могут быть дополнительные допустимые директивы. Не кешируйте ответы как подтверждённую доступность. Для всех залов достаточно одного запроса. Чтение календаря не резервирует выбранное время: после ответа другой пользователь может создать новую запись. Метод не синхронизирует внешний календарь и не переключает автоматически существующий процесс создания броней.
Ошибки
Для ошибок авторизации, параметров и чтения календаря возвращается короткий JSON:
{"error":{"code":"calendar_unavailable"}}
| HTTP | Код / причина | Действие |
|---|---|---|
| 401 | unauthorized: ключ отсутствует, неверен, отозван или передан в query; подключение предприятия не действует. | Проверьте ключ у администратора API. |
| 422 | invalid_range: некорректные даты, пустой, обратный или слишком большой диапазон. | Исправьте from и to. |
| 422 | unsupported_parameter: лишний параметр запроса. | Оставьте только from и to. |
| 503 | calendar_unavailable: нельзя получить корректный календарь. Ни один недоступный зал не подменяется пустым свободным списком. | Покажите временную недоступность. |
| 405 | Неподдерживаемый метод; стандартный ответ сервера. | Используйте GET. Не рассчитывайте на описанную выше форму JSON. |
| 429 | Превышен общий лимит; стандартный ответ сервера. | Подождите время из Retry-After и уменьшите частоту запросов. |
Любой другой ответ, включая 500, также не подтверждает свободное время. Стандартные ответы 405 и 429 не имеют гарантированного формата ошибки календаря. Допускается HEAD с той же авторизацией и заголовками, без тела; отдельного второго метода API для него нет.