Аутентификация
OAuth2 (Resource Owner Password Credentials): получение и обновление токена доступа, срок его жизни и заголовок авторизации для запросов к Hostme API.
Hostme API использует OAuth2 со схемой Resource Owner Password Credentials
(password flow). Токен получаете по логину/паролю сервисной учётной записи и прикладываете
его к каждому запросу в заголовке Authorization: Bearer <token>.
Шаг 1. Получение токена
Токен выдаётся по POST /Token в формате application/x-www-form-urlencoded:
curl -X POST https://api.hostmeapp.com/Token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=password" \ -d "username=YOUR_USERNAME" \ -d "password=YOUR_PASSWORD"
client_idиscopeпартнёрам указывать не нужно — достаточноgrant_type,username,password. (Внутренняя админ-панель Hostme дополнительно шлётclient_id=panel, но для партнёрских интеграций это не требуется.)
Ответ:
{ "access_token": "eyJhbGciOiJ...", "token_type": "bearer", "expires_in": 86399}| Поле | Описание |
|---|---|
access_token | Токен доступа. Прикладывается к каждому запросу к API. |
token_type | Тип токена — bearer. |
expires_in | Время жизни токена в секундах. |
refresh_tokenв ответеPOST /Tokenне возвращается — по истеченииexpires_inполучите новый токен повторным запросом с логином/паролем.
Endpoint и окружения
| Окружение | Token endpoint |
|---|---|
| Production | https://api.hostmeapp.com/Token |
| QA / Test | https://api-qa.hostmeapp.com/Token |
Про swagger. В спецификации OAuth2 объявлен с
tokenUrl: https://service.hostmeapp.com/tokenи scopeAll— это официальный сервер авторизации. На практике токен принимается и на базовом домене API ({API_BASE}/Token) — именно так логинится прод-панель, и этот путь рекомендуется для партнёрских интеграций.scopeотправлять не обязательно.
Приложение маркетплейса — client_credentials (рекомендуется)
Если ваша интеграция публикуется приложением в разделе «Интеграции», парольный грант выше вам не нужен и не подходит: логин и пароль кабинета ресторана у партнёра не хранятся. Вместо этого ресторан подключает ваше приложение и Hostme выдаёт ему пару Client ID / Client Secret — она видна в настройках приложения, ресторан копирует её в ваш кабинет.
Пара выдаётся на каждое подключение, то есть на каждый ресторан, а не одна на партнёра.
Сколько ресторанов подключили приложение — столько у вас пар, и токен, полученный по паре,
работает только с этим рестораном: его идентификатор зашит в сам токен, передавать
restaurantId отдельно при получении токена не нужно.
curl -X POST https://api.hostmeapp.com/api/pos/apps/{appId}/security/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET"{appId} — идентификатор вашего приложения в каталоге Hostme (например airsales).
Ответ — тот же, что и у парольного гранта:
{ "access_token": "eyJhbGciOiJ...", "token_type": "Bearer", "expires_in": 43199}| Окружение | Token endpoint |
|---|---|
| Production | https://api.hostmeapp.com/api/pos/apps/{appId}/security/oauth/token |
| QA / Test | https://api-qa.hostmeapp.com/api/pos/apps/{appId}/security/oauth/token |
Что важно учесть
scopeпередавать не нужно. Права берутся из манифеста вашего приложения, а не из запроса. Присланныйscopeигнорируется — в том числеscope=All, который раньше приводил кinvalid_scope.- Время жизни короче, чем у парольного гранта, и может отличаться у разных приложений:
например, у приложений с доступом к броням в реальном времени это 12 часов (
expires_in: 43199). Читайтеexpires_inиз ответа, не зашивайте константу. refresh_tokenне выдаётся — за новым токеном приходите с той же парой.- Неверная пара →
401. Секрет сверяется в постоянном времени, ответ не различает «нет такого client_id» и «неверный секрет». - Отключение приложения рестораном мгновенно отзывает доступ: резолвер пары смотрит только активные подключения, поэтому нового токена вы не получите, а выданный перестанет работать.
- Токен приходит в зашифрованном виде (JWE, пять частей): разобрать его на своей стороне, чтобы прочитать claims, нельзя — используйте как непрозрачную строку.
Чем такой токен отличается в работе
Брони, созданные под этим токеном, автоматически помечаются вашим приложением
(vendorKey / vendorName в контракте брони) и попадают в аналитику ресторана как ваш канал —
проставлять ничего вручную не нужно. Поле source у них — web.
Права ограничены манифестом: ручки, которых нет в запрошенных разрешениях, ответят 403,
даже если токен действителен. Так, приложению с доступом к броням и доступности не видны
заявки на бронь (GET /api/rsv/admin/restaurants/{id}/requests).
Шаг 2. Использование токена
Прикладывайте access_token к каждому запросу:
curl https://api.hostmeapp.com/api/core/admin/account/me \ -H "Authorization: Bearer eyJhbGciOiJ..."Без действительного токена API вернёт 401 Unauthorized.
Шаг 3. Какой ресторан доступен
GET /api/core/admin/account/me
После получения токена узнайте, к каким ресторанам у вас есть доступ, и их restaurantId:
curl https://api.hostmeapp.com/api/core/admin/account/me \ -H "Authorization: Bearer <token>"Ответ — UserInfoContract. Ключевые поля:
| Поле | Тип | Описание |
|---|---|---|
id | string | Идентификатор пользователя/учётной записи |
email | string | |
fullName | string | Имя |
partnerId | string | Идентификатор партнёра (если учётка партнёрская) |
roles[] | array | Роли по ресторанам: restaurantId, restaurantName, name, type |
restaurants[] | array | Доступные рестораны (см. ниже) |
Элемент restaurants[] (RestaurantSummaryContract):
| Поле | Тип | Описание |
|---|---|---|
id | integer | restaurantId — используйте в путях /restaurants/{restaurantId}/... |
name | string | Название |
address, city, country, countryShort | string | Адрес |
timeZone | string | Часовой пояс ресторана |
isVerified | boolean | Верифицирован |
isSuspended | boolean | Приостановлен |
isOnline | boolean | Онлайн-приём броней включён |
role | string | Ваша роль в ресторане |
Типы токенов и поведение API
Поведение некоторых эндпоинтов зависит от типа токена, под которым выполнен запрос:
| Тип токена | Кто это | Как создаются записи |
|---|---|---|
| Hostme | Хост/менеджер в админ-панели | От имени текущего пользователя |
| Partner | Партнёрская учётная запись | От имени текущего пользователя (хоста/менеджера) |
| Vendor | Внешнее приложение (POS, CRM) | От имени внешнего приложения; автоматически проставляется VendorAppId |
Пример: при создании брони (POST .../reservations) под токеном Vendor бронь создаётся
от имени внешнего приложения, а при выборке списка для scope App автоматически
подставляется VendorAppId и требуется обязательный диапазон дат (не более 60 дней).
Подробнее — в разделах Бронирования и Партнёрские брони.
Партнёрский токен
POST /api/core/admin/account/partners/token
Для партнёрских сценариев платформа поддерживает выдачу партнёрского токена через
POST /api/core/admin/account/partners/token (тело — PartnerTokenRequest). Конкретная
схема запроса согласуется индивидуально при подключении партнёра.
Точный формат тела
PartnerTokenRequestи условия выдачи партнёрского токена предоставляет команда Hostme при онбординге партнёра — см. Регистрация приложения.
Обработка ошибок аутентификации
| Код | Причина | Что делать |
|---|---|---|
401 | Токен отсутствует, истёк или недействителен | Получить новый токен; проверить заголовок Authorization |
403 | Нет прав на ресторан/действие | Проверить доступ учётной записи к restaurantId |
Подробнее об ошибках — в разделе Ошибки и коды ответов.