Открытый APIверсия 26.11.2
Документация · Bounty API — партнёры
Открытый API бизнеса: объекты пяти категорий, номерной фонд, календарь доступности, цены и правила, брони и заселения, долгосрочная аренда, переписка с гостями, отзывы и финансы. Своё ПО и модули связи с PMS входят ключом API из кабинета партнёра (Компания → Разработчикам).
202 эндпоинта26 разделовhttps://partner-api.bounty.travel/v1
Разделы и поиск · 26
Как пользоваться
Два способа войти. Ключ API bnt_live_… — без входа, сессии и капчи, с правами по разделам, выданными владельцем, и своим лимитом частоты. Сотрудник — по паролю, с теми же правами по разделам.
Модуль связи с чужой PMS или channel manager пишется против этого контракта, а не против базы. Отдельной тестовой среды нет: проверяйте интеграцию на объекте, который ещё не опубликован. Условия — «Условия использования API».
Общие правила
Версия — в пути. Все эндпоинты начинаются с /v1. Ломающие изменения выходят новой версией пути, а не правкой текущей.
Аутентификация — Authorization: Bearer <access>. Токен выдаёт POST /v1/auth/login; он живёт 15 минут, обновляется по refresh-токену через POST /v1/auth/refresh. Обмен отдаёт свежий access и тот же refresh, а срок сессии сдвигается: сессия держится, пока ей пользуются. Выход и «выйти везде» закрывают сессию сразу.
Токен одного API никогда не принимается другим. У каждой аудитории свой секрет подписи, а не только claim aud: чужой токен не проходит проверку подписи, а не проверку прав.
Ответы и ошибки
Успех — тело эндпоинта как есть. Ошибка — всегда один и тот же конверт:
{
"error": {
"code": "validation_error",
"message": "Дата выезда должна быть позже даты заезда",
"details": {"field": "date_to"},
"request_id": "0f1c…"
}
}
code — машинный, по нему и нужно ветвиться. message — для человека, он может меняться. request_id есть в каждом ответе и в заголовке X-Request-Id: с ним обращение в поддержку находит запрос в журнале за секунды.
Коды: 400 validation_error, 401 unauthorized, 403 forbidden, 404 not_found, 409 conflict, 410 gone, 422 unprocessable (данные верны, но действие сейчас невозможно — например, объект не готов к публикации), 429 rate_limited (с заголовком Retry-After), 500 internal_error, 502 upstream_unavailable (не ответил внешний сервис — повторите позже). Ошибка разбора тела или параметров — всегда 400 validation_error с полями в details.fields, а не 422.
Списки
Пагинация курсорная, OFFSET не используется нигде:
{"items": [...], "next_cursor": "eyJ…", "has_more": true}
next_cursor непрозрачен — собирать его руками нельзя, его форма не часть контракта. Нет next_cursor — страница последняя.
Повторы и идемпотентность
Создающие запросы принимают заголовок Idempotency-Key. Повтор с тем же ключом возвращает тот же результат, а не заводит вторую запись. Ключ живёт 24 часа.
Частота
Лимиты считаются по адресу и по актёру. Превышение — 429 с Retry-After в секундах. Клиент обязан ждать указанное время, а не повторять сразу.
Время, деньги и языки
- Время объекта — в его часовом поясе и в UTC не переводится никогда. Календарные даты (заезд, выезд, день события) — это
dateв поясе объекта. Моменты —timestamptzв UTC. - Деньги — в минорных единицах (
price_minor) вместе с кодом валюты. Суммы никогда не приходят от клиента: их считает сервер. - Язык ответа — заголовок
Accept-Languageили параметрlang. Языки:en(по умолчанию),ru,th,zh-Hans. Непереведённая строка отдаётся по-английски, а переведённый контент помечается пометкой о переводе.
Особенности этого API
- Ключ показывается один раз — в ответе на выпуск; в базе только отпечаток. Отзыв действует сразу.
- Ключу закрыто то, что делает только человек: вход и сессии, ключи, сотрудники и журнал, документы компании, свои настройки —
403 api_key_forbidden. - Права —
403 role_requiredс нужным скоупом вdetails.required. - Realtime — WebSocket
/v1/ws: переписка с гостями и уведомления. Вход, кадры и события — раздел «Сокет/v1/ws» ниже.
Сокет /v1/ws
Swagger сокетов не показывает, поэтому всё о нём — здесь. Адрес: wss://partner-api.bounty.travel/v1/ws?token=… или …?ticket=…. Заголовок Authorization браузерному WebSocket не поставить, поэтому вход — параметром адреса:
token— токен сотрудника, выбравшего бизнес, или ключ APIbnt_live_…с правомchat:read. Токен без выбранного бизнеса не подходит: непонятно, чьи события слать.ticket— одноразовый билет изPOST /v1/auth/ws-ticketдля кабинета в браузере: живёт минуту и открывает один сокет.
Канал — на бизнес: события получают все сотрудники и ключи, подключённые сейчас, — на сообщение гостя отвечает тот, кто свободен.
Отказ во входе — закрытие с кодом 1008: обновите токен или возьмите новый билет, а не переподключайтесь по кругу.
Кадр — JSON в обе стороны: {"event": "…", "payload": {…}, "ts": "…"}. ts ставит сервер. Время внутри payload может прийти и как 2026-10-14 11:18:22.300148+00:00 (через пробел) — читайте оба вида.
События сервера
| Событие | Когда | payload |
|---|---|---|
message.new | новое сообщение в переписке, в том числе служебное и своё с другого устройства | сообщение, как в GET /v1/dialogs/{id}/messages |
message.read | собеседник прочитал | {dialog_id, up_to_id} |
message.translated | готов перевод сообщения на язык получателя | {dialog_id, message_id, lang, text} |
message.deleted | сообщение убрано из переписки | {dialog_id, message_id} |
typing | собеседник печатает | {dialog_id} |
notification.new | новое уведомление в ленте | уведомление, как в GET /v1/notifications |
pong | ответ на ping | {} |
Команды клиента
| Событие | Что делает | payload |
|---|---|---|
message.send | отправить сообщение | dialog_id, text или upload_id, reply_to_id? |
message.read | пометить прочитанным | {dialog_id, up_to_id?} — без up_to_id всё |
typing | «печатает», в базе не хранится | {dialog_id} |
ping | держать соединение | раз в 30 секунд, иначе прокси рвёт простаивающее соединение |
Правила
- Права и лимиты у команд — те же, что у REST. Отказ (нет прав, чужой диалог, лимит, закрытая переписка) кадром не приходит и соединение не рвёт: команда просто не выполняется. Отправленное видно по
message.new; нужен ответ с кодом ошибки — шлитеPOST /v1/dialogs/{id}/messages. - Неизвестная команда пропускается молча.
- Файлы по сокету не летят: сначала
POST /v1/uploads, затемmessage.sendсupload_id. - Доставка не гарантируется. После переподключения или если сокет не открывается вовсе догоняйте пропущенное
GET /v1/dialogs/{id}/messages?after_id=…. - Разрыв — повтор с паузой 1 → 2 → 4 → 8 секунд, не дольше 30.
Ничего не нашлось — попробуйте путь (/v1/bookings) или метод (POST)
Аутентификация
18 эндпоинтовВход сотрудника паролем, выбор бизнеса, сессии, восстановление пароля. Своему ПО это не нужно: оно входит ключом API (Authorization: Bearer bnt_live_…) — без входа, сессии и капчи. Ключу весь раздел закрыт.
POST/v1/auth/register
Самостоятельная регистрация партнёра
Без входа
Заводится человек, а не бизнес: категорию и тип он выберет в анкете. Ответ одинаков для занятого и свободного адреса — иначе форма отвечала бы на вопрос, работает ли эта компания с Bounty.
Тело запросаRegisterRequest · application/json
captcha_id
string
по умолчанию ""
Номер задачи капчи — ползунка-пазла, который выдаёт модуль капчи
captcha_answer
string
по умолчанию ""
Ответ на задачу капчи
email
string (email)
обязательно
Адрес почты
password
string
обязательно
Пароль
full_name
string
обязательно
Имя и фамилия
Ответы
202Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/register' \
-H 'Content-Type: application/json' \
-d '{"email": "anna@example.com", "password": "…", "full_name": "…"}'
POST/v1/auth/verify-email
Подтверждение адреса по ссылке из письма
Без входа
Токенов не выдаёт: человек возвращается на форму входа и заходит сам. Пускать по ссылке из письма — значит превращать письмо в ключ от учётки, живущий двое суток в чужом почтовом ящике.
Тело запросаVerifyEmailRequest · application/json
token
string
обязательно
Ответы
200Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/verify-email' \
-H 'Content-Type: application/json' \
-d '{"token": "…"}'
POST/v1/auth/resend-verification
Выслать письмо с подтверждением заново
Без входа
Тело запросаResendVerificationRequest · application/json
captcha_id
string
по умолчанию ""
Номер задачи капчи — ползунка-пазла, который выдаёт модуль капчи
captcha_answer
string
по умолчанию ""
Ответ на задачу капчи
email
string (email)
обязательно
Адрес почты
Ответы
200Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/resend-verification' \
-H 'Content-Type: application/json' \
-d '{"email": "anna@example.com"}'
POST/v1/auth/login
Вход в панель по почте и паролю
Без входа
Входит человек, а сессия заводится в бизнесе. У кого бизнесов несколько и partner_id не прислан — 409 partner_choice_required со списком в details.partners.
Тело запросаLoginRequest · application/json
captcha_id
string
по умолчанию ""
Номер задачи капчи — ползунка-пазла, который выдаёт модуль капчи
captcha_answer
string
по умолчанию ""
Ответ на задачу капчи
email
string (email)
обязательно
Адрес почты
password
string
обязательно
Пароль
partner_id
string (uuid) или null
Идентификатор бизнеса-партнёра (UUID)
Ответы
200Успешный ответ · TokenPairResponse
Поля ответа · 5
access_token
string
обязательно
Короткий токен для заголовка Authorization: Bearer …
refresh_token
string
обязательно
Долгий токен обмена: POST /v1/auth/refresh даёт по нему новый access
token_type
string
по умолчанию "Bearer"
expires_in
integer
обязательно
Через сколько секунд истекает
session_id
string (uuid)
обязательно
Идентификатор сессии (UUID)
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/login' \
-H 'Content-Type: application/json' \
-d '{"email": "anna@example.com", "password": "…"}'
POST/v1/auth/login/choose
Второй шаг входа: выбранный бизнес в обмен на билет из 409
Без входа
Пароль второй раз не спрашивается: он проверен на первом шаге, а билет одноразовый и живёт пять минут. Внешнему ПО этот шаг не нужен — оно повторяет тот же POST /v1/auth/login с partner_id.
Тело запросаLoginChooseRequest · application/json
login_token
string
обязательно
partner_id
string (uuid)
обязательно
Идентификатор бизнеса-партнёра (UUID)
Ответы
200Успешный ответ · TokenPairResponse
Поля ответа · 5
access_token
string
обязательно
Короткий токен для заголовка Authorization: Bearer …
refresh_token
string
обязательно
Долгий токен обмена: POST /v1/auth/refresh даёт по нему новый access
token_type
string
по умолчанию "Bearer"
expires_in
integer
обязательно
Через сколько секунд истекает
session_id
string (uuid)
обязательно
Идентификатор сессии (UUID)
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/login/choose' \
-H 'Content-Type: application/json' \
-d '{"login_token": "…", "partner_id": "00000000-0000-0000-0000-000000000000"}'
POST/v1/auth/switch
Перейти в другой свой бизнес — новой парой токенов
Нужен вход
Текущая сессия закрывается сразу: токен, выданный на один бизнес, не должен действовать в другом даже секунду.
Зависимость здесь — человек, а не партнёр с работающим бизнесом. Так сюда попадает и тот, чью анкету только что одобрили: его сессия выдана без бизнеса, и просить у него пароль заново незачем — он всё это время смотрел на экран анкеты. Право проверяет switch: перейти можно только в бизнес, где у человека есть действующее членство.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Тело запросаSwitchRequest · application/json
partner_id
string (uuid)
обязательно
Идентификатор бизнеса-партнёра (UUID)
Ответы
200Успешный ответ · TokenPairResponse
Поля ответа · 5
access_token
string
обязательно
Короткий токен для заголовка Authorization: Bearer …
refresh_token
string
обязательно
Долгий токен обмена: POST /v1/auth/refresh даёт по нему новый access
token_type
string
по умолчанию "Bearer"
expires_in
integer
обязательно
Через сколько секунд истекает
session_id
string (uuid)
обязательно
Идентификатор сессии (UUID)
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/switch' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"partner_id": "00000000-0000-0000-0000-000000000000"}'
GET/v1/auth/partners
Бизнесы, где человек состоит: что показать в переключателе кабинета
Нужен вход
Ответы
200Успешный ответ · массив PartnerChoiceResponse
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/auth/partners' \
-H 'Authorization: Bearer <access>'
GET/v1/auth/invite
Проверка ссылки приглашения. Токен при этом не расходуется
Без входа
Параметры
token
запрос · string
обязательно
Ответы
200Успешный ответ · InviteCheckResponse
Поля ответа · 3
valid
boolean
обязательно
email
string или null
Адрес почты
display_name
string или null
Имя для показа
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/auth/invite'
POST/v1/auth/invite/accept
Приглашённый задаёт пароль и сразу попадает внутрь
Без входа
Тело запросаInviteAcceptRequest · application/json
token
string
обязательно
password
string
обязательно
Пароль
Ответы
200Успешный ответ · TokenPairResponse
Поля ответа · 5
access_token
string
обязательно
Короткий токен для заголовка Authorization: Bearer …
refresh_token
string
обязательно
Долгий токен обмена: POST /v1/auth/refresh даёт по нему новый access
token_type
string
по умолчанию "Bearer"
expires_in
integer
обязательно
Через сколько секунд истекает
session_id
string (uuid)
обязательно
Идентификатор сессии (UUID)
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/invite/accept' \
-H 'Content-Type: application/json' \
-d '{"token": "…", "password": "…"}'
POST/v1/auth/refresh
Обмен refresh-токена на новую пару
Без входа
Тело запросаRefreshRequest · application/json
refresh_token
string
обязательно
Долгий токен обмена: POST /v1/auth/refresh даёт по нему новый access
Ответы
200Успешный ответ · TokenPairResponse
Поля ответа · 5
access_token
string
обязательно
Короткий токен для заголовка Authorization: Bearer …
refresh_token
string
обязательно
Долгий токен обмена: POST /v1/auth/refresh даёт по нему новый access
token_type
string
по умолчанию "Bearer"
expires_in
integer
обязательно
Через сколько секунд истекает
session_id
string (uuid)
обязательно
Идентификатор сессии (UUID)
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/refresh' \
-H 'Content-Type: application/json' \
-d '{"refresh_token": "…"}'
POST/v1/auth/ws-ticket
Одноразовый билет для подключения к /v1/ws
Нужен вход
Нужен кабинету: токен лежит на его сервере, а у страницы в браузере нет ничего, кроме идентификатора сессии в cookie HttpOnly. Заголовок Authorization браузерному WebSocket не поставить, а отдать токен странице значило бы снять эту защиту ради удобства подключения.
Своему ПО партнёра билет не нужен: у него есть токен, и он шлёт его параметром адреса.
Ответы
200Успешный ответ · WsTicketResponse
Поля ответа · 2
ticket
string
обязательно
expires_in
integer
обязательно
Через сколько секунд истекает
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/ws-ticket' \
-H 'Authorization: Bearer <access>'
POST/v1/auth/logout
Выйти: закрыть текущую сессию. Её refresh больше не обменивается
Нужен вход
Ответы
200Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/logout' \
-H 'Authorization: Bearer <access>'
POST/v1/auth/logout-all
Выйти везде, кроме этого устройства — во всех бизнесах сотрудника
Нужен вход
Для человека это один пароль, а не несколько кабинетов; в ответе — сколько сессий закрыто.
Ответы
200Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/logout-all' \
-H 'Authorization: Bearer <access>'
GET/v1/auth/sessions
Устройства, с которых заходили в панель
Нужен вход
Ответы
200Успешный ответ · массив SessionResponse
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/auth/sessions' \
-H 'Authorization: Bearer <access>'
DELETE/v1/auth/sessions/<span class="text-brand-ink">{session_id}</span>
Закрыть одну свою сессию — например, на потерянном устройстве
Нужен вход
Параметры
session_id
путь · string (uuid)
обязательно
Идентификатор сессии (UUID)
Ответы
200Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/auth/sessions/{session_id}' \
-H 'Authorization: Bearer <access>'
POST/v1/auth/password-reset/request
Ссылка на смену пароля. Всегда 202, независимо от наличия аккаунта
Без входа
Тело запросаPasswordResetRequest · application/json
captcha_id
string
по умолчанию ""
Номер задачи капчи — ползунка-пазла, который выдаёт модуль капчи
captcha_answer
string
по умолчанию ""
Ответ на задачу капчи
email
string (email)
обязательно
Адрес почты
Ответы
202Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/password-reset/request' \
-H 'Content-Type: application/json' \
-d '{"email": "anna@example.com"}'
POST/v1/auth/password-reset/confirm
Новый пароль по ссылке из письма. Все сессии завершаются
Без входа
Тело запросаPasswordResetConfirm · application/json
token
string
обязательно
password
string
обязательно
Пароль
Ответы
200Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/password-reset/confirm' \
-H 'Content-Type: application/json' \
-d '{"token": "…", "password": "…"}'
POST/v1/auth/password/change
Смена пароля изнутри панели. Текущая сессия остаётся жить
Нужен вход
Тело запросаPasswordChangeRequest · application/json
current_password
string
обязательно
new_password
string
обязательно
Ответы
200Успешный ответ · MessageResponse
Поля ответа · 2
ok
boolean
по умолчанию true
Успешно ли
message
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/auth/password/change' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"current_password": "…", "new_password": "…"}'
Ключи API
4 эндпоинтаКлючи бизнеса для своего ПО и интеграций: справочник формы, список, выпуск, отзыв. Только полный доступ и только сессией кабинета — ключом другой ключ не выпустить. Ключ показывается один раз.
GET/v1/keys/form
Справочник формы нового ключа: разделы, образцы, сроки
Нужен вход
Разделы — те же, что у доступа сотрудника, плюс «Вебхуки» — только у ключа. Образцы — под типовые системы: PMS, менеджер каналов, свой сайт, бухгалтерия.
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · KeyFormResponse
Поля ответа · 3
areas
массив KeyArea
обязательно
presets
массив KeyPreset
обязательно
terms
массив integer или null
обязательно
Сроки на выбор в днях; null — без срока
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/keys/form' \
-H 'Authorization: Bearer <access>'
GET/v1/keys
Ключи бизнеса — новые сверху; отозванные и истёкшие остаются в списке
Нужен вход
У ключа — начало, права, кто выпустил, срок, адреса, последний запрос и запросов за сегодня. Самого ключа нет: в базе только отпечаток.
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · массив KeyResponse
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/keys' \
-H 'Authorization: Bearer <access>'
POST/v1/keys
Выпускает ключ. Ключ в ответе один раз — дальше только начало
Нужен вход
Без согласия с «Условиями использования API» — 422 terms_required. Права — access (раздел → положение) или scopes. Срок — 30, 90, 365 дней или null. Адреса — необязательно. Действующих ключей — не больше
- Владельцам бизнеса уходит письмо «Выпущен ключ API».
Доступ. только владелец бизнеса.
Тело запросаKeyCreate · application/json
name
string
обязательно
access
object или null
Раздел → none / read / write; webhooks → none / write
scopes
массив string или null
Вместо access: calendar:write, …
expires_in_days
integer или null
по умолчанию 365
30 / 90 / 365 или null — без срока
allowed_ips
массив string
Адреса и подсети, по одному
accept_terms
boolean
обязательно
Согласие с «Условиями использования API» — обязательно
Ответы
201Успешный ответ · KeyCreated
Поля ответа · 18
id
string
обязательно
Идентификатор записи (UUID)
name
string
обязательно
prefix
string
обязательно
Видимое начало ключа: bnt_live_7f3c
status
string
обязательно
active / expiring (меньше 14 дней) / revoked / expired
scopes
массив string
обязательно
Права по разделам
access
object
обязательно
Положения переключателей по разделам
allowed_ips
массив string
обязательно
Адреса и подсети; пусто — с любого адреса
rate_limit_per_min
integer
обязательно
expires_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
created_by
KeyPerson или null
обязательно
last_used_at
string (date-time) или null
обязательно
Последний запрос — с точностью до минуты
last_used_ip
string или null
обязательно
requests_today
integer
обязательно
Запросов за сегодня (UTC)
revoked_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
revoked_by
KeyPerson или null
обязательно
revoked_reason
string или null
обязательно
key
string
обязательно
Ключ целиком — один раз. Потерян — отзовите и выпустите новый
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/keys' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"name": "…", "accept_terms": false}'
DELETE/v1/keys/<span class="text-brand-ink">{key_id}</span>
Отзывает ключ сразу: следующий запрос с ним получит 401
Нужен вход
Вернуть ключ нельзя — только выпустить новый. Чужой и несуществующий ключ отвечают одинаково — 404. Отзыв доступен и ограниченному бизнесу: убрать доступ — это защита, а не действие.
Доступ. только владелец бизнеса.
Параметры
key_id
путь · string (uuid)
обязательно
Идентификатор ключа API (UUID)
Ответы
200Успешный ответ · KeyResponse
Поля ответа · 17
id
string
обязательно
Идентификатор записи (UUID)
name
string
обязательно
prefix
string
обязательно
Видимое начало ключа: bnt_live_7f3c
status
string
обязательно
active / expiring (меньше 14 дней) / revoked / expired
scopes
массив string
обязательно
Права по разделам
access
object
обязательно
Положения переключателей по разделам
allowed_ips
массив string
обязательно
Адреса и подсети; пусто — с любого адреса
rate_limit_per_min
integer
обязательно
expires_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
created_by
KeyPerson или null
обязательно
last_used_at
string (date-time) или null
обязательно
Последний запрос — с точностью до минуты
last_used_ip
string или null
обязательно
requests_today
integer
обязательно
Запросов за сегодня (UTC)
revoked_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
revoked_by
KeyPerson или null
обязательно
revoked_reason
string или null
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/keys/{key_id}' \
-H 'Authorization: Bearer <access>'
Вебхуки
7 эндпоинтовМы сами сообщаем вашей системе о новой брони, подтверждении, отмене, сообщении гостя и блокировке объекта: адреса, события, секрет подписи, журнал доставок, проверка. Владелец сессией кабинета или ключ с правом webhooks:manage.
GET/v1/webhooks/events
События, на которые можно подписаться, с названиями на языке запроса
Нужен вход
Доступ. владелец сессией кабинета или ключ API с правом webhooks:manage.
Ответы
200Успешный ответ · массив WebhookEvent
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/webhooks/events' \
-H 'Authorization: Bearer <access>'
GET/v1/webhooks
Адреса бизнеса — новые сверху, у каждого пять последних доставок
Нужен вход
Состояние: active, paused (выключен), disabled (остановлен после шести неудач подряд — владельцам ушло письмо). Секрета в списке нет.
Доступ. владелец сессией кабинета или ключ API с правом webhooks:manage.
Ответы
200Успешный ответ · массив WebhookResponse
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/webhooks' \
-H 'Authorization: Bearer <access>'
POST/v1/webhooks
Новый адрес. Секрет подписи в ответе один раз
Нужен вход
Адрес — только https и только публичный: имя проверяется сейчас и перед каждой отправкой (400 validation_error, details.reason: https_only, credentials, not_public). Не больше 10 адресов — 409.
Доступ. владелец сессией кабинета или ключ API с правом webhooks:manage.
Тело запросаWebhookCreate · application/json
url
string
обязательно
Только https и только публичный адрес
events
массив string
обязательно
События из GET /v1/webhooks/events
Ответы
201Успешный ответ · WebhookWithSecret
Поля ответа · 9
id
string
обязательно
Идентификатор записи (UUID)
url
string
обязательно
Адрес
events
массив string
обязательно
status
string
обязательно
active / paused (выключен) / disabled (остановлен после ошибок)
failures_in_row
integer
обязательно
Неудачных попыток подряд
disabled_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
deliveries
массив WebhookDelivery
обязательно
Последние доставки, новые сверху
secret
string
обязательно
bnt_hook_… — ключ HMAC-SHA256 подписи X-Bounty-Signature
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/webhooks' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"url": "…", "events": ["…"]}'
PATCH/v1/webhooks/<span class="text-brand-ink">{hook_id}</span>
Адрес, события, «Выключить»
Нужен вход
(active: false) и «Включить снова» (active: true — счёт неудач обнуляется, доставка продолжается).
Доступ. владелец сессией кабинета или ключ API с правом webhooks:manage.
Параметры
hook_id
путь · string (uuid)
обязательно
Идентификатор вебхука (UUID)
Тело запросаWebhookUpdate · application/json
url
string или null
Адрес
events
массив string или null
active
boolean или null
Ответы
200Успешный ответ · WebhookResponse
Поля ответа · 8
id
string
обязательно
Идентификатор записи (UUID)
url
string
обязательно
Адрес
events
массив string
обязательно
status
string
обязательно
active / paused (выключен) / disabled (остановлен после ошибок)
failures_in_row
integer
обязательно
Неудачных попыток подряд
disabled_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
deliveries
массив WebhookDelivery
обязательно
Последние доставки, новые сверху
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/webhooks/{hook_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"url": "…", "events": ["…"]}'
POST/v1/webhooks/<span class="text-brand-ink">{hook_id}</span>/secret
Новый секрет подписи — один раз в ответе; прежний не действует сразу
Нужен вход
Доступ. владелец сессией кабинета или ключ API с правом webhooks:manage.
Параметры
hook_id
путь · string (uuid)
обязательно
Идентификатор вебхука (UUID)
Ответы
200Успешный ответ · WebhookWithSecret
Поля ответа · 9
id
string
обязательно
Идентификатор записи (UUID)
url
string
обязательно
Адрес
events
массив string
обязательно
status
string
обязательно
active / paused (выключен) / disabled (остановлен после ошибок)
failures_in_row
integer
обязательно
Неудачных попыток подряд
disabled_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
deliveries
массив WebhookDelivery
обязательно
Последние доставки, новые сверху
secret
string
обязательно
bnt_hook_… — ключ HMAC-SHA256 подписи X-Bounty-Signature
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/webhooks/{hook_id}/secret' \
-H 'Authorization: Bearer <access>'
POST/v1/webhooks/<span class="text-brand-ink">{hook_id}</span>/test
«Отправить проверку»: событие ping только этому адресу, за секунды
Нужен вход
Итог — в журнале доставок. Выключенный адрес — 409. Неудачная проверка повторяется, как любое событие, но адрес не останавливает.
Доступ. владелец сессией кабинета или ключ API с правом webhooks:manage.
Параметры
hook_id
путь · string (uuid)
обязательно
Идентификатор вебхука (UUID)
Ответы
202Успешный ответ · WebhookTestResponse
Поля ответа · 1
queued
integer
обязательно
Сколько проверок поставлено — 1
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/webhooks/{hook_id}/test' \
-H 'Authorization: Bearer <access>'
GET/v1/webhooks/<span class="text-brand-ink">{hook_id}</span>/deliveries
Журнал доставок адреса — каждая попытка строкой, новые сверху
Нужен вход
Доступ. владелец сессией кабинета или ключ API с правом webhooks:manage.
Параметры
hook_id
путь · string (uuid)
обязательно
Идентификатор вебхука (UUID)
before
запрос · integer или null
Курсор — next_cursor прошлой страницы
limit
запрос · integer
Сколько записей на странице
Ответы
200Успешный ответ · WebhookDeliveriesPage
Поля ответа · 2
items
массив WebhookDelivery
обязательно
Записи страницы
next_cursor
integer или null
обязательно
Передайте в before, чтобы получить более старые
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/webhooks/{hook_id}/deliveries' \
-H 'Authorization: Bearer <access>'
Анкета бизнеса
5 эндпоинтовАнкета до проверки модератором. Ключу закрыта.
GET/v1/application
Состояние анкеты вместе с требованиями по выбранной тройке
Нужен вход
Требования приходят с названиями: справочник правит супер-админ, и ключа локали у кода, заведённого вчера, не существует.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Ответы
200Успешный ответ · object
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/application' \
-H 'Authorization: Bearer <access>'
PUT/v1/application
Черновик анкеты. Первое сохранение заводит бизнес в статусе draft
Нужен вход
Смена категории или типа пересобирает список требований, а уже загруженные документы остаются: партнёр, ошибшийся типом, не должен заливать всё заново.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Тело запросаApplicationSaveRequest · application/json
business_kind
string или null
country
string или null
partner_type
string или null
kind
string или null
legal_name
string или null
display_name
string или null
Имя для показа
contact_name
string или null
phone
string или null
Телефон в международном виде, +66…
tax_id
string или null
registration_no
string или null
address
string или null
language
string или null
Язык: en, ru, th или zh-Hans
currency
string или null
Код валюты ISO 4217 (THB, RUB, USD…)
timezone
string или null
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
Ответы
200Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/application' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"business_kind": "…", "country": "…"}'
POST/v1/application/documents
Загрузка файла сразу, до отправки анкеты
Нужен вход
Так партнёр видит ход и результат по каждому файлу, а не узнаёт об отказе на восьмом, отправив всё разом.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Тело запросаBody_upload_document_v1_application_documents_post · multipart/form-data
kind
string
обязательно
Код документа из справочника страны
file
string
обязательно
PDF, JPEG, PNG, DOCX или XLSX
Ответы
201Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/application/documents' \
-H 'Authorization: Bearer <access>' \
-F 'file=@photo.jpg'
DELETE/v1/application/documents/<span class="text-brand-ink">{document_id}</span>
Убрать файл из черновика. Мягко
Нужен вход
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Параметры
document_id
путь · string (uuid)
обязательно
Идентификатор документа (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/application/documents/{document_id}' \
-H 'Authorization: Bearer <access>'
POST/v1/application/submit
Отправить заявку модератору
Нужен вход
Неполная не отправляется: 409 application_incomplete со списком того, чего не хватает. Число попыток не ограничено — ограничен темп, иначе очередь модерации забивается одной заявкой.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Ответы
200Успешный ответ · object
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/application/submit' \
-H 'Authorization: Bearer <access>'
Кабинет
8 эндпоинтовПрофиль бизнеса, числа у меню, свои настройки писем и пушей. Ключу доступны профиль и числа; свои настройки — только человеку.
GET/v1/me
Бизнес, его состояние, пояс объектов — и кто именно вошёл
Нужен вход
Блок me кабинет использует, чтобы порезать меню под роль: показывать пункт, на котором человек получит «нет прав», хуже, чем не показывать его вовсе.
Ответы
200Успешный ответ · PartnerProfileResponse
Поля ответа · 30
id
string (uuid)
обязательно
Идентификатор записи (UUID)
business_kind
string
обязательно
stay / experience / service — категория закрепляется навсегда
me
PartnerMeResponse или null
Человек этой сессии; у запроса по API-ключу его нет
status
string
обязательно
kind
string
обязательно
legal_name
string
обязательно
display_name
string
обязательно
Имя для показа
logo_url
string или null
обязательно
about
string или null
обязательно
contact_name
string или null
обязательно
phone
string или null
обязательно
Телефон в международном виде, +66…
country
string или null
обязательно
address
string или null
обязательно
verification_status
string
обязательно
commission_percent
number или null
обязательно
commission_effective_percent
number или null
country_title
string или null
restrictions
массив object
payout_currency
string или null
обязательно
response_rate
number или null
обязательно
response_time_min
integer или null
обязательно
rating_avg
number или null
обязательно
Средняя оценка, от 1 до 5
rating_count
integer
обязательно
Сколько оценок
listings_count
integer
обязательно
Количество
language
string или null
обязательно
Язык: en, ru, th или zh-Hans
currency
string или null
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
timezone
string
обязательно
Пояс объектов партнёра. Все календарные даты — в нём
documents_blocked_at
string (date-time) или null
Витрина погашена: убран обязательный документ
partner_type
string или null
Код типа партнёра из справочника страны
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/me' \
-H 'Authorization: Bearer <access>'
PATCH/v1/me
Язык объявлений, валюта цен, пояс, описание
Нужен вход
Меняет их владелец: это настройки всего бизнеса, и администратор на стойке, переключивший их под себя, заводил бы объекты не на том языке и не в той валюте. Уже заведённые объекты не трогаются — у каждого свой язык оригинала и своя валюта цены. Менять их задним числом значило бы объявить чужой текст переведённым, а старую цену — суммой в другой валюте: число осталось бы прежним, а денег в нём стало бы втрое больше.
Тело запросаBusinessSettingsRequest · application/json
language
string или null
Язык: en, ru, th или zh-Hans
currency
string или null
Код валюты ISO 4217 (THB, RUB, USD…)
timezone
string или null
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
about
string или null
Ответы
200Успешный ответ · PartnerProfileResponse
Поля ответа · 30
id
string (uuid)
обязательно
Идентификатор записи (UUID)
business_kind
string
обязательно
stay / experience / service — категория закрепляется навсегда
me
PartnerMeResponse или null
Человек этой сессии; у запроса по API-ключу его нет
status
string
обязательно
kind
string
обязательно
legal_name
string
обязательно
display_name
string
обязательно
Имя для показа
logo_url
string или null
обязательно
about
string или null
обязательно
contact_name
string или null
обязательно
phone
string или null
обязательно
Телефон в международном виде, +66…
country
string или null
обязательно
address
string или null
обязательно
verification_status
string
обязательно
commission_percent
number или null
обязательно
commission_effective_percent
number или null
country_title
string или null
restrictions
массив object
payout_currency
string или null
обязательно
response_rate
number или null
обязательно
response_time_min
integer или null
обязательно
rating_avg
number или null
обязательно
Средняя оценка, от 1 до 5
rating_count
integer
обязательно
Сколько оценок
listings_count
integer
обязательно
Количество
language
string или null
обязательно
Язык: en, ru, th или zh-Hans
currency
string или null
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
timezone
string
обязательно
Пояс объектов партнёра. Все календарные даты — в нём
documents_blocked_at
string (date-time) или null
Витрина погашена: убран обязательный документ
partner_type
string или null
Код типа партнёра из справочника страны
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/me' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"language": "…", "currency": "…"}'
GET/v1/me/badges
Числа у пунктов меню: заявки, переписки, уведомления
Нужен вход
Кабинет спрашивает их на каждой странице, поэтому ответ лёгкий — три счётчика, а не сводка обзора. Каждое число — по праву роли, как в /v1/overview: закрытое приходит null.
Ответы
200Успешный ответ · BadgesResponse
Поля ответа · 3
bookings
integer или null
обязательно
Заявки, ждущие ответа партнёра (без договоров аренды); null — у роли нет права «Брони · смотреть»
chats
integer или null
обязательно
Переписки с непрочитанными сообщениями гостей; null — нет права «Переписка · смотреть»
notifications
integer
обязательно
Непрочитанные уведомления бизнеса
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/me/badges' \
-H 'Authorization: Bearer <access>'
GET/v1/me/person
Кто вошёл — без бизнеса
Нужен вход
Нужно ровно одному экрану: анкете. У человека, который ещё не прошёл проверку, бизнеса нет вовсе, и GET /v1/me ему отвечает 403 application_required — а кабинету всё равно нужно показать в шапке имя вошедшего, иначе он выглядит чужим.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Ответы
200Успешный ответ · object
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/me/person' \
-H 'Authorization: Bearer <access>'
GET/v1/me/email-prefs
Галочки писем по группам. Чего человек не трогал — по умолчанию из реестра
Нужен вход
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Ответы
200Успешный ответ · EmailPrefsBody
Поля ответа · 1
groups
массив EmailPrefGroup
обязательно
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/me/email-prefs' \
-H 'Authorization: Bearer <access>'
PUT/v1/me/email-prefs
Включить или выключить письма: {"prefs": {"booking.reminder": false}}
Нужен вход
Выключить можно всё, кроме ответов на действие самого человека (подтверждение почты, сброс пароля): их в настройках нет вовсе. Незнакомый код — 400 email_pref_unknown.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Тело запросаEmailPrefsUpdate · application/json
prefs
object
Ответы
200Успешный ответ · EmailPrefsBody
Поля ответа · 1
groups
массив EmailPrefGroup
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/me/email-prefs' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"prefs": {}}'
GET/v1/me/push-prefs
Пуши человека: общий выключатель и галочки — по его правам в бизнесе
Нужен вход
Сотрудник без раздела «Брони» не видит галочек о бронях и не получает таких пушей; анкета и документы бизнеса — только владельцу. Настройки личные: у каждого сотрудника свои.
Ответы
200Успешный ответ · PushPrefsBody
Поля ответа · 3
enabled
boolean
обязательно
Общий выключатель: выключен — не уходит ни один пуш
quiet
QuietHours
обязательно
Свои тихие часы: срочные пуши приходят всегда, остальные — после
groups
массив PushPrefGroup
обязательно
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/me/push-prefs' \
-H 'Authorization: Bearer <access>'
PUT/v1/me/push-prefs
Выключатель, тихие часы и/или галочки: {"enabled": true, "quiet": {"enabled": true, "start": 0, "end": 6}, "prefs": {"booking.created": false}}
Нужен вход
Тихие часы — свои у каждого: не срочные пуши в эти часы ждут утра.
Пуш, не положенный по правам, или незнакомый код — 400 push_pref_unknown.
Тело запросаPushPrefsUpdate · application/json
enabled
boolean или null
Включено ли
quiet
QuietHoursUpdate или null
prefs
object
Ответы
200Успешный ответ · PushPrefsBody
Поля ответа · 3
enabled
boolean
обязательно
Общий выключатель: выключен — не уходит ни один пуш
quiet
QuietHours
обязательно
Свои тихие часы: срочные пуши приходят всегда, остальные — после
groups
массив PushPrefGroup
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/me/push-prefs' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"enabled": false, "quiet": {"enabled": false, "start": 0}}'
Сотрудники
11 эндпоинтовСотрудники, права по разделам и журнал действий — только владельцу.
GET/v1/staff
Люди этого бизнеса: имя, почта, должность, роль, статус, последний вход
Нужен вход
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · массив StaffResponse
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/staff' \
-H 'Authorization: Bearer <access>'
POST/v1/staff
Завести сотрудника с выбранным доступом и пригласить письмом
Нужен вход
Доступ — full_access (совладелец), access по разделам, scopes списком или код образца в role. Человека, который уже работает в другом бизнесе, новый пароль не просят: заводится только членство, а письмо зовёт его в новую организацию.
Доступ. только владелец бизнеса.
Тело запросаStaffCreate · application/json
email
string (email)
обязательно
Адрес почты
full_name
string
обязательно
Имя и фамилия
position
string или null
Порядок показа, с нуля
full_access
boolean
по умолчанию false
Полный доступ — совладелец
access
object или null
Положение по каждому разделу: none / read / write (GET /v1/staff/areas). Не присланный раздел — none
scopes
массив string или null
Набор прав списком скоупов
role
string или null
owner / staff или код образца (manager, reception…)
Ответы
201Успешный ответ · StaffResponse
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
email
string
обязательно
Адрес почты
full_name
string
обязательно
Имя и фамилия
position
string или null
обязательно
Порядок показа, с нуля
role
string
обязательно
owner / staff
role_title
string
обязательно
status
string
обязательно
invited / active / suspended — состояние членства
scopes
массив string
обязательно
Права по разделам
full_access
boolean
обязательно
access
object
обязательно
Положение по каждому разделу бизнеса
invite_pending
boolean
обязательно
Пароль ещё не задан: приглашение не принято
last_login_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/staff' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"email": "anna@example.com", "full_name": "…"}'
GET/v1/staff/areas
Разделы кабинета, на которые выдаётся доступ
Нужен вход
У каждого — положения переключателя: «нет · смотреть · управлять»; у объектов «нет» не бывает, у финансов — «управлять». Подготовка — только у бизнеса, у которого она есть. Панель своего списка не держит: два справочника прав всегда расходятся.
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · массив AreaResponse
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/staff/areas' \
-H 'Authorization: Bearer <access>'
GET/v1/staff/roles
Образцы — прежние роли, которыми форма заполняется разом
Нужен вход
access — положения переключателей, которые образец выставляет.
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · массив RoleResponse
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/staff/roles' \
-H 'Authorization: Bearer <access>'
GET/v1/staff/audit
Кто из сотрудников что сделал (P19b)
Нужен вход
Доступ. только владелец бизнеса.
Список страницами. Ответ отдаёт next_cursor; следующую страницу просите с ним в cursor. has_more: false или нет курсора — список кончился.
Параметры
actor_id
запрос · string (uuid) или null
action
запрос · string или null
limit
запрос · integer или null
Сколько записей на странице
cursor
запрос · string или null
Курсор из next_cursor прошлого ответа; без него — первая страница
Ответы
200Успешный ответ · StaffAuditPage
Поля ответа · 3
items
массив StaffAuditEntry
обязательно
Записи страницы
next_cursor
string или null
обязательно
Курсор следующей страницы: передайте его в cursor. Нет — страница последняя. Непрозрачен: не разбирайте и не собирайте руками
has_more
boolean
обязательно
Есть ли следующая страница
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/staff/audit' \
-H 'Authorization: Bearer <access>'
GET/v1/staff/<span class="text-brand-ink">{person_id}</span>
Карточка сотрудника: должность, права по разделам, состояние, принято ли приглашение, последний вход
Нужен вход
Доступ. только владелец бизнеса.
Параметры
person_id
путь · string (uuid)
обязательно
Идентификатор сотрудника (UUID)
Ответы
200Успешный ответ · StaffResponse
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
email
string
обязательно
Адрес почты
full_name
string
обязательно
Имя и фамилия
position
string или null
обязательно
Порядок показа, с нуля
role
string
обязательно
owner / staff
role_title
string
обязательно
status
string
обязательно
invited / active / suspended — состояние членства
scopes
массив string
обязательно
Права по разделам
full_access
boolean
обязательно
access
object
обязательно
Положение по каждому разделу бизнеса
invite_pending
boolean
обязательно
Пароль ещё не задан: приглашение не принято
last_login_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/staff/{person_id}' \
-H 'Authorization: Bearer <access>'
PATCH/v1/staff/<span class="text-brand-ink">{person_id}</span>
Сменить доступ или должность. Присланный набор заменяет прежний
Нужен вход
Последнего владельца разжаловать нельзя — 409 last_owner; себя лишить полного доступа — 409 conflict.
Доступ. только владелец бизнеса.
Параметры
person_id
путь · string (uuid)
обязательно
Идентификатор сотрудника (UUID)
Тело запросаStaffUpdate · application/json
position
string или null
Порядок показа, с нуля
full_access
boolean или null
access
object или null
Положение по каждому разделу: none / read / write (GET /v1/staff/areas). Не присланный раздел — none
scopes
массив string или null
Права по разделам
role
string или null
Ответы
200Успешный ответ · StaffResponse
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
email
string
обязательно
Адрес почты
full_name
string
обязательно
Имя и фамилия
position
string или null
обязательно
Порядок показа, с нуля
role
string
обязательно
owner / staff
role_title
string
обязательно
status
string
обязательно
invited / active / suspended — состояние членства
scopes
массив string
обязательно
Права по разделам
full_access
boolean
обязательно
access
object
обязательно
Положение по каждому разделу бизнеса
invite_pending
boolean
обязательно
Пароль ещё не задан: приглашение не принято
last_login_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/staff/{person_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"position": "…", "full_access": false}'
DELETE/v1/staff/<span class="text-brand-ink">{person_id}</span>
Убрать из бизнеса — мягко: членство уходит в suspended
Нужен вход
Строка остаётся: без неё журнал действий превратился бы в список неизвестных идентификаторов.
Доступ. только владелец бизнеса.
Параметры
person_id
путь · string (uuid)
обязательно
Идентификатор сотрудника (UUID)
Ответы
200Успешный ответ · StaffResponse
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
email
string
обязательно
Адрес почты
full_name
string
обязательно
Имя и фамилия
position
string или null
обязательно
Порядок показа, с нуля
role
string
обязательно
owner / staff
role_title
string
обязательно
status
string
обязательно
invited / active / suspended — состояние членства
scopes
массив string
обязательно
Права по разделам
full_access
boolean
обязательно
access
object
обязательно
Положение по каждому разделу бизнеса
invite_pending
boolean
обязательно
Пароль ещё не задан: приглашение не принято
last_login_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/staff/{person_id}' \
-H 'Authorization: Bearer <access>'
POST/v1/staff/<span class="text-brand-ink">{person_id}</span>/suspend
Отключить сотрудника. Его сессии в этом бизнесе закрываются немедленно
Нужен вход
Доступ. только владелец бизнеса.
Параметры
person_id
путь · string (uuid)
обязательно
Идентификатор сотрудника (UUID)
Ответы
200Успешный ответ · StaffResponse
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
email
string
обязательно
Адрес почты
full_name
string
обязательно
Имя и фамилия
position
string или null
обязательно
Порядок показа, с нуля
role
string
обязательно
owner / staff
role_title
string
обязательно
status
string
обязательно
invited / active / suspended — состояние членства
scopes
массив string
обязательно
Права по разделам
full_access
boolean
обязательно
access
object
обязательно
Положение по каждому разделу бизнеса
invite_pending
boolean
обязательно
Пароль ещё не задан: приглашение не принято
last_login_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/staff/{person_id}/suspend' \
-H 'Authorization: Bearer <access>'
POST/v1/staff/<span class="text-brand-ink">{person_id}</span>/restore
Вернуть отключённого сотрудника
Нужен вход
Доступ. только владелец бизнеса.
Параметры
person_id
путь · string (uuid)
обязательно
Идентификатор сотрудника (UUID)
Ответы
200Успешный ответ · StaffResponse
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
email
string
обязательно
Адрес почты
full_name
string
обязательно
Имя и фамилия
position
string или null
обязательно
Порядок показа, с нуля
role
string
обязательно
owner / staff
role_title
string
обязательно
status
string
обязательно
invited / active / suspended — состояние членства
scopes
массив string
обязательно
Права по разделам
full_access
boolean
обязательно
access
object
обязательно
Положение по каждому разделу бизнеса
invite_pending
boolean
обязательно
Пароль ещё не задан: приглашение не принято
last_login_at
string (date-time) или null
обязательно
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/staff/{person_id}/restore' \
-H 'Authorization: Bearer <access>'
POST/v1/staff/<span class="text-brand-ink">{person_id}</span>/resend-invite
Выслать приглашение заново
Нужен вход
Доступ. только владелец бизнеса.
Параметры
person_id
путь · string (uuid)
обязательно
Идентификатор сотрудника (UUID)
Ответы
202Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/staff/{person_id}/resend-invite' \
-H 'Authorization: Bearer <access>'
Документы компании
4 эндпоинтаДокументы бизнеса для проверки — только владельцу.
GET/v1/documents
Что загружено и что с ним стало — с названиями из справочника
Нужен вход
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · массив object
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/documents' \
-H 'Authorization: Bearer <access>'
POST/v1/documents
Загрузка документа в приватный бакет и постановка в очередь проверки
Нужен вход
Доступ. только владелец бизнеса.
Тело запросаBody_upload_document_v1_documents_post · multipart/form-data
kind
string
обязательно
Код документа из справочника страны
file
string
обязательно
PDF, JPEG, PNG, DOCX или XLSX
Ответы
201Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/documents' \
-H 'Authorization: Bearer <access>' \
-F 'file=@photo.jpg'
GET/v1/documents/status
Долг по документам: чего не хватает и погашена ли витрина
Нужен вход
Один ответ на два вопроса кабинета: чем заполнить форму загрузки и что показать плашкой на обзоре. Двумя эндпоинтами это было бы двумя запросами за одним и тем же справочником страны.
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · object
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/documents/status' \
-H 'Authorization: Bearer <access>'
DELETE/v1/documents/<span class="text-brand-ink">{document_id}</span>
Мягкое удаление. Проверенный документ не удаляется вовсе
Нужен вход
Отвечает телом, а не 204: убранный обязательный документ гасит витрину бизнеса, и кабинету нужно сказать человеку, что именно произошло, — «объекты скрыты из поиска, пока документ не вернётся».
Доступ. только владелец бизнеса.
Параметры
document_id
путь · string (uuid)
обязательно
Идентификатор документа (UUID)
Ответы
200Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/documents/{document_id}' \
-H 'Authorization: Bearer <access>'
Справочники
5 эндпоинтовМеста, удобства, категории, валюты, пояса.
GET/v1/places
Поиск места для режима «только город»
Нужен вход
Поиск идёт по названию на всех языках сразу, а не только на языке запроса: русскоязычный партнёр в Таиланде наберёт «Patong» латиницей ровно так же часто, как «Патонг».
Параметры
q
запрос · string или null
parent_id
запрос · integer или null
Идентификатор родительской записи (UUID)
level
запрос · string или null
Ответы
200Успешный ответ · массив PlaceItem
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/places' \
-H 'Authorization: Bearer <access>'
GET/v1/amenities
Удобства группами. kind отсекает неподходящие типу объекта
Нужен вход
Параметры
kind
запрос · ListingKind или null
Ответы
200Успешный ответ · массив AmenityItem
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/amenities' \
-H 'Authorization: Bearer <access>'
GET/v1/categories
Категории впечатлений и услуг
Нужен вход
Параметры
kind
запрос · ListingKind или null
Ответы
200Успешный ответ · массив CategoryItem
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/categories' \
-H 'Authorization: Bearer <access>'
GET/v1/currencies
Валюты, в которых можно выставить цену
Нужен вход
Список тот же, что у гостя в вебе, и это не совпадение: цена, выставленная в валюте, которую витрина не умеет показать и пересчитать, — это цена, которую никто не прочтёт.
Ответы
200Успешный ответ · массив CurrencyItem
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/currencies' \
-H 'Authorization: Bearer <access>'
GET/v1/timezones
Часовые пояса стран, где сервис работает, плюс пояс самого бизнеса
Нужен вход
Не весь список IANA: в нём шестьсот записей, и выбирать из них «Азия/ Бангкок» дольше, чем набрать его руками. Берём пояса городов справочника — это ровно те места, где у нас бывают объекты, — и добавляем текущий пояс бизнеса, чтобы выбранное однажды не исчезло из списка.
Ответы
200Успешный ответ · массив string
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/timezones' \
-H 'Authorization: Bearer <access>'
Политики отмены
4 эндпоинтаУсловия отмены и сезонные правила.
GET/v1/cancellation-policies
Условия отмены бизнеса: основная первой, дальше сезонные по датам
Нужен вход
Доступ. Нужно право: listings:read.
Ответы
200Успешный ответ · массив PolicyBody
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/cancellation-policies' \
-H 'Authorization: Bearer <access>'
POST/v1/cancellation-policies
Новая политика: основная (без сезона) или сезонная
Нужен вход
Вторая основная и пересечение сезонов отвечают 409: и то и другое означало бы два разных ответа на вопрос «сколько вернётся сегодня».
Доступ. Нужно право: listings:write.
Тело запросаPolicyRequest · application/json
name
string
обязательно
terms
string или null
rules
массив RuleBody
season_from
integer или null
Начало сезона как MMDD (1220 — 20 декабря). Пусто у основной политики
season_to
integer или null
Ответы
201Успешный ответ · PolicyBody
Поля ответа · 9
id
integer
обязательно
Идентификатор записи (UUID)
name
string или null
terms
string или null
free_days
integer или null
season_from
integer или null
season_to
integer или null
rules
массив RuleBody
по умолчанию []
is_main
boolean
по умолчанию false
is_active
boolean
по умолчанию true
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/cancellation-policies' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"name": "…"}'
PUT/v1/cancellation-policies/<span class="text-brand-ink">{policy_id}</span>
Правка политики. Оформленные брони считаются по своему снимку
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
policy_id
путь · integer
обязательно
Идентификатор политики отмены (UUID)
Тело запросаPolicyRequest · application/json
name
string
обязательно
terms
string или null
rules
массив RuleBody
season_from
integer или null
Начало сезона как MMDD (1220 — 20 декабря). Пусто у основной политики
season_to
integer или null
Ответы
200Успешный ответ · PolicyBody
Поля ответа · 9
id
integer
обязательно
Идентификатор записи (UUID)
name
string или null
terms
string или null
free_days
integer или null
season_from
integer или null
season_to
integer или null
rules
массив RuleBody
по умолчанию []
is_main
boolean
по умолчанию false
is_active
boolean
по умолчанию true
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/cancellation-policies/{policy_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"name": "…"}'
DELETE/v1/cancellation-policies/<span class="text-brand-ink">{policy_id}</span>
Мягкое удаление сезонной политики
Нужен вход
Основную удалить нельзя вовсе: без неё нашлись бы дни, у которых условий отмены нет, и возврат считался бы нулём — молча и не в пользу гостя. Изменить её можно, убрать — нет.
Доступ. Нужно право: listings:write.
Параметры
policy_id
путь · integer
обязательно
Идентификатор политики отмены (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/cancellation-policies/{policy_id}' \
-H 'Authorization: Bearer <access>'
Объекты
14 эндпоинтовОбъекты пяти категорий: создание, правка, публикация, пауза, архив.
GET/v1/listings
Мои объекты. Читать список может и ограниченный партнёр
Нужен вход
Доступ. Нужно право: listings:read.
Список страницами. Ответ отдаёт next_cursor; следующую страницу просите с ним в cursor. has_more: false или нет курсора — список кончился.
Параметры
status
запрос · ListingStatus или null
kind
запрос · ListingKind или null
q
запрос · string или null
limit
запрос · integer или null
Сколько записей на странице
cursor
запрос · string или null
Курсор из next_cursor прошлого ответа; без него — первая страница
Ответы
200Успешный ответ · ListingPage
Поля ответа · 3
items
массив ListingBrief
обязательно
Записи страницы
next_cursor
string или null
Курсор следующей страницы: передайте его в cursor. Нет — страница последняя. Непрозрачен: не разбирайте и не собирайте руками
has_more
boolean
по умолчанию false
Есть ли следующая страница
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings' \
-H 'Authorization: Bearer <access>'
POST/v1/listings
Черновик нового объекта
Нужен вход
Тип не спрашивается: он равен категории бизнеса. Присланный не своей категории отвечает business_kind_mismatch.
Доступ. Нужно право: listings:write.
Тело запросаListingCreate · application/json
kind
ListingKind или null
Не передаётся: тип равен категории бизнеса. Присланный не своей категории отвечает business_kind_mismatch
title
string
обязательно
description
string или null
lang
string или null
Язык названия и описания. Не прислан — берётся язык бизнеса, затем язык его страны, затем английский
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
Как попасть внутрь: квартира, подъезд, этаж, код домофона. Видит только гость с подтверждённой бронью, хранится зашифрованным
public_address
string или null
Адрес для всех: улица, дом, район. Его видят страница объекта, карточки, карта и Bounty AI — без брони. Пустая строка — убрать
currency
string или null
Валюта цены. По умолчанию — валюта бизнеса, затем валюта его страны
max_guests
integer или null
stay
StayFields или null
experience
ExperienceFields или null
service
ServiceFields или null
transport
TransportFields или null
food
FoodFields или null
Ответы
201Успешный ответ · ListingDetail
Поля ответа · 45
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
ListingKind
обязательно
Пять категорий сервиса.
Порядок значений — порядок разделов в интерфейсе, а не важности.
Способности категории (есть ли фонд ресурсов, продаётся ли слотами,
бывают ли контракты) спрашиваются не сравнением с этим перечислением, а
через bounty_core.categories.
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
slug
string
обязательно
Короткое имя для адреса: латиница, цифры, дефис
title
string
обязательно
description
string или null
lang
string
обязательно
Язык: en, ru, th или zh-Hans
business_lang
string или null
photo_translations_enabled
boolean
по умолчанию true
place
PlaceBrief или null
place_path
массив PlaceBrief
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
public_address
string или null
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
Минимум по календарю. Считаем мы, править нельзя
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode
обязательно
guest_details
GuestDetails
по умолчанию "optional"
Спрашивать ли данные гостей заказа — и обязательно ли.
Просьба Никиты 25.09.2026: страховой на экскурсии нужны имя и фамилия,
дата рождения и номер паспорта каждого участника. Вопрос решает **партнёр
по объекту**, а не сервис: у прогулки на лодке страховка есть, у мастер-
класса её нет, и спрашивать паспорт там, где он никому не нужен, значит
собирать чужие документы без причины.
* optional — можно заполнить: поля видны, но пропустить их разрешено.
Так у всех объектов по умолчанию.
* required — обязательно до брони: без данных всех
участников кнопка «Забронировать» не работает, а сервер отказывает
кодом guest_details_required. Оплату они держат по-прежнему — на
случай, если данные стёрли после брони.
* off — «не спрашивать» — снят с выбора: поля имени, даты рождения и паспорта есть у каждого заказа,
вопрос лишь в том, обязательны ли они. Значение осталось в типе базы —
удалять значение перечисления PostgreSQL незачем и небезопасно, — а
миграция 0003 перевела все такие объекты в optional. Прочитанное
откуда-то off ядро понимает как optional (guest_details.mode_of).
requires_verification
boolean
по умолчанию false
required_documents
массив string
Что взять с собой при заселении
rating_avg
number или null
Средняя оценка, от 1 до 5
rating_count
integer
по умолчанию 0
Сколько оценок
reviews_count
integer
по умолчанию 0
Сколько отзывов
views_count
integer
по умолчанию 0
Количество
published_at
string (date-time) или null
Момент в UTC, ISO 8601
moderated_at
string (date-time) или null
Момент в UTC, ISO 8601
reject_reason_code
string или null
reject_reason_title
string или null
reject_comment
string или null
amenities
массив string
photos
массив PhotoResponse
readiness
ReadinessResponse
обязательно
Что мешает опубликовать объявление.
actions
массив string
notices
массив object
archived_at
string (date-time) или null
Момент в UTC, ISO 8601
stay
object или null
experience
object или null
service
object или null
transport
object или null
food
object или null
created_at
string (date-time) или null
Момент в UTC, ISO 8601
updated_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"title": "…"}'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>
Полная карточка своего объекта — и архивного тоже: его читают, чтобы видеть, что было продано, но ничего в нём не меняют
Нужен вход
Доступ. Нужно право: listings:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ListingDetail
Поля ответа · 45
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
ListingKind
обязательно
Пять категорий сервиса.
Порядок значений — порядок разделов в интерфейсе, а не важности.
Способности категории (есть ли фонд ресурсов, продаётся ли слотами,
бывают ли контракты) спрашиваются не сравнением с этим перечислением, а
через bounty_core.categories.
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
slug
string
обязательно
Короткое имя для адреса: латиница, цифры, дефис
title
string
обязательно
description
string или null
lang
string
обязательно
Язык: en, ru, th или zh-Hans
business_lang
string или null
photo_translations_enabled
boolean
по умолчанию true
place
PlaceBrief или null
place_path
массив PlaceBrief
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
public_address
string или null
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
Минимум по календарю. Считаем мы, править нельзя
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode
обязательно
guest_details
GuestDetails
по умолчанию "optional"
Спрашивать ли данные гостей заказа — и обязательно ли.
Просьба Никиты 25.09.2026: страховой на экскурсии нужны имя и фамилия,
дата рождения и номер паспорта каждого участника. Вопрос решает **партнёр
по объекту**, а не сервис: у прогулки на лодке страховка есть, у мастер-
класса её нет, и спрашивать паспорт там, где он никому не нужен, значит
собирать чужие документы без причины.
* optional — можно заполнить: поля видны, но пропустить их разрешено.
Так у всех объектов по умолчанию.
* required — обязательно до брони: без данных всех
участников кнопка «Забронировать» не работает, а сервер отказывает
кодом guest_details_required. Оплату они держат по-прежнему — на
случай, если данные стёрли после брони.
* off — «не спрашивать» — снят с выбора: поля имени, даты рождения и паспорта есть у каждого заказа,
вопрос лишь в том, обязательны ли они. Значение осталось в типе базы —
удалять значение перечисления PostgreSQL незачем и небезопасно, — а
миграция 0003 перевела все такие объекты в optional. Прочитанное
откуда-то off ядро понимает как optional (guest_details.mode_of).
requires_verification
boolean
по умолчанию false
required_documents
массив string
Что взять с собой при заселении
rating_avg
number или null
Средняя оценка, от 1 до 5
rating_count
integer
по умолчанию 0
Сколько оценок
reviews_count
integer
по умолчанию 0
Сколько отзывов
views_count
integer
по умолчанию 0
Количество
published_at
string (date-time) или null
Момент в UTC, ISO 8601
moderated_at
string (date-time) или null
Момент в UTC, ISO 8601
reject_reason_code
string или null
reject_reason_title
string или null
reject_comment
string или null
amenities
массив string
photos
массив PhotoResponse
readiness
ReadinessResponse
обязательно
Что мешает опубликовать объявление.
actions
массив string
notices
массив object
archived_at
string (date-time) или null
Момент в UTC, ISO 8601
stay
object или null
experience
object или null
service
object или null
transport
object или null
food
object или null
created_at
string (date-time) или null
Момент в UTC, ISO 8601
updated_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}' \
-H 'Authorization: Bearer <access>'
PATCH/v1/listings/<span class="text-brand-ink">{listing_id}</span>
Правка — сразу на витрине в любом статусе
Нужен вход
Правка карточки (всё, кроме цен, сборов и сроков) отмечается для окна изменений модератора; ревизий и ожидания проверки больше нет.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаListingUpdate · application/json
title
string или null
description
string или null
lang
string или null
Язык, на котором написаны название и описание. Смена языка обесценивает все переводы объекта: они сделаны с другого оригинала
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
Как попасть внутрь: квартира, подъезд, этаж, код домофона. Видит только гость с подтверждённой бронью, хранится зашифрованным
public_address
string или null
Адрес для всех: улица, дом, район. Его видят страница объекта, карточки, карта и Bounty AI — без брони. Пустая строка — убрать
place_id
integer или null
Район объекта — только из GET /v1/listings/{id}/places-nearby для его точки. Не прислан — район определяется по точке
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string или null
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode или null
guest_details
GuestDetails или null
requires_verification
boolean или null
required_documents
массив string или null
Что взять с собой: коды справочника, неизвестные отбрасываются
stay
StayFields или null
experience
ExperienceFields или null
service
ServiceFields или null
transport
TransportFields или null
food
FoodFields или null
Ответы
200Успешный ответ · UpdateResult
Поля ответа · 3
applied
массив string
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
translations_stale
массив string
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/listings/{listing_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"title": "…", "description": "…"}'
DELETE/v1/listings/<span class="text-brand-ink">{listing_id}</span>
Прежнее имя архива: удаление объекта и есть уход в архив
Нужен вход
Те же правила, что у POST /archive: интеграция, написанная до архива, не должна снимать с продажи опубликованный объект одним запросом.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/listings/{listing_id}' \
-H 'Authorization: Bearer <access>'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/places-nearby
Районы рядом с точкой объекта — для выбора руками
Нужен вход
Ближние первыми, не больше шести и не дальше 15 км. Пустой список — у объекта ещё нет точки.
Доступ. Нужно право: listings:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/places-nearby' \
-H 'Authorization: Bearer <access>'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/readiness
Чего не хватает для публикации
Нужен вход
Отдельным эндпоинтом, потому что кабинет показывает этот список постоянно — на карточке и в списке объектов, — и тянуть ради него всю карточку незачем.
Доступ. Нужно право: listings:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ReadinessResponse
Поля ответа · 2
ok
boolean
обязательно
Успешно ли
problems
массив string
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/readiness' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/publish
Опубликовать объект — сразу, без проверки модератором
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ListingDetail
Поля ответа · 45
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
ListingKind
обязательно
Пять категорий сервиса.
Порядок значений — порядок разделов в интерфейсе, а не важности.
Способности категории (есть ли фонд ресурсов, продаётся ли слотами,
бывают ли контракты) спрашиваются не сравнением с этим перечислением, а
через bounty_core.categories.
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
slug
string
обязательно
Короткое имя для адреса: латиница, цифры, дефис
title
string
обязательно
description
string или null
lang
string
обязательно
Язык: en, ru, th или zh-Hans
business_lang
string или null
photo_translations_enabled
boolean
по умолчанию true
place
PlaceBrief или null
place_path
массив PlaceBrief
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
public_address
string или null
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
Минимум по календарю. Считаем мы, править нельзя
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode
обязательно
guest_details
GuestDetails
по умолчанию "optional"
Спрашивать ли данные гостей заказа — и обязательно ли.
Просьба Никиты 25.09.2026: страховой на экскурсии нужны имя и фамилия,
дата рождения и номер паспорта каждого участника. Вопрос решает **партнёр
по объекту**, а не сервис: у прогулки на лодке страховка есть, у мастер-
класса её нет, и спрашивать паспорт там, где он никому не нужен, значит
собирать чужие документы без причины.
* optional — можно заполнить: поля видны, но пропустить их разрешено.
Так у всех объектов по умолчанию.
* required — обязательно до брони: без данных всех
участников кнопка «Забронировать» не работает, а сервер отказывает
кодом guest_details_required. Оплату они держат по-прежнему — на
случай, если данные стёрли после брони.
* off — «не спрашивать» — снят с выбора: поля имени, даты рождения и паспорта есть у каждого заказа,
вопрос лишь в том, обязательны ли они. Значение осталось в типе базы —
удалять значение перечисления PostgreSQL незачем и небезопасно, — а
миграция 0003 перевела все такие объекты в optional. Прочитанное
откуда-то off ядро понимает как optional (guest_details.mode_of).
requires_verification
boolean
по умолчанию false
required_documents
массив string
Что взять с собой при заселении
rating_avg
number или null
Средняя оценка, от 1 до 5
rating_count
integer
по умолчанию 0
Сколько оценок
reviews_count
integer
по умолчанию 0
Сколько отзывов
views_count
integer
по умолчанию 0
Количество
published_at
string (date-time) или null
Момент в UTC, ISO 8601
moderated_at
string (date-time) или null
Момент в UTC, ISO 8601
reject_reason_code
string или null
reject_reason_title
string или null
reject_comment
string или null
amenities
массив string
photos
массив PhotoResponse
readiness
ReadinessResponse
обязательно
Что мешает опубликовать объявление.
actions
массив string
notices
массив object
archived_at
string (date-time) или null
Момент в UTC, ISO 8601
stay
object или null
experience
object или null
service
object или null
transport
object или null
food
object или null
created_at
string (date-time) или null
Момент в UTC, ISO 8601
updated_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/publish' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/submit
Прежнее имя публикации — «отправить на модерацию», пока проверка была
Нужен вход
Делает ровно то же, что publish: интеграция, написанная по прежнему контракту, не должна сломаться оттого, что проверки больше нет.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ListingDetail
Поля ответа · 45
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
ListingKind
обязательно
Пять категорий сервиса.
Порядок значений — порядок разделов в интерфейсе, а не важности.
Способности категории (есть ли фонд ресурсов, продаётся ли слотами,
бывают ли контракты) спрашиваются не сравнением с этим перечислением, а
через bounty_core.categories.
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
slug
string
обязательно
Короткое имя для адреса: латиница, цифры, дефис
title
string
обязательно
description
string или null
lang
string
обязательно
Язык: en, ru, th или zh-Hans
business_lang
string или null
photo_translations_enabled
boolean
по умолчанию true
place
PlaceBrief или null
place_path
массив PlaceBrief
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
public_address
string или null
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
Минимум по календарю. Считаем мы, править нельзя
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode
обязательно
guest_details
GuestDetails
по умолчанию "optional"
Спрашивать ли данные гостей заказа — и обязательно ли.
Просьба Никиты 25.09.2026: страховой на экскурсии нужны имя и фамилия,
дата рождения и номер паспорта каждого участника. Вопрос решает **партнёр
по объекту**, а не сервис: у прогулки на лодке страховка есть, у мастер-
класса её нет, и спрашивать паспорт там, где он никому не нужен, значит
собирать чужие документы без причины.
* optional — можно заполнить: поля видны, но пропустить их разрешено.
Так у всех объектов по умолчанию.
* required — обязательно до брони: без данных всех
участников кнопка «Забронировать» не работает, а сервер отказывает
кодом guest_details_required. Оплату они держат по-прежнему — на
случай, если данные стёрли после брони.
* off — «не спрашивать» — снят с выбора: поля имени, даты рождения и паспорта есть у каждого заказа,
вопрос лишь в том, обязательны ли они. Значение осталось в типе базы —
удалять значение перечисления PostgreSQL незачем и небезопасно, — а
миграция 0003 перевела все такие объекты в optional. Прочитанное
откуда-то off ядро понимает как optional (guest_details.mode_of).
requires_verification
boolean
по умолчанию false
required_documents
массив string
Что взять с собой при заселении
rating_avg
number или null
Средняя оценка, от 1 до 5
rating_count
integer
по умолчанию 0
Сколько оценок
reviews_count
integer
по умолчанию 0
Сколько отзывов
views_count
integer
по умолчанию 0
Количество
published_at
string (date-time) или null
Момент в UTC, ISO 8601
moderated_at
string (date-time) или null
Момент в UTC, ISO 8601
reject_reason_code
string или null
reject_reason_title
string или null
reject_comment
string или null
amenities
массив string
photos
массив PhotoResponse
readiness
ReadinessResponse
обязательно
Что мешает опубликовать объявление.
actions
массив string
notices
массив object
archived_at
string (date-time) или null
Момент в UTC, ISO 8601
stay
object или null
experience
object или null
service
object или null
transport
object или null
food
object или null
created_at
string (date-time) или null
Момент в UTC, ISO 8601
updated_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/submit' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/pause
Снять с показа, не удаляя
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ListingDetail
Поля ответа · 45
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
ListingKind
обязательно
Пять категорий сервиса.
Порядок значений — порядок разделов в интерфейсе, а не важности.
Способности категории (есть ли фонд ресурсов, продаётся ли слотами,
бывают ли контракты) спрашиваются не сравнением с этим перечислением, а
через bounty_core.categories.
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
slug
string
обязательно
Короткое имя для адреса: латиница, цифры, дефис
title
string
обязательно
description
string или null
lang
string
обязательно
Язык: en, ru, th или zh-Hans
business_lang
string или null
photo_translations_enabled
boolean
по умолчанию true
place
PlaceBrief или null
place_path
массив PlaceBrief
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
public_address
string или null
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
Минимум по календарю. Считаем мы, править нельзя
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode
обязательно
guest_details
GuestDetails
по умолчанию "optional"
Спрашивать ли данные гостей заказа — и обязательно ли.
Просьба Никиты 25.09.2026: страховой на экскурсии нужны имя и фамилия,
дата рождения и номер паспорта каждого участника. Вопрос решает **партнёр
по объекту**, а не сервис: у прогулки на лодке страховка есть, у мастер-
класса её нет, и спрашивать паспорт там, где он никому не нужен, значит
собирать чужие документы без причины.
* optional — можно заполнить: поля видны, но пропустить их разрешено.
Так у всех объектов по умолчанию.
* required — обязательно до брони: без данных всех
участников кнопка «Забронировать» не работает, а сервер отказывает
кодом guest_details_required. Оплату они держат по-прежнему — на
случай, если данные стёрли после брони.
* off — «не спрашивать» — снят с выбора: поля имени, даты рождения и паспорта есть у каждого заказа,
вопрос лишь в том, обязательны ли они. Значение осталось в типе базы —
удалять значение перечисления PostgreSQL незачем и небезопасно, — а
миграция 0003 перевела все такие объекты в optional. Прочитанное
откуда-то off ядро понимает как optional (guest_details.mode_of).
requires_verification
boolean
по умолчанию false
required_documents
массив string
Что взять с собой при заселении
rating_avg
number или null
Средняя оценка, от 1 до 5
rating_count
integer
по умолчанию 0
Сколько оценок
reviews_count
integer
по умолчанию 0
Сколько отзывов
views_count
integer
по умолчанию 0
Количество
published_at
string (date-time) или null
Момент в UTC, ISO 8601
moderated_at
string (date-time) или null
Момент в UTC, ISO 8601
reject_reason_code
string или null
reject_reason_title
string или null
reject_comment
string или null
amenities
массив string
photos
массив PhotoResponse
readiness
ReadinessResponse
обязательно
Что мешает опубликовать объявление.
actions
массив string
notices
массив object
archived_at
string (date-time) или null
Момент в UTC, ISO 8601
stay
object или null
experience
object или null
service
object или null
transport
object или null
food
object или null
created_at
string (date-time) или null
Момент в UTC, ISO 8601
updated_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/pause' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/resume
Вернуть в показ
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ListingDetail
Поля ответа · 45
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
ListingKind
обязательно
Пять категорий сервиса.
Порядок значений — порядок разделов в интерфейсе, а не важности.
Способности категории (есть ли фонд ресурсов, продаётся ли слотами,
бывают ли контракты) спрашиваются не сравнением с этим перечислением, а
через bounty_core.categories.
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
slug
string
обязательно
Короткое имя для адреса: латиница, цифры, дефис
title
string
обязательно
description
string или null
lang
string
обязательно
Язык: en, ru, th или zh-Hans
business_lang
string или null
photo_translations_enabled
boolean
по умолчанию true
place
PlaceBrief или null
place_path
массив PlaceBrief
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
public_address
string или null
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
Минимум по календарю. Считаем мы, править нельзя
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode
обязательно
guest_details
GuestDetails
по умолчанию "optional"
Спрашивать ли данные гостей заказа — и обязательно ли.
Просьба Никиты 25.09.2026: страховой на экскурсии нужны имя и фамилия,
дата рождения и номер паспорта каждого участника. Вопрос решает **партнёр
по объекту**, а не сервис: у прогулки на лодке страховка есть, у мастер-
класса её нет, и спрашивать паспорт там, где он никому не нужен, значит
собирать чужие документы без причины.
* optional — можно заполнить: поля видны, но пропустить их разрешено.
Так у всех объектов по умолчанию.
* required — обязательно до брони: без данных всех
участников кнопка «Забронировать» не работает, а сервер отказывает
кодом guest_details_required. Оплату они держат по-прежнему — на
случай, если данные стёрли после брони.
* off — «не спрашивать» — снят с выбора: поля имени, даты рождения и паспорта есть у каждого заказа,
вопрос лишь в том, обязательны ли они. Значение осталось в типе базы —
удалять значение перечисления PostgreSQL незачем и небезопасно, — а
миграция 0003 перевела все такие объекты в optional. Прочитанное
откуда-то off ядро понимает как optional (guest_details.mode_of).
requires_verification
boolean
по умолчанию false
required_documents
массив string
Что взять с собой при заселении
rating_avg
number или null
Средняя оценка, от 1 до 5
rating_count
integer
по умолчанию 0
Сколько оценок
reviews_count
integer
по умолчанию 0
Сколько отзывов
views_count
integer
по умолчанию 0
Количество
published_at
string (date-time) или null
Момент в UTC, ISO 8601
moderated_at
string (date-time) или null
Момент в UTC, ISO 8601
reject_reason_code
string или null
reject_reason_title
string или null
reject_comment
string или null
amenities
массив string
photos
массив PhotoResponse
readiness
ReadinessResponse
обязательно
Что мешает опубликовать объявление.
actions
массив string
notices
массив object
archived_at
string (date-time) или null
Момент в UTC, ISO 8601
stay
object или null
experience
object или null
service
object или null
transport
object или null
food
object или null
created_at
string (date-time) или null
Момент в UTC, ISO 8601
updated_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/resume' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/archive
В архив — конечное состояние
Нужен вход
Только из черновика, паузы и «отклонён»; опубликованный — 422 listing_not_archivable, заблокированный — 422 listing_blocked. Из архива объект не возвращается ничем.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ListingDetail
Поля ответа · 45
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
ListingKind
обязательно
Пять категорий сервиса.
Порядок значений — порядок разделов в интерфейсе, а не важности.
Способности категории (есть ли фонд ресурсов, продаётся ли слотами,
бывают ли контракты) спрашиваются не сравнением с этим перечислением, а
через bounty_core.categories.
status
ListingStatus
обязательно
Жизненный цикл объекта.
Модерации до публикации нет: черновик публикуется сразу, а
blocked ставит модератор, увидев нарушение в окне изменений. Вернуть
заблокированный объект на показ может только он.
pending и rejected больше не выдаются — объекты на проверке
опубликованы миграцией 0004, отклонённые возвращены в черновики. Значения
остались, потому что из типа базы их не убрать, а старые записи аудита и
журнала ссылаются на них словами.
slug
string
обязательно
Короткое имя для адреса: латиница, цифры, дефис
title
string
обязательно
description
string или null
lang
string
обязательно
Язык: en, ru, th или zh-Hans
business_lang
string или null
photo_translations_enabled
boolean
по умолчанию true
place
PlaceBrief или null
place_path
массив PlaceBrief
lat
number или null
Широта, градусы WGS 84
lon
number или null
Долгота, градусы WGS 84
address
string или null
public_address
string или null
max_guests
integer или null
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
Минимум по календарю. Считаем мы, править нельзя
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
booking_mode
BookingMode
обязательно
guest_details
GuestDetails
по умолчанию "optional"
Спрашивать ли данные гостей заказа — и обязательно ли.
Просьба Никиты 25.09.2026: страховой на экскурсии нужны имя и фамилия,
дата рождения и номер паспорта каждого участника. Вопрос решает **партнёр
по объекту**, а не сервис: у прогулки на лодке страховка есть, у мастер-
класса её нет, и спрашивать паспорт там, где он никому не нужен, значит
собирать чужие документы без причины.
* optional — можно заполнить: поля видны, но пропустить их разрешено.
Так у всех объектов по умолчанию.
* required — обязательно до брони: без данных всех
участников кнопка «Забронировать» не работает, а сервер отказывает
кодом guest_details_required. Оплату они держат по-прежнему — на
случай, если данные стёрли после брони.
* off — «не спрашивать» — снят с выбора: поля имени, даты рождения и паспорта есть у каждого заказа,
вопрос лишь в том, обязательны ли они. Значение осталось в типе базы —
удалять значение перечисления PostgreSQL незачем и небезопасно, — а
миграция 0003 перевела все такие объекты в optional. Прочитанное
откуда-то off ядро понимает как optional (guest_details.mode_of).
requires_verification
boolean
по умолчанию false
required_documents
массив string
Что взять с собой при заселении
rating_avg
number или null
Средняя оценка, от 1 до 5
rating_count
integer
по умолчанию 0
Сколько оценок
reviews_count
integer
по умолчанию 0
Сколько отзывов
views_count
integer
по умолчанию 0
Количество
published_at
string (date-time) или null
Момент в UTC, ISO 8601
moderated_at
string (date-time) или null
Момент в UTC, ISO 8601
reject_reason_code
string или null
reject_reason_title
string или null
reject_comment
string или null
amenities
массив string
photos
массив PhotoResponse
readiness
ReadinessResponse
обязательно
Что мешает опубликовать объявление.
actions
массив string
notices
массив object
archived_at
string (date-time) или null
Момент в UTC, ISO 8601
stay
object или null
experience
object или null
service
object или null
transport
object или null
food
object или null
created_at
string (date-time) или null
Момент в UTC, ISO 8601
updated_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/archive' \
-H 'Authorization: Bearer <access>'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/revisions
История правок и решения модератора
Нужен вход
Доступ. Нужно право: listings:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · массив RevisionResponse
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/revisions' \
-H 'Authorization: Bearer <access>'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/amenities
Полная замена списка удобств
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаAmenitiesRequest · application/json
codes
массив string
Ответы
200Успешный ответ · массив string
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/amenities' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"codes": ["…"]}'
Фотографии
7 эндпоинтовФотографии объекта: загрузка, порядок, подписи.
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/photos
Фотографии объекта по порядку; первая — обложка
Нужен вход
Доступ. Нужно право: listings:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · массив PhotoResponse
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/photos' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/photos
Загрузка пачкой
Нужен вход
Размер каждого файла проверяется до обработки: смысла декодировать стомегабайтный файл, чтобы затем его отклонить, нет.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаBody_upload_photos_v1_listings__listing_id__photos_post · multipart/form-data
files
массив string
обязательно
До 10 изображений за раз
Ответы
201Успешный ответ · PhotoUploadResult
Поля ответа · 2
photos
массив PhotoResponse
обязательно
rejected
массив object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/photos' \
-H 'Authorization: Bearer <access>' \
-F 'file=@photo.jpg'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/photos/order
Новый порядок; первый становится обложкой
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаPhotoOrderRequest · application/json
ids
массив string (uuid)
обязательно
Ответы
200Успешный ответ · массив PhotoResponse
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/photos/order' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"ids": ["00000000-0000-0000-0000-000000000000"]}'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/photo-translations/enabled
Переводить ли подписи под фотографиями
Нужен вход
Снятая галочка означает «переводов подписей нет вовсе»: их не создаст ни отправка на модерацию, ни кнопка обновления. Уже готовые переводы при этом не удаляются — они просто перестают обновляться.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаPhotoTranslationsToggle · application/json
enabled
boolean
обязательно
Включено ли
Ответы
200Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/photo-translations/enabled' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"enabled": false}'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/photo-translations
Обновить переводы подписей, не дожидаясь модерации
Нужен вход
Работает, только если есть что обновлять: подпись изменилась или её ещё не переводили. Ничего не изменилось — отвечаем {"queued": 0}, и это не ошибка, а честный ответ «работы нет».
При снятой галочке не делает ничего: 409 photo_translations_disabled.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
202Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/photo-translations' \
-H 'Authorization: Bearer <access>'
PATCH/v1/photos/<span class="text-brand-ink">{photo_id}</span>
Подпись, комната, позиция
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
photo_id
путь · string (uuid)
обязательно
Идентификатор фотографии (UUID)
Тело запросаPhotoUpdate · application/json
position
integer или null
Порядок показа, с нуля
caption
string или null
Ответы
200Успешный ответ · PhotoResponse
Поля ответа · 8
id
string (uuid)
обязательно
Идентификатор записи (UUID)
position
integer
обязательно
Порядок показа, с нуля
urls
object
обязательно
width
integer или null
Ширина, px
height
integer или null
Высота, px
avg_color
string или null
caption
string или null
captions
object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/photos/{photo_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"position": 0, "caption": "…"}'
DELETE/v1/photos/<span class="text-brand-ink">{photo_id}</span>
Мягкое удаление; файлы в хранилище остаются
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
photo_id
путь · string (uuid)
обязательно
Идентификатор фотографии (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/photos/{photo_id}' \
-H 'Authorization: Bearer <access>'
Языки объявления
6 эндпоинтовПереводы описания и их этапы.
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/translations
Состояние перевода по каждому языку
Нужен вход
Читать может и ограниченный партнёр: ограничение — это запрет действовать, а не запрет видеть своё.
Доступ. Нужно право: listings:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · TranslationsResponse
Поля ответа · 12
original_lang
string или null
Язык, на котором текст написан автором
enabled
boolean
по умолчанию true
Включено ли
langs
массив TranslationRow
Языки: en, ru, th, zh-Hans
queue
TranslationQueue или null
active
boolean
по умолчанию false
rates_lang
string или null
captions_enabled
boolean
по умолчанию true
langs_all
массив string
rates
массив RateTranslations
extras
массив ExtraTranslations
photos
массив PhotoTranslations
attention
integer
по умолчанию 0
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/translations' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/translations
Поставить перевод в очередь
Нужен вход
202, а не 200: перевод делает воркер, и держать на нём ответ партнёру нельзя — запрос к модели занимает секунды.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаTranslationEnqueue · application/json
langs
массив string
Языки: en, ru, th, zh-Hans
Ответы
202Успешный ответ · TranslationQueued
Поля ответа · 3
queued
массив string
job_id
integer или null
Идентификатор задачи (UUID)
captions
integer
по умолчанию 0
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/translations' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"langs": ["…"]}'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/translations/<span class="text-brand-ink">{lang_code}</span>/enabled
Снять галочку с языка или вернуть её
Нужен вход
Все языки включены по умолчанию, и выбирать «какие включить» партнёру не нужно — он только отказывается от лишних. Отказ ничего не удаляет: готовый перевод остаётся в базе и вернётся вместе с галочкой.
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
lang_code
путь · string
обязательно
Тело запросаLanguageToggle · application/json
enabled
boolean
обязательно
Включено ли
Ответы
200Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/translations/{lang_code}/enabled' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"enabled": false}'
PATCH/v1/listings/<span class="text-brand-ink">{listing_id}</span>/translations/<span class="text-brand-ink">{lang_code}</span>
Своя версия перевода. После неё машина этот язык не трогает
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
lang_code
путь · string
обязательно
Тело запросаTranslationRequest · application/json
title
string или null
description
string или null
house_rules
string или null
meeting_point
string или null
Ответы
200Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/listings/{listing_id}/translations/{lang_code}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"title": "…", "description": "…"}'
DELETE/v1/listings/<span class="text-brand-ink">{listing_id}</span>/translations/<span class="text-brand-ink">{lang_code}</span>
Убрать перевод: гостю с этим языком показывается оригинал
Нужен вход
Доступ. Нужно право: listings:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
lang_code
путь · string
обязательно
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/listings/{listing_id}/translations/{lang_code}' \
-H 'Authorization: Bearer <access>'
GET/v1/translations/history
История переводов бизнеса, новые сверху
Нужен вход
Строка — один перевод: текст до, текст после, язык, когда и куда смотреть.
Исходный текст показывается текущий, а не тот, что был в момент перевода: мы его не храним, в строке лежит только отпечаток. У устаревшего перевода слева поэтому будет уже новый текст партнёра — и это видно по состоянию stale, что честнее выдуманного.
Доступ. Нужно право: listings:read.
Список страницами. Ответ отдаёт next_cursor; следующую страницу просите с ним в cursor. has_more: false или нет курсора — список кончился.
Параметры
listing_id
запрос · string (uuid) или null
Идентификатор объекта (UUID)
kind
запрос · string или null
listing / photo / seo / message
limit
запрос · integer
Сколько записей на странице
cursor
запрос · string или null
Курсор из next_cursor прошлого ответа; без него — первая страница
Ответы
200Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/translations/history' \
-H 'Authorization: Bearer <access>'
Календарь и цены
26 эндпоинтовСвободные и закрытые даты, цена по дням, правила цен, тарифы, доплаты, выходы. Даты — календарные, в поясе объекта; правка диапазонами — с Idempotency-Key.
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/availability
Календарь объекта: статус, цена и минимальный срок каждого дня
Нужен вход
Доступ. Нужно право: calendar:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
from
запрос · string (date)
обязательно
to
запрос · string (date)
обязательно
Ответы
200Успешный ответ · CalendarResponse
Поля ответа · 7
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
timezone
string
обязательно
Пояс объекта: все даты календаря — в нём
today
string (date) или null
Сегодня в поясе объекта
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
base_price_minor
integer или null
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
units_total
integer
по умолчанию 1
Размер номерного фонда объекта
days
массив CalendarDay
обязательно
Дни — календарные даты в поясе объекта
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/availability' \
-H 'Authorization: Bearer <access>'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/availability
Массовая правка диапазонов. Даты под бронью — 409
Нужен вход
Доступ. Нужно право: calendar:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Тело запросаCalendarUpdate · application/json
ranges
массив CalendarRange
обязательно
Ответы
200Успешный ответ · CalendarUpdateResult
Поля ответа · 3
updated
integer
обязательно
days
integer
обязательно
Дни — календарные даты в поясе объекта
price_from_minor
integer или null
Пересчитанная «цена от» для ленты и карты
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/availability' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"ranges": [{}]}'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/pricing
Базовая цена, сборы и все правила объекта
Нужен вход
Доступ. Нужно право: pricing:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · PricingResponse
Поля ответа · 18
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
base_price_minor
integer или null
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
rules
массив PriceRuleResponse
обязательно
rates
массив RateResponse
по умолчанию []
extras
массив ExtraResponse
по умолчанию []
extras_supported
boolean
по умолчанию false
rates_lang
string
по умолчанию "en"
rates_langs
массив string
по умолчанию []
rules_supported
boolean
по умолчанию true
base_price_supported
boolean
по умолчанию true
cleaning_fee_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
deposit_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
extra_guest_fee_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
base_guests
integer или null
min_nights
integer или null
Наименьшее число ночей брони
max_nights
integer или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/pricing' \
-H 'Authorization: Bearer <access>'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/pricing
Правит базовую цену и сборы. На модерацию цена не идёт
Нужен вход
Доступ. Нужно право: pricing:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Тело запросаPricingUpdate · application/json
base_price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string или null
Код валюты ISO 4217 (THB, RUB, USD…)
cleaning_fee_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
deposit_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
extra_guest_fee_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
base_guests
integer или null
min_nights
integer или null
Наименьшее число ночей брони
max_nights
integer или null
Ответы
200Успешный ответ · PricingResponse
Поля ответа · 18
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
base_price_minor
integer или null
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
price_from_minor
integer или null
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
rules
массив PriceRuleResponse
обязательно
rates
массив RateResponse
по умолчанию []
extras
массив ExtraResponse
по умолчанию []
extras_supported
boolean
по умолчанию false
rates_lang
string
по умолчанию "en"
rates_langs
массив string
по умолчанию []
rules_supported
boolean
по умолчанию true
base_price_supported
boolean
по умолчанию true
cleaning_fee_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
deposit_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
extra_guest_fee_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
base_guests
integer или null
min_nights
integer или null
Наименьшее число ночей брони
max_nights
integer или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/pricing' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"base_price_minor": 0, "currency": "…"}'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/price-rules
Правила цены объекта: сезоны, выходные, скидки за длительность, раннее и позднее бронирование
Нужен вход
Доступ. Нужно право: pricing:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · массив PriceRuleResponse
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/price-rules' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/price-rules
Заводит правило цены: сезон, выходные, скидку, доплату
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаPriceRuleBody · application/json
kind
PriceRuleKind
обязательно
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
dow_mask
integer или null
Дни недели битами: понедельник — 1, вторник — 2, … воскресенье — 64
min_nights
integer или null
Наименьшее число ночей брони
days_before
integer или null
mode
PriceMode
по умолчанию "percent"
value
number
обязательно
Плюс — наценка, минус — скидка
priority
integer
по умолчанию 0
Ответы
201Успешный ответ · PriceRuleResponse
Поля ответа · 10
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
string
обязательно
date_from
string (date) или null
обязательно
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
обязательно
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
dow_mask
integer или null
обязательно
Дни недели битами: понедельник — 1, вторник — 2, … воскресенье — 64
min_nights
integer или null
обязательно
Наименьшее число ночей брони
days_before
integer или null
обязательно
mode
string
обязательно
value
number
обязательно
priority
integer
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/price-rules' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"kind": "season", "value": 0.0}'
PATCH/v1/price-rules/<span class="text-brand-ink">{rule_id}</span>
Изменить правило цены. Меняются только присланные поля
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
rule_id
путь · string (uuid)
обязательно
Тело запросаPriceRuleUpdate · application/json
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
dow_mask
integer или null
Дни недели битами: понедельник — 1, вторник — 2, … воскресенье — 64
min_nights
integer или null
Наименьшее число ночей брони
days_before
integer или null
mode
PriceMode или null
value
number или null
priority
integer или null
Ответы
200Успешный ответ · PriceRuleResponse
Поля ответа · 10
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
string
обязательно
date_from
string (date) или null
обязательно
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
обязательно
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
dow_mask
integer или null
обязательно
Дни недели битами: понедельник — 1, вторник — 2, … воскресенье — 64
min_nights
integer или null
обязательно
Наименьшее число ночей брони
days_before
integer или null
обязательно
mode
string
обязательно
value
number
обязательно
priority
integer
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/price-rules/{rule_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"date_from": "2026-11-02", "date_to": "2026-11-02"}'
DELETE/v1/price-rules/<span class="text-brand-ink">{rule_id}</span>
Убрать правило цены. Цены уже созданных броней не меняются
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
rule_id
путь · string (uuid)
обязательно
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/price-rules/{rule_id}' \
-H 'Authorization: Bearer <access>'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/rates
Тарифы объекта: «взрослый 800», «ребёнок 600», «всё включено 1200»
Нужен вход
Доступ. Нужно право: pricing:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · массив RateResponse
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/rates' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/rates
Заводит тариф. Первый тариф объекта сам становится базовым
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаRateCreate · application/json
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
is_base
boolean
по умолчанию false
code
string или null
Ответы
201Успешный ответ · RateResponse
Поля ответа · 7
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
is_base
boolean
обязательно
sort
integer
обязательно
translations
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/rates' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"title": "…", "price_minor": 0}'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/rates/translate
Переводит названия тарифов машиной — все разом, одним запросом
Нужен вход
Переводы, поправленные партнёром руками, не трогаются: иначе следующая же кнопка вернула бы их к машинному варианту.
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаRatesTranslateRequest · application/json
langs
массив string или null
Языки: en, ru, th, zh-Hans
Ответы
200Успешный ответ · RatesTranslated
Поля ответа · 3
translated
integer
обязательно
langs
массив string
по умолчанию []
Языки: en, ru, th, zh-Hans
rejected
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/rates/translate' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"langs": ["…"]}'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/rates/<span class="text-brand-ink">{rate_id}</span>/translation
Правка перевода названия руками. Машина его больше не трогает
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
rate_id
путь · string (uuid)
обязательно
Идентификатор тарифа (UUID)
Тело запросаRateTranslationBody · application/json
lang
string
обязательно
Язык: en, ru, th или zh-Hans
title
string
обязательно
Ответы
200Успешный ответ · RateResponse
Поля ответа · 7
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
is_base
boolean
обязательно
sort
integer
обязательно
translations
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/rates/{rate_id}/translation' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"lang": "…", "title": "…"}'
PATCH/v1/listings/<span class="text-brand-ink">{listing_id}</span>/rates/<span class="text-brand-ink">{rate_id}</span>
Изменить тариф объекта. Меняются только присланные поля
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
rate_id
путь · string (uuid)
обязательно
Идентификатор тарифа (UUID)
Тело запросаRateUpdate · application/json
title
string или null
price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
is_base
boolean или null
sort
integer или null
Ответы
200Успешный ответ · RateResponse
Поля ответа · 7
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
is_base
boolean
обязательно
sort
integer
обязательно
translations
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/listings/{listing_id}/rates/{rate_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"title": "…", "price_minor": 0}'
DELETE/v1/listings/<span class="text-brand-ink">{listing_id}</span>/rates/<span class="text-brand-ink">{rate_id}</span>
Убирает тариф из продажи. Базовый так не убирается — 409
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
rate_id
путь · string (uuid)
обязательно
Идентификатор тарифа (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/listings/{listing_id}/rates/{rate_id}' \
-H 'Authorization: Bearer <access>'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/extras
Доп. услуги объекта: трансфер, обеды. У жилья, проката и еды — пусто
Нужен вход
Доступ. Нужно право: pricing:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · массив ExtraResponse
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/extras' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/extras
Заводит доп. услугу. У категории без услуг — 409 extras_not_supported
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаExtraCreate · application/json
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
per_unit
boolean
по умолчанию false
Цена за единицу, а не за всё
max_qty
integer
по умолчанию 1
Наибольшее количество
Ответы
201Успешный ответ · ExtraResponse
Поля ответа · 8
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
per_unit
boolean
обязательно
Цена за единицу, а не за всё
max_qty
integer
обязательно
Наибольшее количество
sort
integer
обязательно
translations
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/extras' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"title": "…", "price_minor": 0}'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/extras/translate
Переводит машиной недостающие названия услуг. Правку руками не трогает
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаRatesTranslateRequest · application/json
langs
массив string или null
Языки: en, ru, th, zh-Hans
Ответы
200Успешный ответ · RatesTranslated
Поля ответа · 3
translated
integer
обязательно
langs
массив string
по умолчанию []
Языки: en, ru, th, zh-Hans
rejected
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/extras/translate' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"langs": ["…"]}'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/extras/<span class="text-brand-ink">{extra_id}</span>/translation
Правка перевода названия руками. Машина его больше не трогает
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
extra_id
путь · string (uuid)
обязательно
Тело запросаRateTranslationBody · application/json
lang
string
обязательно
Язык: en, ru, th или zh-Hans
title
string
обязательно
Ответы
200Успешный ответ · ExtraResponse
Поля ответа · 8
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
per_unit
boolean
обязательно
Цена за единицу, а не за всё
max_qty
integer
обязательно
Наибольшее количество
sort
integer
обязательно
translations
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/extras/{extra_id}/translation' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"lang": "…", "title": "…"}'
PATCH/v1/listings/<span class="text-brand-ink">{listing_id}</span>/extras/<span class="text-brand-ink">{extra_id}</span>
Правит услугу. Проданные брони это не трогает: у них своя копия
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
extra_id
путь · string (uuid)
обязательно
Тело запросаExtraUpdate · application/json
title
string или null
price_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
per_unit
boolean или null
Цена за единицу, а не за всё
max_qty
integer или null
Наибольшее количество
sort
integer или null
Ответы
200Успешный ответ · ExtraResponse
Поля ответа · 8
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
title
string
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
per_unit
boolean
обязательно
Цена за единицу, а не за всё
max_qty
integer
обязательно
Наибольшее количество
sort
integer
обязательно
translations
object
по умолчанию {}
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/listings/{listing_id}/extras/{extra_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"title": "…", "price_minor": 0}'
DELETE/v1/listings/<span class="text-brand-ink">{listing_id}</span>/extras/<span class="text-brand-ink">{extra_id}</span>
Убирает услугу из продажи. Строка остаётся
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
extra_id
путь · string (uuid)
обязательно
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/listings/{listing_id}/extras/{extra_id}' \
-H 'Authorization: Bearer <access>'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/slots
Выходы впечатления или окна услуги за период — с бронями каждого
Нужен вход
Снятые выходы по умолчанию не приходят: сетку заводят на сезон и снимают пачкой, и половина списка оказывалась про то, чего уже нет. Терять их тоже нельзя — по ним объясняют, почему отменилась бронь.
Доступ. Нужно право: calendar:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
from
запрос · string (date)
обязательно
to
запрос · string (date)
обязательно
cancelled
запрос · boolean
Показывать снятые выходы. По умолчанию нет: сетку заводят на сезон и снимают пачкой, и половина списка оказывалась про то, чего уже нет
Ответы
200Успешный ответ · SlotsResponse
Поля ответа · 4
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
timezone
string
обязательно
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
slots
массив SlotResponse
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/slots' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/slots
Создаёт выход или пачку выходов по правилу повторения
Нужен вход
Доступ. Нужно право: calendar:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Тело запросаSlotCreate · application/json
starts_at
string (date-time)
обязательно
Начало; без пояса — время объекта
ends_at
string (date-time) или null
Конец; без пояса — время объекта
duration_min
integer или null
Длительность, минуты
capacity_total
integer или null
Пусто — без ограничения по местам
language
string или null
Язык: en, ru, th или zh-Hans
guide_name
string или null
repeat_until
string (date) или null
dow_mask
integer или null
Дни недели битами: понедельник — 1, вторник — 2, … воскресенье — 64
unit_ids
массив string (uuid) или null
Идентификаторы номера
sales_close_min
integer или null
За сколько минут до начала закрыть продажу гостям сервиса. Пусто или 0 — в момент начала. Своя бронь партнёра пишется до конца выхода
Ответы
201Успешный ответ · SlotsCreated
Поля ответа · 2
created
integer
обязательно
slots
массив SlotResponse
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/slots' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"starts_at": "2026-11-02T14:00:00+07:00"}'
PATCH/v1/slots/<span class="text-brand-ink">{slot_id}</span>
Правит выход. Мест меньше, чем уже забронировано, — 409
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
slot_id
путь · string (uuid)
обязательно
Идентификатор выхода (UUID)
Тело запросаSlotUpdate · application/json
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
ends_at
string (date-time) или null
Момент в UTC, ISO 8601
duration_min
integer или null
Длительность, минуты
capacity_total
integer или null
language
string или null
Язык: en, ru, th или zh-Hans
guide_name
string или null
status
SlotStatus или null
sales_close_min
integer или null
Ответы
200Успешный ответ · SlotResponse
Поля ответа · 15
id
string (uuid)
обязательно
Идентификатор записи (UUID)
starts_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
ends_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
timezone
string
обязательно
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
duration_min
integer или null
обязательно
Длительность, минуты
capacity_total
integer или null
обязательно
capacity_left
integer или null
обязательно
price_minor
integer или null
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
status
string
обязательно
language
string или null
обязательно
Язык: en, ru, th или zh-Hans
guide_name
string или null
обязательно
sales_close_min
integer
по умолчанию 0
sales_close_at
string (date-time) или null
Момент в UTC, ISO 8601
on_sale
boolean или null
bookings
массив SlotBooking
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/slots/{slot_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"starts_at": "2026-11-02T14:00:00+07:00", "ends_at": "2026-11-02T14:00:00+07:00"}'
DELETE/v1/slots/<span class="text-brand-ink">{slot_id}</span>
Отменяет выход. Строка остаётся: по ней разбирают отменённые брони
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
slot_id
путь · string (uuid)
обязательно
Идентификатор выхода (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/slots/{slot_id}' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/slots/cancel-all
Отменяет все будущие выходы объекта разом
Нужен вход
Выходы с живыми бронями остаются: их снимают разбором каждой брони, а не одной кнопкой. Сколько осталось — в ответе.
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
from
запрос · string (date) или null
Ответы
200Успешный ответ · SlotsCancelled
Поля ответа · 2
cancelled
integer
обязательно
kept_with_bookings
integer
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/slots/cancel-all' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/quote
Тот же расчёт, что видит гость, — для сверки со своей системой
Нужен вход
Доступ. Нужно право: pricing:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаQuoteRequest · application/json
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
slot_id
string (uuid) или null
Идентификатор выхода (UUID)
guests
integer
по умолчанию 1
Число гостей
Ответы
200Успешный ответ · QuoteResponse
Поля ответа · 9
available
boolean
обязательно
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
nights
integer
обязательно
Число ночей
lines
массив QuoteLine
обязательно
total
MoneyBody
обязательно
Сколько всего
deposit
MoneyBody или null
reason
string или null
conflict_dates
массив string (date) или null
min_nights
integer или null
Наименьшее число ночей брони
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/quote' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"date_from": "2026-11-02", "date_to": "2026-11-02"}'
iCal
6 эндпоинтовСинхронизация занятости с Airbnb, Booking.com, Agoda и PMS по стандарту iCalendar (RFC 5545) — по номерам: у каждого номера своя ссылка экспорта .ics (работает без входа) и свои календари других площадок, раз в 15 минут. Наши брони календарь не снимает; пересечение — предупреждением и письмом.
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/ical
Ссылки экспорта по номерам и подключённые календари других площадок
Нужен вход
У номера без ссылки она выпускается при первом показе. Только объекты с датами и номерами (жильё, транспорт) — иначе 409.
Доступ. Нужно право: calendar:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · IcalOverview
Поля ответа · 6
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
timezone
string
обязательно
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
interval_min
integer
обязательно
Раз в столько минут обновляются чужие календари
units
массив IcalUnit
обязательно
exports
массив IcalExport
обязательно
feeds
массив IcalFeedBody
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/ical' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units/<span class="text-brand-ink">{unit_id}</span>/ical-export
«Выпустить новую ссылку» номера: прежняя перестаёт работать сразу
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
unit_id
путь · string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
Ответы
200Успешный ответ · IcalExport
Поля ответа · 3
unit_id
string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string
обязательно
Название номера
url
string
обязательно
Секретная ссылка .ics номера — вставляется в чужой календарь
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units/{unit_id}/ical-export' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/ical-feeds
Подключить чужой календарь номера
Нужен вход
Первое обновление — в течение минуты, дальше — раз в 15 минут. Тот же адрес у номера — 409, больше 10 — 409.
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаIcalFeedCreate · application/json
unit_id
string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
name
string
обязательно
url
string
обязательно
https://…, http://… или webcal://…
Ответы
201Успешный ответ · IcalFeedBody
Поля ответа · 15
id
string (uuid)
обязательно
Идентификатор записи (UUID)
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
name
string или null
Откуда календарь — «Airbnb», «Booking.com»
url
string или null
Адрес
state
pending | ok | error | conflict
обязательно
pending — ещё не обновлялся, error — не открывается, conflict — пересёкся с бронью Bounty
error
404 | not_ical | unreachable или null
Почему не открывается: нет ссылки, не календарь, площадка не отвечает
error_detail
string или null
last_ok_at
string (date-time) или null
Последнее удачное обновление
last_sync_at
string (date-time) или null
Момент в UTC, ISO 8601
failing_since
string (date-time) или null
busy_days
integer
по умолчанию 0
Сколько занятых ночей в календаре
conflicts
массив IcalConflict
interval_min
integer
по умолчанию 15
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/ical-feeds' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"unit_id": "00000000-0000-0000-0000-000000000000", "name": "…", "url": "…"}'
POST/v1/ical-feeds/<span class="text-brand-ink">{feed_id}</span>/sync
«Обновить сейчас»: загрузка в запросе, до 15 секунд; итог — в ответе
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
feed_id
путь · string (uuid)
обязательно
Идентификатор календаря iCal (UUID)
Ответы
200Успешный ответ · IcalFeedBody
Поля ответа · 15
id
string (uuid)
обязательно
Идентификатор записи (UUID)
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
name
string или null
Откуда календарь — «Airbnb», «Booking.com»
url
string или null
Адрес
state
pending | ok | error | conflict
обязательно
pending — ещё не обновлялся, error — не открывается, conflict — пересёкся с бронью Bounty
error
404 | not_ical | unreachable или null
Почему не открывается: нет ссылки, не календарь, площадка не отвечает
error_detail
string или null
last_ok_at
string (date-time) или null
Последнее удачное обновление
last_sync_at
string (date-time) или null
Момент в UTC, ISO 8601
failing_since
string (date-time) или null
busy_days
integer
по умолчанию 0
Сколько занятых ночей в календаре
conflicts
массив IcalConflict
interval_min
integer
по умолчанию 15
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/ical-feeds/{feed_id}/sync' \
-H 'Authorization: Bearer <access>'
DELETE/v1/ical-feeds/<span class="text-brand-ink">{feed_id}</span>
«Отключить»: даты, закрытые этим календарём, открываются; брони не трогаются
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
feed_id
путь · string (uuid)
обязательно
Идентификатор календаря iCal (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/ical-feeds/{feed_id}' \
-H 'Authorization: Bearer <access>'
GET/v1/ical/<span class="text-brand-ink">{secret}</span>.ics
Календарь номера в формате iCalendar (RFC 5545) — без входа
Без входа
Брони и закрытия номера, даты, закрытые у объекта целиком; VALUE=DATE, день выезда не входит; данных гостя нет, в SUMMARY — код брони.
Параметры
secret
путь · string
обязательно
Ответы
200Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
404Ссылки нет или её выпустили заново
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/ical/{secret}.ics'
Массовые операции
4 эндпоинтаКалендарь и цены по многим объектам одной задачей: ответ 202 с задачей (id, status: queued) сразу, ход и итог — GET /v1/jobs/{id}. Ошибка в одной строке не откатывает пачку.
POST/v1/bulk/calendar
Календарь пачкой: до 200 объектов, у каждого — дни объекта (ranges, как в PUT /availability), закрыть и открыть номер (close, open)
Нужен вход
Объект и номер — нашим id или вашим кодом из сопоставлений.
Доступ. Нужно право: calendar:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Тело запросаBulkCalendar · application/json
items
массив BulkCalendarItem
обязательно
Записи страницы
Ответы
202Успешный ответ · JobBody
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
string
обязательно
status
queued | running | done | failed
обязательно
progress
integer
обязательно
0–100
total
integer
по умолчанию 0
Сколько всего
done
integer
по умолчанию 0
failed
integer
по умолчанию 0
errors
массив JobError
results
массив JobResult
Только у bulk_listings
warnings
массив JobError
Не откатили строку: снимок не скачался, объект не готов к публикации
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
started_at
string (date-time) или null
Момент в UTC, ISO 8601
finished_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bulk/calendar' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"items": [{}]}'
POST/v1/bulk/pricing
Цены пачкой: базовая цена и сборы, цена и минимальный срок по дням, новые правила
Нужен вход
Доступ. Нужно право: pricing:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Тело запросаBulkPricing · application/json
items
массив BulkPricingItem
обязательно
Записи страницы
Ответы
202Успешный ответ · JobBody
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
string
обязательно
status
queued | running | done | failed
обязательно
progress
integer
обязательно
0–100
total
integer
по умолчанию 0
Сколько всего
done
integer
по умолчанию 0
failed
integer
по умолчанию 0
errors
массив JobError
results
массив JobResult
Только у bulk_listings
warnings
массив JobError
Не откатили строку: снимок не скачался, объект не готов к публикации
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
started_at
string (date-time) или null
Момент в UTC, ISO 8601
finished_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bulk/pricing' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"items": [{}]}'
POST/v1/bulk/listings
Объекты пачкой: до 100 объектов — создать или обновить по вашему коду
Нужен вход
Строка находит объект по listing_id или по external_id; нет такого — создаётся черновик и сопоставляется вашему коду. listing — поля как в PATCH /v1/listings/{id}, amenities — полной заменой, units — номера по вашим кодам (ещё право calendar:write), photos — адреса снимков, publish — опубликовать, если объект готов. Наш id каждой строки — в results итога, не скачавшиеся снимки и неготовность — в warnings.
Доступ. Нужно право: listings:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Тело запросаBulkListings · application/json
items
массив BulkListingItem
обязательно
Записи страницы
Ответы
202Успешный ответ · JobBody
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
string
обязательно
status
queued | running | done | failed
обязательно
progress
integer
обязательно
0–100
total
integer
по умолчанию 0
Сколько всего
done
integer
по умолчанию 0
failed
integer
по умолчанию 0
errors
массив JobError
results
массив JobResult
Только у bulk_listings
warnings
массив JobError
Не откатили строку: снимок не скачался, объект не готов к публикации
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
started_at
string (date-time) или null
Момент в UTC, ISO 8601
finished_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bulk/listings' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"items": [{}]}'
GET/v1/jobs/<span class="text-brand-ink">{job_id}</span>
Ход и итог задачи: queued → running → done; неудачные строки — в errors
Нужен вход
Параметры
job_id
путь · string (uuid)
обязательно
Идентификатор задачи (UUID)
Ответы
200Успешный ответ · JobBody
Поля ответа · 13
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
string
обязательно
status
queued | running | done | failed
обязательно
progress
integer
обязательно
0–100
total
integer
по умолчанию 0
Сколько всего
done
integer
по умолчанию 0
failed
integer
по умолчанию 0
errors
массив JobError
results
массив JobResult
Только у bulk_listings
warnings
массив JobError
Не откатили строку: снимок не скачался, объект не готов к публикации
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
started_at
string (date-time) или null
Момент в UTC, ISO 8601
finished_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/jobs/{job_id}' \
-H 'Authorization: Bearer <access>'
Сопоставления
3 эндпоинтаПары «наш объект ↔ ваш объект» на нашей стороне: объект, номер, бронь, тариф. У бизнеса и у каждого приложения — свои; переживают переустановку вашего модуля.
GET/v1/external-refs
Ваши пары «наш объект ↔ ваш объект»: найти наш id по вашему коду и наоборот
Нужен вход
Параметры
kind
запрос · string или null
external_id
запрос · string или null
entity_id
запрос · string (uuid) или null
Ответы
200Успешный ответ · массив ExternalRefBody
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/external-refs' \
-H 'Authorization: Bearer <access>'
PUT/v1/external-refs
Сопоставить (201) или перепривязать (200). Ваш код у другого нашего объекта — 409
Нужен вход
Тело запросаExternalRefPut · application/json
kind
listing | unit | booking | rate_plan
обязательно
entity_id
string (uuid)
обязательно
external_id
string
обязательно
external_system
string или null
Ответы
200Успешный ответ · ExternalRefBody
Поля ответа · 6
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
listing | unit | booking | rate_plan
обязательно
entity_id
string (uuid)
обязательно
external_id
string
обязательно
external_system
string или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/external-refs' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"kind": "listing", "entity_id": "00000000-0000-0000-0000-000000000000", "external_id": "…"}'
DELETE/v1/external-refs/<span class="text-brand-ink">{ref_id}</span>
Снять сопоставление «наш объект ↔ ваш»
Нужен вход
Сами объект, номер или бронь не меняются — пропадает только пара.
Параметры
ref_id
путь · string (uuid)
обязательно
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/external-refs/{ref_id}' \
-H 'Authorization: Bearer <access>'
Приложения
4 эндпоинтаПриложения интеграторов, подключённые к бизнесу: список, страница подключения, права, отключение. Только полный доступ и только сессией кабинета. Само приложение шлёт Authorization: Bearer bnt_app_… и X-Bounty-Partner: <id>.
GET/v1/apps
Подключённые приложения: кто, права, кто и когда подключил, последний запрос
Нужен вход
Доступ. только владелец бизнеса.
Ответы
200Успешный ответ · массив AppGrantBody
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/apps' \
-H 'Authorization: Bearer <access>'
GET/v1/apps/<span class="text-brand-ink">{code}</span>
Страница «Подключить приложение»: кто просит и что сможет
Нужен вход
Приложения нет или оно приостановлено — 404.
Доступ. только владелец бизнеса.
Параметры
code
путь · string
обязательно
Ответы
200Успешный ответ · AppConnectInfo
Поля ответа · 5
app
AppPublic
обязательно
about
string или null
areas
массив object
обязательно
Разделы — как у ключа; levels урезаны потолком приложения
access
object
обязательно
Положения по умолчанию: подключённое — его права, новое — потолок
connected
boolean
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/apps/{code}' \
-H 'Authorization: Bearer <access>'
PUT/v1/apps/<span class="text-brand-ink">{code}</span>/grant
Подключить приложение (201) или сохранить его права (200)
Нужен вход
Права — не больше потолка приложения; без accept_terms — 422 terms_required. О подключении — письмо всем владельцам.
Доступ. только владелец бизнеса.
Параметры
code
путь · string
обязательно
Тело запросаAppConnect · application/json
access
object
обязательно
Раздел → none / read / write; больше потолка не выдаётся
accept_terms
boolean
по умолчанию false
Ответы
200Успешный ответ · AppGrantBody
Поля ответа · 9
id
string (uuid)
обязательно
Идентификатор записи (UUID)
app
AppPublic
обязательно
scopes
массив string
обязательно
Права по разделам
access
object
обязательно
granted_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
granted_by
AppPerson или null
last_used_at
string (date-time) или null
Момент в UTC, ISO 8601
requests_today
integer
по умолчанию 0
revoked_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/apps/{code}/grant' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"access": {}}'
DELETE/v1/apps/<span class="text-brand-ink">{app_id}</span>/grant
«Отключить»: следующий запрос приложения к бизнесу — 403 not_connected
Нужен вход
Доступ. только владелец бизнеса.
Параметры
app_id
путь · string (uuid)
обязательно
Идентификатор приложения (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/apps/{app_id}/grant' \
-H 'Authorization: Bearer <access>'
Номерной фонд и контракты
13 эндпоинтовЕдиницы фонда, их закрытия и долгосрочные контракты.
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units
Единицы объекта: сколько их и в каком они состоянии
Нужен вход
Доступ. Нужно право: calendar:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · UnitsResponse
Поля ответа · 3
listing_id
string
обязательно
Идентификатор объекта (UUID)
units_total
integer
обязательно
Сколько единиц продаётся: выведенные не в счёт
units
массив app__schemas__units__UnitBody
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units' \
-H 'Authorization: Bearer <access>'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units
Количество единиц. Уменьшение под будущей бронью — 409
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаUnitsTotal · application/json
units_total
integer
обязательно
names
массив string или null
Ответы
200Успешный ответ · UnitsResponse
Поля ответа · 3
listing_id
string
обязательно
Идентификатор объекта (UUID)
units_total
integer
обязательно
Сколько единиц продаётся: выведенные не в счёт
units
массив app__schemas__units__UnitBody
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"units_total": 0}'
PATCH/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units/<span class="text-brand-ink">{unit_id}</span>
Имя единицы: «302», «Bungalow C»
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
unit_id
путь · string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
Тело запросаUnitRename · application/json
name
string
обязательно
Ответы
200Успешный ответ · app__schemas__units__UnitBody
Поля ответа · 10
id
string
обязательно
Идентификатор записи (UUID)
name
string
обязательно
status
string
обязательно
available / out_of_service
note
string или null
Заметка
position
integer
обязательно
Порядок показа, с нуля
attrs
object
care
string или null
dirty / prepared / ready
care_note
string или null
care_updated_at
string (date-time) или null
Момент в UTC, ISO 8601
attr_spec
массив object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units/{unit_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"name": "…"}'
DELETE/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units/<span class="text-brand-ink">{unit_id}</span>
Убирает единицу из фонда. Последнюю или занятую бронью — 409
Нужен вход
Отвечает всем фондом, а не пустотой: кабинет после удаления показывает список, и отдельный запрос за ним был бы вторым способом узнать то же самое — с окном, в котором два ответа разойдутся.
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
unit_id
путь · string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
Ответы
200Успешный ответ · UnitsResponse
Поля ответа · 3
listing_id
string
обязательно
Идентификатор объекта (UUID)
units_total
integer
обязательно
Сколько единиц продаётся: выведенные не в счёт
units
массив app__schemas__units__UnitBody
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units/{unit_id}' \
-H 'Authorization: Bearer <access>'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units/<span class="text-brand-ink">{unit_id}</span>/status
Вывод единицы в ремонт и возврат её в работу
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
unit_id
путь · string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
Тело запросаUnitStatusBody · application/json
status
string
обязательно
available / out_of_service
note
string или null
Заметка
Ответы
200Успешный ответ · app__schemas__units__UnitBody
Поля ответа · 10
id
string
обязательно
Идентификатор записи (UUID)
name
string
обязательно
status
string
обязательно
available / out_of_service
note
string или null
Заметка
position
integer
обязательно
Порядок показа, с нуля
attrs
object
care
string или null
dirty / prepared / ready
care_note
string или null
care_updated_at
string (date-time) или null
Момент в UTC, ISO 8601
attr_spec
массив object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units/{unit_id}/status' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"status": "…"}'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/blocks
Закрытия единиц в диапазоне дат
Нужен вход
Доступ. Нужно право: calendar:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
from
запрос · string (date)
обязательно
to
запрос · string (date)
обязательно
Ответы
200Успешный ответ · BlocksResponse
Поля ответа · 2
listing_id
string
обязательно
Идентификатор объекта (UUID)
blocks
массив BlockBody
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/blocks' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/blocks
Закрывает единицу на диапазон. Даты под бронью — 409
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаBlockCreate · application/json
unit_id
string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
date_from
string (date)
обязательно
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date)
обязательно
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
reason
string
по умолчанию "manual"
manual / maintenance
note
string или null
Заметка
Ответы
201Успешный ответ · BlockBody
Поля ответа · 7
id
string
обязательно
Идентификатор записи (UUID)
unit_id
string
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
date_from
string (date)
обязательно
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date)
обязательно
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
reason
string
обязательно
note
string или null
Заметка
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/blocks' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"unit_id": "00000000-0000-0000-0000-000000000000", "date_from": "2026-11-02", "date_to": "2026-11-02"}'
DELETE/v1/listings/<span class="text-brand-ink">{listing_id}</span>/blocks/<span class="text-brand-ink">{block_id}</span>
Снимает закрытие и возвращает дни в продажу
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
block_id
путь · string (uuid)
обязательно
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/listings/{listing_id}/blocks/{block_id}' \
-H 'Authorization: Bearer <access>'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/long-term
Включает или выключает долгосрочную аренду у объекта
Нужен вход
До включения предложений у объекта не бывает вовсе. Выключение не трогает уже заключённые сделки: договор — обязательство перед человеком, и снять его переключателем нельзя; закрывается только витрина.
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаLongTermBody · application/json
long_term
boolean
обязательно
Ответы
200Успешный ответ · LongTermBody
Поля ответа · 1
long_term
boolean
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/long-term' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"long_term": false}'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/contracts
Предложения долгосрочной аренды. Отелю — 409
Нужен вход
Доступ. Нужно право: pricing:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · ContractsResponse
Поля ответа · 4
listing_id
string
обязательно
Идентификатор объекта (UUID)
includes
массив string
обязательно
Справочник кодов «что входит в цену»
contracts
массив ContractBody
обязательно
long_term
boolean
по умолчанию false
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/contracts' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/contracts
Новое предложение долгосрочной аренды
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
Тело запросаContractCreate · application/json
duration_months
integer
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string или null
Код валюты ISO 4217 (THB, RUB, USD…)
deposit_minor
integer
по умолчанию 0
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
utilities
string
по умолчанию "by_meter"
utilities_extra_minor
integer
по умолчанию 0
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
electricity_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
water_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
includes
массив string
min_notice_days
integer
по умолчанию 0
Ответы
201Успешный ответ · ContractBody
Поля ответа · 14
id
string
обязательно
Идентификатор записи (UUID)
duration_months
integer
обязательно
price_minor
integer
обязательно
Цена месяца, фиксированная
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
deposit_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
utilities
string
обязательно
included / by_meter / extra
utilities_extra_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
electricity_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
water_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
includes
массив string
обязательно
min_notice_days
integer
обязательно
is_active
boolean
обязательно
total_minor
integer
обязательно
Справочно: цена месяца × срок
settlement
string
по умолчанию "outside"
Кто проводит деньги. Пока всегда outside — расчёт вне сервиса
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/contracts' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"duration_months": 0, "price_minor": 0}'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/contracts/<span class="text-brand-ink">{contract_id}</span>
Правка предложения
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
contract_id
путь · string (uuid)
обязательно
Идентификатор договора (UUID)
Тело запросаContractCreate · application/json
duration_months
integer
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string или null
Код валюты ISO 4217 (THB, RUB, USD…)
deposit_minor
integer
по умолчанию 0
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
utilities
string
по умолчанию "by_meter"
utilities_extra_minor
integer
по умолчанию 0
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
electricity_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
water_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
includes
массив string
min_notice_days
integer
по умолчанию 0
Ответы
200Успешный ответ · ContractBody
Поля ответа · 14
id
string
обязательно
Идентификатор записи (UUID)
duration_months
integer
обязательно
price_minor
integer
обязательно
Цена месяца, фиксированная
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
deposit_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
utilities
string
обязательно
included / by_meter / extra
utilities_extra_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
electricity_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
water_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
includes
массив string
обязательно
min_notice_days
integer
обязательно
is_active
boolean
обязательно
total_minor
integer
обязательно
Справочно: цена месяца × срок
settlement
string
по умолчанию "outside"
Кто проводит деньги. Пока всегда outside — расчёт вне сервиса
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/contracts/{contract_id}' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"duration_months": 0, "price_minor": 0}'
DELETE/v1/listings/<span class="text-brand-ink">{listing_id}</span>/contracts/<span class="text-brand-ink">{contract_id}</span>
Снятие предложения с показа. Не удаление
Нужен вход
Доступ. Нужно право: pricing:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
contract_id
путь · string (uuid)
обязательно
Идентификатор договора (UUID)
Ответы
200Успешный ответ · ContractBody
Поля ответа · 14
id
string
обязательно
Идентификатор записи (UUID)
duration_months
integer
обязательно
price_minor
integer
обязательно
Цена месяца, фиксированная
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
deposit_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
utilities
string
обязательно
included / by_meter / extra
utilities_extra_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
electricity_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
water_rate_minor
integer или null
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
includes
массив string
обязательно
min_notice_days
integer
обязательно
is_active
boolean
обязательно
total_minor
integer
обязательно
Справочно: цена месяца × срок
settlement
string
по умолчанию "outside"
Кто проводит деньги. Пока всегда outside — расчёт вне сервиса
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/listings/{listing_id}/contracts/{contract_id}' \
-H 'Authorization: Bearer <access>'
Работа дня
10 эндпоинтовОбзор, доска дня, шахматка, подготовка (15б).
GET/v1/overview
Обзор бизнеса для первого экрана кабинета
Нужен вход
Объекты, заявки и неделя вперёд, деньги за месяц, отзывы и переписка — каждая часть по праву роли; закрытая приходит null, а не отказом всей сводки.
Ответы
200Успешный ответ · OverviewResponse
Поля ответа · 6
today
string (date)
обязательно
listings
object или null
bookings
object или null
money
object или null
reviews
object или null
chats
object или null
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/overview' \
-H 'Authorization: Bearer <access>'
GET/v1/board
Доска дня: кто заезжает, кто выезжает, кто внутри, что свободно
Нужен вход
date — дата в поясе объекта, а не сервера. Без неё берётся сегодняшний день первого объекта партнёра: для управляющей компании из Москвы и виллы на Пхукете это разные сутки.
Доступ. Нужно право: bookings:read.
Параметры
date
запрос · string (date) или null
Календарный день в поясе объекта, без времени и пояса (YYYY-MM-DD)
listing_id
запрос · string (uuid) или null
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · BoardResponse
Поля ответа · 9
date
string (date)
обязательно
Календарный день в поясе объекта, без времени и пояса (YYYY-MM-DD)
arrivals
массив BoardBooking
обязательно
departures
массив BoardBooking
обязательно
in_house
массив BoardBooking
обязательно
pending
массив BoardBooking
обязательно
attention
массив BoardBooking
обязательно
slots
массив BoardSlot
обязательно
free
массив BoardFree
обязательно
care
массив UnitCareBody
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/board' \
-H 'Authorization: Bearer <access>'
GET/v1/guest-list
Лист гостей на день или дни: кто едет на каждом выходе
Нужен вход
Для впечатления, услуги и еды. Дни → выходы → брони → люди: участник строкой, не названные — пустыми строками, чтобы счёт голов сходился с бронью. Персональные данные — по правилам карточки брони: у заявки и до подтверждения — только число людей. Срок любой — хоть вся история бизнеса; в days приходят только дни с записями, days_total — дней в промежутке всего.
Доступ. Нужно право: bookings:read.
Параметры
from
запрос · string (date)
обязательно
Первый день — в поясе объекта
to
запрос · string (date) или null
Последний день включительно; пусто — тот же день
listing_id
запрос · string (uuid) или null
Только этот объект
slot_id
запрос · string (uuid) или null
Только этот выход
documents
запрос · boolean
Добавить номера паспортов участников (по умолчанию — нет)
Ответы
200Успешный ответ · GuestListResponse
Поля ответа · 7
date_from
string (date)
обязательно
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date)
обязательно
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
with_documents
boolean
обязательно
generated_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
totals
object
обязательно
days_total
integer
по умолчанию 0
Дней в промежутке, включая дни без записей
days
массив GuestListDay
обязательно
Только дни, на которые кто-то записан
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/guest-list' \
-H 'Authorization: Bearer <access>'
GET/v1/listings/<span class="text-brand-ink">{listing_id}</span>/rack
Шахматка «ресурс × день» — не больше месяца за раз
Нужен вход
Доступ. Нужно право: calendar:read.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
from
запрос · string (date)
обязательно
to
запрос · string (date)
обязательно
Ответы
200Успешный ответ · RackResponse
Поля ответа · 11
listing_id
string
обязательно
Идентификатор объекта (UUID)
kind
string
обязательно
mode
string
по умолчанию "units"
timezone
string или null
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
date_from
string (date)
обязательно
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date)
обязательно
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
today
string (date) или null
days
массив string (date)
по умолчанию []
Дни — календарные даты в поясе объекта
rows
массив RackRowBody
по умолчанию []
slot_days
массив RackDayBody
по умолчанию []
unplaced
массив RackUnplacedBody
по умолчанию []
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/listings/{listing_id}/rack' \
-H 'Authorization: Bearer <access>'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/move
Переселяет бронь в другую единицу. Занятая единица — 409
Нужен вход
До этого единственным ответом на «в номере течёт кондиционер» была отмена брони, то есть потерять и деньги, и человека.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаMoveBody · application/json
unit_id
string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
Ответы
200Успешный ответ · BookingBrief
Поля ответа · 21
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/move' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"unit_id": "00000000-0000-0000-0000-000000000000"}'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/dates
Продление или сокращение проживания
Нужен вход
Считается заново тем же кодом, что и создание: цена ночей могла измениться, скидка за длительность включиться, минимальный срок перестать выполняться. Занятые сутки — 409. Оплаченную бронь этот эндпоинт не двигает вовсе — 409 paid_booking: её сумма уже состоявшийся факт, и пересчёт переписал бы заплаченное. Продлевают такую бронь отдельным чеком.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаRescheduleRequest · application/json
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
Ответы
200Успешный ответ · BookingBrief
Поля ответа · 21
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/dates' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"date_from": "2026-11-02", "date_to": "2026-11-02"}'
GET/v1/care
Список подготовки: что убрано, что готово, что ждёт
Нужен вход
Доступ. Нужно право: care:read.
Параметры
listing_id
запрос · string (uuid) или null
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · CareListResponse
Поля ответа · 1
items
массив UnitCareBody
обязательно
Записи страницы
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/care' \
-H 'Authorization: Bearer <access>'
POST/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units/<span class="text-brand-ink">{unit_id}</span>/care
Состояние подготовки: грязный → подготовлен → готов
Нужен вход
Переход свободный, а не по цепочке: горничная отмечает «готов» сразу, а стойка, увидев беспорядок, возвращает в «грязный».
Доступ. Нужно право: care:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
unit_id
путь · string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
Тело запросаCareSet · application/json
care
string
обязательно
dirty / prepared / ready
note
string или null
Заметка
Ответы
200Успешный ответ · UnitCareBody
Поля ответа · 13
id
string
обязательно
Идентификатор записи (UUID)
name
string
обязательно
status
string
обязательно
note
string или null
Заметка
position
integer
обязательно
Порядок показа, с нуля
attrs
object
care
string
обязательно
dirty / prepared / ready
care_note
string или null
care_updated_at
string (date-time) или null
Момент в UTC, ISO 8601
attr_spec
массив object
listing_id
string или null
Идентификатор объекта (UUID)
listing_title
string или null
Название объекта на языке ответа
kind
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units/{unit_id}/care' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"care": "…"}'
PUT/v1/listings/<span class="text-brand-ink">{listing_id}</span>/units/<span class="text-brand-ink">{unit_id}</span>/attrs
Свойства единицы: этаж и вид, госномер и пробег, места и зона
Нужен вход
Доступ. Нужно право: calendar:write.
Параметры
listing_id
путь · string (uuid)
обязательно
Идентификатор объекта (UUID)
unit_id
путь · string (uuid)
обязательно
Идентификатор номера (единицы номерного фонда) (UUID)
Тело запросаAttrsSet · application/json
attrs
object
Ответы
200Успешный ответ · UnitCareBody
Поля ответа · 13
id
string
обязательно
Идентификатор записи (UUID)
name
string
обязательно
status
string
обязательно
note
string или null
Заметка
position
integer
обязательно
Порядок показа, с нуля
attrs
object
care
string
обязательно
dirty / prepared / ready
care_note
string или null
care_updated_at
string (date-time) или null
Момент в UTC, ISO 8601
attr_spec
массив object
listing_id
string или null
Идентификатор объекта (UUID)
listing_title
string или null
Название объекта на языке ответа
kind
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PUT 'https://partner-api.bounty.travel/v1/listings/{listing_id}/units/{unit_id}/attrs' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"attrs": {}}'
GET/v1/stats
Загрузка, средняя цена проданной единицы и выручка на единицу фонда
Нужен вход
Доступ. Нужно право: finance:read.
Параметры
from
запрос · string (date)
обязательно
to
запрос · string (date)
обязательно
listing_id
запрос · string (uuid) или null
Идентификатор объекта (UUID)
Ответы
200Успешный ответ · StatsResponse
Поля ответа · 11
date_from
string (date)
обязательно
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date)
обязательно
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
days
integer
обязательно
Дни — календарные даты в поясе объекта
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
capacity_nights
integer
обязательно
sold_nights
integer
обязательно
occupancy_percent
number
обязательно
revenue_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
adr_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
revpar_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
slots
SlotStats
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/stats' \
-H 'Authorization: Bearer <access>'
Бронирования
13 эндпоинтовБрони гостей: подтверждение, отказ, отмена, заселение, выезд, неявка.
GET/v1/bookings
Брони бизнеса. Фильтры — статус, объект, период
Нужен вход
Все брони — от гостей сервиса: своих броней у партнёра нет. Занятость из другой системы — закрытие единицы (POST /v1/listings/{id}/blocks).
Доступ. Нужно право: bookings:read.
Список страницами. Ответ отдаёт next_cursor; следующую страницу просите с ним в cursor. has_more: false или нет курсора — список кончился.
Параметры
status
запрос · BookingStatus или null
listing_id
запрос · string (uuid) или null
Идентификатор объекта (UUID)
from
запрос · string (date) или null
to
запрос · string (date) или null
limit
запрос · integer или null
Сколько записей на странице
cursor
запрос · string или null
Курсор из next_cursor прошлого ответа; без него — первая страница
with_counts
запрос · boolean
Добавить counts — брони по состояниям
Ответы
200Успешный ответ · BookingPage
Поля ответа · 4
items
массив BookingBrief
обязательно
Записи страницы
next_cursor
string или null
Курсор следующей страницы: передайте его в cursor. Нет — страница последняя. Непрозрачен: не разбирайте и не собирайте руками
has_more
boolean
по умолчанию false
Есть ли следующая страница
counts
object или null
Только с with_counts=true: брони по состояниям (pending, confirmed, …) и all — при тех же объекте и периоде, без отбора по состоянию
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/bookings' \
-H 'Authorization: Bearer <access>'
POST/v1/bookings/scan
Проверка билета или номера брони. Ничего не меняет
Нужен вход
Каждая попытка, включая неудачную, пишется в booking_checkins: и спор «я приходил», и подбор чужих номеров разбираются по этому журналу.
Доступ. Нужно право: bookings:write.
Тело запросаScanRequest · application/json
ticket
string или null
code
string или null
Ответы
200Успешный ответ · ScanResponse
Поля ответа · 17
can_check_in
boolean
обязательно
result
string
обязательно
ok / invalid_ticket / expired / wrong_partner / not_paid / too_early / already_used / cancelled
id
string (uuid) или null
Идентификатор записи (UUID)
code
string или null
status
string или null
kind
string или null
listing_id
string (uuid) или null
Идентификатор объекта (UUID)
listing_title
string или null
Название объекта на языке ответа
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer или null
Число гостей
total
MoneyBody или null
Сколько всего
payment_status
string или null
timezone
string или null
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
guests_details
массив GuestBody или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/scan' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"ticket": "…", "code": "…"}'
GET/v1/bookings/<span class="text-brand-ink">{booking_id}</span>
Карточка брони: гость и его история, даты в поясе объекта, деньги и доплаты, сообщение гостя и заметка бизнеса
Нужен вход
Доступ. Нужно право: bookings:read.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ · BookingDetail
Поля ответа · 58
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
lines
массив QuoteLine
обязательно
can_review_guest
boolean
по умолчанию false
guest_review
object или null
review_until
string (date-time) или null
guest_review_refusal
string или null
review_opens_at
string (date-time) или null
Момент в UTC, ISO 8601
has_guest_account
boolean
по умолчанию false
subtotal
MoneyBody или null
discount
MoneyBody или null
cleaning_fee
MoneyBody или null
extra_guest_fee
MoneyBody или null
service_fee
MoneyBody или null
tax
MoneyBody или null
guest_profile
GuestProfileBody или null
guest_history
GuestHistoryBody или null
commission
MoneyBody
обязательно
Комиссия сервиса
guest_message
string или null
partner_note
string или null
free_cancel_until
string (date-time) или null
checkin_at
string (date-time) или null
Момент в UTC, ISO 8601
checkout_at
string (date-time) или null
Момент в UTC, ISO 8601
can_check_in_now
boolean
по умолчанию true
checkin_opens_at
string (date) или null
Момент в UTC, ISO 8601
can_check_out_now
boolean
по умолчанию true
can_mark_no_show
boolean
по умолчанию false
«Гость не пришёл»: с начала заказа до конца окна
can_undo_no_show
boolean
по умолчанию false
Снять отметку неявки: до конца того же окна
no_show_opens_at
string (date-time) или null
Плановое начало: раньше неявку не отмечают
no_show_closes_at
string (date-time) или null
Конец окна неявки: окончание + часы booking_autoclose_hours
auto_complete_at
string (date-time) или null
Когда выход впечатления, услуги или еды завершится сам; у жилья и проката пусто
cancel_reason_code
string или null
cancelled_by_kind
string или null
timezone
string
обязательно
Пояс объекта: все даты брони — в нём
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
details
object
settled
object
snapshot
object
confirmed_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/bookings/{booking_id}' \
-H 'Authorization: Bearer <access>'
GET/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/guests
Данные проживающих. По неподтверждённой броне — пусто
Нужен вход
После срока хранения список тоже пуст: фоновая задача обнуляет персональные поля, а строка остаётся — по ней видно, сколько людей заселялось.
Доступ. Нужно право: bookings:read.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ · массив GuestBody
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/guests' \
-H 'Authorization: Bearer <access>'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/confirm
Подтвердить запрос брони
Нужен вход
Доступ. Нужно право: bookings:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Ответы
200Успешный ответ · BookingDetail
Поля ответа · 58
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
lines
массив QuoteLine
обязательно
can_review_guest
boolean
по умолчанию false
guest_review
object или null
review_until
string (date-time) или null
guest_review_refusal
string или null
review_opens_at
string (date-time) или null
Момент в UTC, ISO 8601
has_guest_account
boolean
по умолчанию false
subtotal
MoneyBody или null
discount
MoneyBody или null
cleaning_fee
MoneyBody или null
extra_guest_fee
MoneyBody или null
service_fee
MoneyBody или null
tax
MoneyBody или null
guest_profile
GuestProfileBody или null
guest_history
GuestHistoryBody или null
commission
MoneyBody
обязательно
Комиссия сервиса
guest_message
string или null
partner_note
string или null
free_cancel_until
string (date-time) или null
checkin_at
string (date-time) или null
Момент в UTC, ISO 8601
checkout_at
string (date-time) или null
Момент в UTC, ISO 8601
can_check_in_now
boolean
по умолчанию true
checkin_opens_at
string (date) или null
Момент в UTC, ISO 8601
can_check_out_now
boolean
по умолчанию true
can_mark_no_show
boolean
по умолчанию false
«Гость не пришёл»: с начала заказа до конца окна
can_undo_no_show
boolean
по умолчанию false
Снять отметку неявки: до конца того же окна
no_show_opens_at
string (date-time) или null
Плановое начало: раньше неявку не отмечают
no_show_closes_at
string (date-time) или null
Конец окна неявки: окончание + часы booking_autoclose_hours
auto_complete_at
string (date-time) или null
Когда выход впечатления, услуги или еды завершится сам; у жилья и проката пусто
cancel_reason_code
string или null
cancelled_by_kind
string или null
timezone
string
обязательно
Пояс объекта: все даты брони — в нём
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
details
object
settled
object
snapshot
object
confirmed_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/confirm' \
-H 'Authorization: Bearer <access>'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/decline
Отклонить запрос. Даты освобождаются немедленно
Нужен вход
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаDeclineRequest · application/json
reason_code
string или null
Машинный код причины
comment
string или null
Комментарий
Ответы
200Успешный ответ · BookingDetail
Поля ответа · 58
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
lines
массив QuoteLine
обязательно
can_review_guest
boolean
по умолчанию false
guest_review
object или null
review_until
string (date-time) или null
guest_review_refusal
string или null
review_opens_at
string (date-time) или null
Момент в UTC, ISO 8601
has_guest_account
boolean
по умолчанию false
subtotal
MoneyBody или null
discount
MoneyBody или null
cleaning_fee
MoneyBody или null
extra_guest_fee
MoneyBody или null
service_fee
MoneyBody или null
tax
MoneyBody или null
guest_profile
GuestProfileBody или null
guest_history
GuestHistoryBody или null
commission
MoneyBody
обязательно
Комиссия сервиса
guest_message
string или null
partner_note
string или null
free_cancel_until
string (date-time) или null
checkin_at
string (date-time) или null
Момент в UTC, ISO 8601
checkout_at
string (date-time) или null
Момент в UTC, ISO 8601
can_check_in_now
boolean
по умолчанию true
checkin_opens_at
string (date) или null
Момент в UTC, ISO 8601
can_check_out_now
boolean
по умолчанию true
can_mark_no_show
boolean
по умолчанию false
«Гость не пришёл»: с начала заказа до конца окна
can_undo_no_show
boolean
по умолчанию false
Снять отметку неявки: до конца того же окна
no_show_opens_at
string (date-time) или null
Плановое начало: раньше неявку не отмечают
no_show_closes_at
string (date-time) или null
Конец окна неявки: окончание + часы booking_autoclose_hours
auto_complete_at
string (date-time) или null
Когда выход впечатления, услуги или еды завершится сам; у жилья и проката пусто
cancel_reason_code
string или null
cancelled_by_kind
string или null
timezone
string
обязательно
Пояс объекта: все даты брони — в нём
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
details
object
settled
object
snapshot
object
confirmed_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/decline' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"reason_code": "…", "comment": "…"}'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/cancel
Отмена подтверждённой брони
Нужен вход
Гостю возвращается всё, независимо от политики: он остался без жилья не по своей вине. Для партнёра это нарушение и повлияет на рейтинг.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаDeclineRequest · application/json
reason_code
string или null
Машинный код причины
comment
string или null
Комментарий
Ответы
200Успешный ответ · RefundBody
Поля ответа · 4
amount
MoneyBody
обязательно
percent
integer
обязательно
free
boolean
обязательно
reason
string
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/cancel' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"reason_code": "…", "comment": "…"}'
PATCH/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/note
Внутренняя заметка бизнеса к брони. Гость её не видит
Нужен вход
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаNoteRequest · application/json
note
string или null
Заметка
Ответы
200Успешный ответ · BookingDetail
Поля ответа · 58
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
lines
массив QuoteLine
обязательно
can_review_guest
boolean
по умолчанию false
guest_review
object или null
review_until
string (date-time) или null
guest_review_refusal
string или null
review_opens_at
string (date-time) или null
Момент в UTC, ISO 8601
has_guest_account
boolean
по умолчанию false
subtotal
MoneyBody или null
discount
MoneyBody или null
cleaning_fee
MoneyBody или null
extra_guest_fee
MoneyBody или null
service_fee
MoneyBody или null
tax
MoneyBody или null
guest_profile
GuestProfileBody или null
guest_history
GuestHistoryBody или null
commission
MoneyBody
обязательно
Комиссия сервиса
guest_message
string или null
partner_note
string или null
free_cancel_until
string (date-time) или null
checkin_at
string (date-time) или null
Момент в UTC, ISO 8601
checkout_at
string (date-time) или null
Момент в UTC, ISO 8601
can_check_in_now
boolean
по умолчанию true
checkin_opens_at
string (date) или null
Момент в UTC, ISO 8601
can_check_out_now
boolean
по умолчанию true
can_mark_no_show
boolean
по умолчанию false
«Гость не пришёл»: с начала заказа до конца окна
can_undo_no_show
boolean
по умолчанию false
Снять отметку неявки: до конца того же окна
no_show_opens_at
string (date-time) или null
Плановое начало: раньше неявку не отмечают
no_show_closes_at
string (date-time) или null
Конец окна неявки: окончание + часы booking_autoclose_hours
auto_complete_at
string (date-time) или null
Когда выход впечатления, услуги или еды завершится сам; у жилья и проката пусто
cancel_reason_code
string или null
cancelled_by_kind
string или null
timezone
string
обязательно
Пояс объекта: все даты брони — в нём
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
details
object
settled
object
snapshot
object
confirmed_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X PATCH 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/note' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"note": "…"}'
GET/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/check-in
Карточка заселения: вердикт вместе с тем, что нужно на стойке
Нужен вход
Отличие от POST /scan — в том, чего здесь нет: записи в журнал попыток. Открытие карточки из кабинета попыткой заселиться не является; журнал отвечает на вопрос «кто и когда приходил» и засоряться просмотрами не должен.
Сверх обычной карточки брони отдаются единица фонда со свойствами, адрес объекта и часы заезда — то самое «куда заселять», за которым стойка до сих пор ходила в объявление.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ · CheckinCard
Поля ответа · 22
can_check_in
boolean
обязательно
result
string
обязательно
ok / invalid_ticket / expired / wrong_partner / not_paid / too_early / already_used / cancelled
id
string (uuid) или null
Идентификатор записи (UUID)
code
string или null
status
string или null
kind
string или null
listing_id
string (uuid) или null
Идентификатор объекта (UUID)
listing_title
string или null
Название объекта на языке ответа
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer или null
Число гостей
total
MoneyBody или null
Сколько всего
payment_status
string или null
timezone
string или null
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
guests_details
массив GuestBody или null
unit
app__schemas__bookings__UnitBody или null
place
PlaceBody или null
guest_message
string или null
partner_note
string или null
guest_history
object или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/check-in' \
-H 'Authorization: Bearer <access>'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/check-in
Второй шаг заселения: отметка после проверки
Нужен вход
Доступ. Нужно право: bookings:write.
Повтор без дубля. Обязателен заголовок Idempotency-Key — любая строка до 80 символов, своя на каждую операцию. Повтор с тем же ключом и тем же телом в течение суток вернёт первый ответ, с другим телом — 409 idempotency_key_reuse.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Idempotency-Key
заголовок · string
обязательно
Ключ повтора: любая строка до 80 символов, своя на каждую операцию
Ответы
200Успешный ответ · CheckinResponse
Поля ответа · 2
checked_in
boolean
обязательно
result
string
обязательно
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
409Повтор Idempotency-Key с другим телом — idempotency_key_reuse; первый запрос с этим ключом ещё выполняется — idempotency_in_progress; данные расходятся с состоянием — conflict и коды эндпоинта
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/check-in' \
-H 'Authorization: Bearer <access>'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/check-out
Отметка выезда. Бронь становится завершённой
Нужен вход
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ · BookingDetail
Поля ответа · 58
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
lines
массив QuoteLine
обязательно
can_review_guest
boolean
по умолчанию false
guest_review
object или null
review_until
string (date-time) или null
guest_review_refusal
string или null
review_opens_at
string (date-time) или null
Момент в UTC, ISO 8601
has_guest_account
boolean
по умолчанию false
subtotal
MoneyBody или null
discount
MoneyBody или null
cleaning_fee
MoneyBody или null
extra_guest_fee
MoneyBody или null
service_fee
MoneyBody или null
tax
MoneyBody или null
guest_profile
GuestProfileBody или null
guest_history
GuestHistoryBody или null
commission
MoneyBody
обязательно
Комиссия сервиса
guest_message
string или null
partner_note
string или null
free_cancel_until
string (date-time) или null
checkin_at
string (date-time) или null
Момент в UTC, ISO 8601
checkout_at
string (date-time) или null
Момент в UTC, ISO 8601
can_check_in_now
boolean
по умолчанию true
checkin_opens_at
string (date) или null
Момент в UTC, ISO 8601
can_check_out_now
boolean
по умолчанию true
can_mark_no_show
boolean
по умолчанию false
«Гость не пришёл»: с начала заказа до конца окна
can_undo_no_show
boolean
по умолчанию false
Снять отметку неявки: до конца того же окна
no_show_opens_at
string (date-time) или null
Плановое начало: раньше неявку не отмечают
no_show_closes_at
string (date-time) или null
Конец окна неявки: окончание + часы booking_autoclose_hours
auto_complete_at
string (date-time) или null
Когда выход впечатления, услуги или еды завершится сам; у жилья и проката пусто
cancel_reason_code
string или null
cancelled_by_kind
string или null
timezone
string
обязательно
Пояс объекта: все даты брони — в нём
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
details
object
settled
object
snapshot
object
confirmed_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/check-out' \
-H 'Authorization: Bearer <access>'
POST/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/no-show
Гость не пришёл
Нужен вход
С планового начала заказа до конца окна — окончания плюс часы настройки booking_autoclose_hours; только у подтверждённой брони без отметки прихода. Даты и места остаются за гостем: опоздавшего заселяют по билету или снимают отметку. Раньше начала — 409 no_show_too_early, после окна — 409 no_show_closed, у ждущей оплаты и договора — 409 no_show_not_applicable.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ · BookingDetail
Поля ответа · 58
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
lines
массив QuoteLine
обязательно
can_review_guest
boolean
по умолчанию false
guest_review
object или null
review_until
string (date-time) или null
guest_review_refusal
string или null
review_opens_at
string (date-time) или null
Момент в UTC, ISO 8601
has_guest_account
boolean
по умолчанию false
subtotal
MoneyBody или null
discount
MoneyBody или null
cleaning_fee
MoneyBody или null
extra_guest_fee
MoneyBody или null
service_fee
MoneyBody или null
tax
MoneyBody или null
guest_profile
GuestProfileBody или null
guest_history
GuestHistoryBody или null
commission
MoneyBody
обязательно
Комиссия сервиса
guest_message
string или null
partner_note
string или null
free_cancel_until
string (date-time) или null
checkin_at
string (date-time) или null
Момент в UTC, ISO 8601
checkout_at
string (date-time) или null
Момент в UTC, ISO 8601
can_check_in_now
boolean
по умолчанию true
checkin_opens_at
string (date) или null
Момент в UTC, ISO 8601
can_check_out_now
boolean
по умолчанию true
can_mark_no_show
boolean
по умолчанию false
«Гость не пришёл»: с начала заказа до конца окна
can_undo_no_show
boolean
по умолчанию false
Снять отметку неявки: до конца того же окна
no_show_opens_at
string (date-time) или null
Плановое начало: раньше неявку не отмечают
no_show_closes_at
string (date-time) или null
Конец окна неявки: окончание + часы booking_autoclose_hours
auto_complete_at
string (date-time) или null
Когда выход впечатления, услуги или еды завершится сам; у жилья и проката пусто
cancel_reason_code
string или null
cancelled_by_kind
string или null
timezone
string
обязательно
Пояс объекта: все даты брони — в нём
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
details
object
settled
object
snapshot
object
confirmed_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/no-show' \
-H 'Authorization: Bearer <access>'
DELETE/v1/bookings/<span class="text-brand-ink">{booking_id}</span>/no-show
Снять отметку неявки: бронь снова подтверждена
Нужен вход
До конца того же окна; после — 409 no_show_closed, без отметки — 409 no_show_absent.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ · BookingDetail
Поля ответа · 58
id
string (uuid)
обязательно
Идентификатор записи (UUID)
code
string
обязательно
status
string
обязательно
kind
string
обязательно
booking_kind
string
по умолчанию "nightly"
nightly / contract. У контракта сумма справочная: деньги вне сервиса
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_name
string или null
Название номера
guest_name
string или null
Имя гостя — только после подтверждения (как профиль гостя); до него и у брони без аккаунта гостя — null
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
nights
integer или null
Число ночей
starts_at
string (date-time) или null
Момент в UTC, ISO 8601
guests
integer
обязательно
Число гостей
total
MoneyBody
обязательно
Сколько всего
payout
MoneyBody
обязательно
payment_status
string
обязательно
source
string
по умолчанию "web"
web / android / ios / tgbot / partner_api / ical
respond_by
string (date-time) или null
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
lines
массив QuoteLine
обязательно
can_review_guest
boolean
по умолчанию false
guest_review
object или null
review_until
string (date-time) или null
guest_review_refusal
string или null
review_opens_at
string (date-time) или null
Момент в UTC, ISO 8601
has_guest_account
boolean
по умолчанию false
subtotal
MoneyBody или null
discount
MoneyBody или null
cleaning_fee
MoneyBody или null
extra_guest_fee
MoneyBody или null
service_fee
MoneyBody или null
tax
MoneyBody или null
guest_profile
GuestProfileBody или null
guest_history
GuestHistoryBody или null
commission
MoneyBody
обязательно
Комиссия сервиса
guest_message
string или null
partner_note
string или null
free_cancel_until
string (date-time) или null
checkin_at
string (date-time) или null
Момент в UTC, ISO 8601
checkout_at
string (date-time) или null
Момент в UTC, ISO 8601
can_check_in_now
boolean
по умолчанию true
checkin_opens_at
string (date) или null
Момент в UTC, ISO 8601
can_check_out_now
boolean
по умолчанию true
can_mark_no_show
boolean
по умолчанию false
«Гость не пришёл»: с начала заказа до конца окна
can_undo_no_show
boolean
по умолчанию false
Снять отметку неявки: до конца того же окна
no_show_opens_at
string (date-time) или null
Плановое начало: раньше неявку не отмечают
no_show_closes_at
string (date-time) или null
Конец окна неявки: окончание + часы booking_autoclose_hours
auto_complete_at
string (date-time) или null
Когда выход впечатления, услуги или еды завершится сам; у жилья и проката пусто
cancel_reason_code
string или null
cancelled_by_kind
string или null
timezone
string
обязательно
Пояс объекта: все даты брони — в нём
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
details
object
settled
object
snapshot
object
confirmed_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/bookings/{booking_id}/no-show' \
-H 'Authorization: Bearer <access>'
Долгосрочная аренда
6 эндпоинтовЗаявки и договоры аренды.
GET/v1/rentals
Сделки партнёра. По умолчанию — те, что ещё чего-то ждут
Нужен вход
Доступ. Нужно право: bookings:read.
Параметры
stage
запрос · string или null
Стадия; пусто — все открытые
limit
запрос · integer
Сколько записей на странице
offset
запрос · integer
Ответы
200Успешный ответ · RentalPage
Поля ответа · 2
items
массив RentalBrief
обязательно
Записи страницы
total
integer
обязательно
Сколько всего
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/rentals' \
-H 'Authorization: Bearer <access>'
GET/v1/rentals/<span class="text-brand-ink">{booking_id}</span>
Одна сделка целиком: условия, номер с датами, договор, подпись
Нужен вход
Доступ. Нужно право: bookings:read.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ · RentalDetail
Поля ответа · 43
id
string (uuid)
обязательно
Идентификатор записи (UUID)
booking_id
string (uuid)
обязательно
Идентификатор брони (UUID)
stage
string
обязательно
negotiating / awaiting_document / awaiting_signatures / signed / cancelled. living / handover / completed — стадии прежнего пути: встречаются у договоров, закрытых по прежнему пути, и новыми не становятся
months
integer
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
deposit_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
document_name
string или null
document_size
integer или null
has_document
boolean
по умолчанию false
guest_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
partner_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_deadline_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_expired
boolean
по умолчанию false
Срок вышел, подписи нет: ход возвращается партнёру
deposit_paid_at
string (date-time) или null
Момент в UTC, ISO 8601
settled_at
string (date-time) или null
Момент в UTC, ISO 8601
completed_at
string (date-time) или null
Момент в UTC, ISO 8601
cancelled_at
string (date-time) или null
Момент в UTC, ISO 8601
cancel_reason
string или null
terminated_at
string (date-time) или null
Момент в UTC, ISO 8601
terminated_by
string или null
guest / partner
terminate_reason
string или null
handover_at
string (date-time) или null
Момент в UTC, ISO 8601
code
string
обязательно
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_holds_dates
boolean
по умолчанию false
Занимает ли выбранный номер даты прямо сейчас. Ложь до приложенного договора: пока это только выбор партнёра, и квартира остаётся в продаже
guest_name
string
обязательно
waiting_for
string
обязательно
guest / partner / none — чей сейчас ход
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
guest_message
string или null
guest_phone
string или null
guest_email
string или null
guest_age
integer или null
guest_citizenship
string или null
guest_emergency
string или null
guest_contacts_open
boolean
по умолчанию true
stages
массив string
Стадии в порядке жизни
units
массив UnitBrief
partner_legal_name
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/rentals/{booking_id}' \
-H 'Authorization: Bearer <access>'
POST/v1/rentals/<span class="text-brand-ink">{booking_id}</span>/term
Запомнить выбранные номер и срок — до приложения файла
Нужен вход
Подписью это не является: подпись партнёра — приложенный документ. И занятостью тоже не является: выбор хранится в самой сделке, объект остаётся в продаже, и на те же даты партнёр вправе разговаривать с кем-то ещё. В шахматке дни станут «забронировано», когда он приложит договор.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаRentalTerm · application/json
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
Ответы
200Успешный ответ · RentalDetail
Поля ответа · 43
id
string (uuid)
обязательно
Идентификатор записи (UUID)
booking_id
string (uuid)
обязательно
Идентификатор брони (UUID)
stage
string
обязательно
negotiating / awaiting_document / awaiting_signatures / signed / cancelled. living / handover / completed — стадии прежнего пути: встречаются у договоров, закрытых по прежнему пути, и новыми не становятся
months
integer
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
deposit_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
document_name
string или null
document_size
integer или null
has_document
boolean
по умолчанию false
guest_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
partner_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_deadline_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_expired
boolean
по умолчанию false
Срок вышел, подписи нет: ход возвращается партнёру
deposit_paid_at
string (date-time) или null
Момент в UTC, ISO 8601
settled_at
string (date-time) или null
Момент в UTC, ISO 8601
completed_at
string (date-time) или null
Момент в UTC, ISO 8601
cancelled_at
string (date-time) или null
Момент в UTC, ISO 8601
cancel_reason
string или null
terminated_at
string (date-time) или null
Момент в UTC, ISO 8601
terminated_by
string или null
guest / partner
terminate_reason
string или null
handover_at
string (date-time) или null
Момент в UTC, ISO 8601
code
string
обязательно
listing_id
string (uuid)
обязательно
Идентификатор объекта (UUID)
listing_title
string
обязательно
Название объекта на языке ответа
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
unit_holds_dates
boolean
по умолчанию false
Занимает ли выбранный номер даты прямо сейчас. Ложь до приложенного договора: пока это только выбор партнёра, и квартира остаётся в продаже
guest_name
string
обязательно
waiting_for
string
обязательно
guest / partner / none — чей сейчас ход
thread_id
string (uuid) или null
Идентификатор переписки (UUID)
guest_message
string или null
guest_phone
string или null
guest_email
string или null
guest_age
integer или null
guest_citizenship
string или null
guest_emergency
string или null
guest_contacts_open
boolean
по умолчанию true
stages
массив string
Стадии в порядке жизни
units
массив UnitBrief
partner_legal_name
string или null
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/rentals/{booking_id}/term' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"unit_id": "00000000-0000-0000-0000-000000000000", "date_from": "2026-11-02"}'
GET/v1/rentals/<span class="text-brand-ink">{booking_id}</span>/document
Договор потоком. Прямой ссылки на приватный файл не существует
Нужен вход
Доступ. Нужно право: bookings:read.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Ответы
200Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/rentals/{booking_id}/document' \
-H 'Authorization: Bearer <access>'
POST/v1/rentals/<span class="text-brand-ink">{booking_id}</span>/document
Прикладывает договор и закрепляет за ним номер с датами
Нужен вход
Одно действие, а не два. В бумаге стоит конкретная квартира и конкретный срок; если в системе они другие, подпись гостя подтверждает не тот договор. С этой минуты номер занят, а гостю даётся семь дней на подпись.
Замена файла начинает семь дней заново и снимает подпись гостя, если она была: подпись относится к тому тексту, который человек читал, и сохранить её под новым файлом значило бы получить согласие на документ, которого никто не видел.
Занятый номер отвечает 409 dates_unavailable — тем же кодом, что и посуточная бронь: занятость у них одна и та же.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаBody_upload_document_v1_rentals__booking_id__document_post · multipart/form-data
file
string
обязательно
unit_id
string (uuid) или null
Идентификатор номера (единицы номерного фонда) (UUID)
date_from
string (date) или null
Первый день в поясе объекта, без времени и пояса (YYYY-MM-DD). Интервал полуоткрытый: [date_from, date_to)
date_to
string (date) или null
День после последнего в поясе объекта, без времени и пояса (YYYY-MM-DD): для жилья — день выезда, он свободен
Ответы
200Успешный ответ · RentalBody
Поля ответа · 23
id
string (uuid)
обязательно
Идентификатор записи (UUID)
booking_id
string (uuid)
обязательно
Идентификатор брони (UUID)
stage
string
обязательно
negotiating / awaiting_document / awaiting_signatures / signed / cancelled. living / handover / completed — стадии прежнего пути: встречаются у договоров, закрытых по прежнему пути, и новыми не становятся
months
integer
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
deposit_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
document_name
string или null
document_size
integer или null
has_document
boolean
по умолчанию false
guest_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
partner_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_deadline_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_expired
boolean
по умолчанию false
Срок вышел, подписи нет: ход возвращается партнёру
deposit_paid_at
string (date-time) или null
Момент в UTC, ISO 8601
settled_at
string (date-time) или null
Момент в UTC, ISO 8601
completed_at
string (date-time) или null
Момент в UTC, ISO 8601
cancelled_at
string (date-time) или null
Момент в UTC, ISO 8601
cancel_reason
string или null
terminated_at
string (date-time) или null
Момент в UTC, ISO 8601
terminated_by
string или null
guest / partner
terminate_reason
string или null
handover_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/rentals/{booking_id}/document' \
-H 'Authorization: Bearer <access>' \
-F 'file=@photo.jpg'
POST/v1/rentals/<span class="text-brand-ink">{booking_id}</span>/cancel
Отмена сделки партнёром — до подписи гостя
Нужен вход
После подписи договор заключён между сторонами, и расторгают его они сами: сервис не сторона этой бумаги. Такой вызов отвечает 409 already_signed.
Доступ. Нужно право: bookings:write.
Параметры
booking_id
путь · string (uuid)
обязательно
Идентификатор брони (UUID)
Тело запросаRentalCancel · application/json
reason
string или null
Ответы
200Успешный ответ · RentalBody
Поля ответа · 23
id
string (uuid)
обязательно
Идентификатор записи (UUID)
booking_id
string (uuid)
обязательно
Идентификатор брони (UUID)
stage
string
обязательно
negotiating / awaiting_document / awaiting_signatures / signed / cancelled. living / handover / completed — стадии прежнего пути: встречаются у договоров, закрытых по прежнему пути, и новыми не становятся
months
integer
обязательно
price_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
deposit_minor
integer
обязательно
Сумма в минорных единицах валюты (currency): у бата и рубля — сотые, 150000 = 1 500,00. Считает сервер
currency
string
обязательно
Код валюты ISO 4217 (THB, RUB, USD…)
document_name
string или null
document_size
integer или null
has_document
boolean
по умолчанию false
guest_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
partner_signed_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_deadline_at
string (date-time) или null
Момент в UTC, ISO 8601
sign_expired
boolean
по умолчанию false
Срок вышел, подписи нет: ход возвращается партнёру
deposit_paid_at
string (date-time) или null
Момент в UTC, ISO 8601
settled_at
string (date-time) или null
Момент в UTC, ISO 8601
completed_at
string (date-time) или null
Момент в UTC, ISO 8601
cancelled_at
string (date-time) или null
Момент в UTC, ISO 8601
cancel_reason
string или null
terminated_at
string (date-time) или null
Момент в UTC, ISO 8601
terminated_by
string или null
guest / partner
terminate_reason
string или null
handover_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/rentals/{booking_id}/cancel' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"reason": "…"}'
Финансы
4 эндпоинтаНачисления, удержания, выплаты, выгрузка.
GET/v1/finance/summary
Заработано, удержано сервисом, к выплате — по каждой валюте отдельно
Нужен вход
Считаются только оплаченные брони. Подтверждённая, но неоплаченная денег не приносит: гость ещё может не заплатить, и показывать её в «к выплате» значит обещать чужие деньги.
Доступ. Нужно право: finance:read.
Параметры
from
запрос · string (date) или null
to
запрос · string (date) или null
Ответы
200Успешный ответ · FinanceSummary
Поля ответа · 1
totals
массив CurrencyTotals
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/finance/summary' \
-H 'Authorization: Bearer <access>'
GET/v1/finance/operations
Построчно: что заплатил гость и что остаётся партнёру
Нужен вход
Доступ. Нужно право: finance:read.
Список страницами. Ответ отдаёт next_cursor; следующую страницу просите с ним в cursor. has_more: false или нет курсора — список кончился.
Параметры
from
запрос · string (date) или null
to
запрос · string (date) или null
limit
запрос · integer или null
Сколько записей на странице
cursor
запрос · string или null
Курсор из next_cursor прошлого ответа; без него — первая страница
Ответы
200Успешный ответ · OperationPage
Поля ответа · 3
items
массив Operation
обязательно
Записи страницы
next_cursor
string или null
Курсор следующей страницы: передайте его в cursor. Нет — страница последняя. Непрозрачен: не разбирайте и не собирайте руками
has_more
boolean
по умолчанию false
Есть ли следующая страница
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/finance/operations' \
-H 'Authorization: Bearer <access>'
GET/v1/finance/export
Те же операции файлом CSV — для бухгалтерии и сверки с выпиской
Нужен вход
Формат намеренно скучный: суммы минорными единицами и валюта отдельной колонкой. Отформатированная сумма («1 200 ฿») в таблице превращается в текст, который не складывается, и разбирать её обратно пришлось бы руками.
BOM в начале файла стоит ради Excel: без него он открывает UTF-8 в системной кодировке, и названия объектов на русском и тайском превращаются в мусор. Разделитель — точка с запятой по той же причине: Excel в русской локали считает запятую десятичным знаком и раскладывает строку не по тем колонкам.
Доступ. Нужно право: finance:read.
Параметры
from
запрос · string (date) или null
to
запрос · string (date) или null
Ответы
200Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/finance/export' \
-H 'Authorization: Bearer <access>'
GET/v1/finance/payouts
История выплат. Сами выплаты делает администрация
Нужен вход
Доступ. Нужно право: finance:read.
Ответы
200Успешный ответ · PayoutList
Поля ответа · 1
items
массив PayoutBody
Записи страницы
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/finance/payouts' \
-H 'Authorization: Bearer <access>'
Чат
9 эндпоинтовПереписка с гостями и поддержкой; сокет /v1/ws принимает и ключ API.
GET/v1/dialogs
Диалоги бизнеса, свежие сверху
Нужен вход
Доступ. Нужно право: chat:read.
Ответы
200Успешный ответ · DialogList
Поля ответа · 1
items
массив DialogBody
обязательно
Записи страницы
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/dialogs' \
-H 'Authorization: Bearer <access>'
POST/v1/dialogs/support
Обращение в поддержку. Открытое обращение у бизнеса одно
Нужен вход
Доступ. Нужно право: chat:write.
Тело запросаSupportOpen · application/json
subject
string или null
Ответы
200Успешный ответ · DialogBody
Поля ответа · 14
id
string (uuid)
обязательно
Идентификатор записи (UUID)
kind
string
обязательно
status
string
обязательно
subject
string или null
listing_id
string (uuid) или null
Объект ленты заказа (booking); у переписки с гостем — null: она одна на гостя
listing_title
string или null
Название объекта на языке ответа
booking_id
string (uuid) или null
Идентификатор брони (UUID)
guest_name
string или null
unread
integer
по умолчанию 0
last_message_at
string (date-time) или null
Момент в UTC, ISO 8601
last_message_preview
string или null
last_event_code
string или null
last_event_payload
object
contacts_hidden
boolean
по умолчанию false
Всегда false: контакты не скрываются, поле — ради старых клиентов
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/dialogs/support' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"subject": "…"}'
GET/v1/dialogs/<span class="text-brand-ink">{dialog_id}</span>/messages
Лента переписки. before_id — вверх по истории, after_id — вперёд
Нужен вход
Второй курсор нужен экрану, у которого не открылся сокет: он догоняет пропущенное, а не перечитывает весь разговор каждые несколько секунд.
Доступ. Нужно право: chat:read.
Параметры
dialog_id
путь · string (uuid)
обязательно
Идентификатор диалога (UUID)
before_id
запрос · integer или null
after_id
запрос · integer или null
limit
запрос · integer
Сколько записей на странице
Ответы
200Успешный ответ · MessagePage
Поля ответа · 2
items
массив MessageBody
обязательно
Записи страницы
has_more
boolean
по умолчанию false
Есть ли следующая страница
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/dialogs/{dialog_id}/messages' \
-H 'Authorization: Bearer <access>'
POST/v1/dialogs/<span class="text-brand-ink">{dialog_id}</span>/messages
Отправить сообщение в диалог
Нужен вход
Текст до 4000 символов или файл: сначала загрузка POST /v1/uploads, потом сообщение с её upload_id. reply_to_id — ответ на сообщение. Пустое сообщение — 400; слишком часто — 429. Перевод для собеседника приходит после ответа событием в сокете.
Доступ. Нужно право: chat:write.
Параметры
dialog_id
путь · string (uuid)
обязательно
Идентификатор диалога (UUID)
Тело запросаMessageSend · application/json
text
string или null
upload_id
string (uuid) или null
reply_to_id
integer или null
Ответы
200Успешный ответ · MessageBody
Поля ответа · 26
id
integer
обязательно
Идентификатор записи (UUID)
dialog_id
string (uuid)
обязательно
Идентификатор диалога (UUID)
sender_kind
string
обязательно
sender_id
string (uuid) или null
type
string
обязательно
text
string или null
Что показывать: перевод, если он есть, иначе оригинал
text_original
string или null
Как написал человек. Заполнено, только когда есть перевод
translated
boolean
по умолчанию false
Текст показан в переводе
lang
string или null
Язык: en, ru, th или zh-Hans
contacts_hidden
boolean
по умолчанию false
Всегда false: контакты не скрываются, поле — ради старых клиентов
is_official
boolean
по умолчанию false
Сообщение администрации
links
массив MessageLink
Ссылки показанного текста text
listing_id
string (uuid) или null
Объект, с которого гость написал
listing
ListingCard или null
Карточка этого объекта
links_original
массив MessageLink
Ссылки оригинала text_original, когда есть перевод
system_code
string или null
payload
object
reply_to_id
integer или null
file_url
string или null
file_name
string или null
file_size
integer или null
duration_sec
integer или null
width
integer или null
Ширина, px
height
integer или null
Высота, px
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
read_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/dialogs/{dialog_id}/messages' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"text": "…", "upload_id": "00000000-0000-0000-0000-000000000000"}'
DELETE/v1/dialogs/<span class="text-brand-ink">{dialog_id}</span>/messages/<span class="text-brand-ink">{message_id}</span>
Убирает СВОЁ сообщение из переписки
Нужен вход
Сотрудник написал не то и хочет это убрать — обычное дело. Из базы сообщение при этом не пропадает: спор о броне разбирается через месяцы, и «партнёр удалил сообщение» не должно означать «доказательств нет».
Сообщение принадлежит бизнесу, а не тому, кто его отправил: убрать чужую опечатку может любой, у кого есть право писать. Иначе уволившийся сотрудник оставлял бы неудаляемые следы.
Доступ. Нужно право: chat:write.
Параметры
dialog_id
путь · string (uuid)
обязательно
Идентификатор диалога (UUID)
message_id
путь · integer
обязательно
Идентификатор сообщения (UUID)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/dialogs/{dialog_id}/messages/{message_id}' \
-H 'Authorization: Bearer <access>'
POST/v1/dialogs/<span class="text-brand-ink">{dialog_id}</span>/files
Пакет документов: до десяти файлов и двадцать мегабайт суммарно
Нужен вход
Каждый файл сначала загружается обычным POST /v1/uploads, а сюда приходят их идентификаторы. Отправка одна: для человека это одно действие, и в переписке оно должно выглядеть одним событием.
Лимит скорости — тот же, что у сообщений: пакет считается одной отправкой, иначе десять файлов упирались бы в секундный потолок на середине.
Доступ. Нужно право: chat:write.
Параметры
dialog_id
путь · string (uuid)
обязательно
Идентификатор диалога (UUID)
Тело запросаFilesSend · application/json
upload_ids
массив string (uuid)
обязательно
Ответы
200Успешный ответ · массив MessageBody
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/dialogs/{dialog_id}/files' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"upload_ids": ["00000000-0000-0000-0000-000000000000"]}'
POST/v1/dialogs/<span class="text-brand-ink">{dialog_id}</span>/read
Отметить прочитанным всё до сообщения up_to_id включительно
Нужен вход
Доступ. Нужно право: chat:write.
Параметры
dialog_id
путь · string (uuid)
обязательно
Идентификатор диалога (UUID)
Тело запросаapp__schemas__chat__ReadRequest · application/json
up_to_id
integer или null
Ответы
200Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/dialogs/{dialog_id}/read' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"up_to_id": 0}'
POST/v1/uploads
Вложение до отправки сообщения: в сокет файлы не летят
Нужен вход
Доступ. Нужно право: chat:write.
Тело запросаBody_upload_v1_uploads_post · multipart/form-data
kind
string
обязательно
photo / voice / document
file
string
обязательно
Ответы
200Успешный ответ · UploadResponse
Поля ответа · 6
id
string (uuid)
обязательно
Идентификатор записи (UUID)
type
string
обязательно
file_name
string или null
file_size
integer или null
duration_sec
integer или null
Длительность голосового в секундах — измеряется при загрузке
url
string или null
Только для фотографий: они лежат в публичном бакете. Голос и документы отдаются потоком через /v1/media
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/uploads' \
-H 'Authorization: Bearer <access>' \
-F 'file=@photo.jpg'
GET/v1/messages/<span class="text-brand-ink">{message_id}</span>/file
Приватное вложение диалога: голосовое или документ гостя
Нужен вход
Отдаётся потоком после проверки прав, а не ссылкой: файл лежит в приватном бакете, и ссылка из истории браузера без действующей сессии сотрудника этого бизнеса ничего не откроет.
Доступ. Нужно право: chat:read.
Параметры
message_id
путь · integer
обязательно
Идентификатор сообщения (UUID)
Ответы
200Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/messages/{message_id}/file' \
-H 'Authorization: Bearer <access>'
Уведомления
6 эндпоинтовЛента уведомлений бизнеса; устройства для пушей — только человеку.
GET/v1/notifications
Лента бизнеса: ключи и параметры, тексты собирает кабинет
Нужен вход
Список страницами. Ответ отдаёт next_cursor; следующую страницу просите с ним в cursor. has_more: false или нет курсора — список кончился.
Параметры
cursor
запрос · string или null
Курсор из next_cursor прошлого ответа; без него — первая страница
limit
запрос · integer или null
Сколько записей на странице
entity_id
запрос · string (uuid) или null
Ответы
200Успешный ответ · NotificationPage
Поля ответа · 4
items
массив NotificationBody
обязательно
Записи страницы
next_cursor
string или null
Курсор следующей страницы: передайте его в cursor. Нет — страница последняя. Непрозрачен: не разбирайте и не собирайте руками
has_more
boolean
по умолчанию false
Есть ли следующая страница
unread
integer
по умолчанию 0
Сколько непрочитанных всего
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/notifications' \
-H 'Authorization: Bearer <access>'
POST/v1/notifications/read
Прочитано — для всего бизнеса сразу
Нужен вход
Так и должно быть: если запрос увидел администратор на стойке, второй раз он никого не касается — на него уже ответили.
Тело запросаapp__schemas__notifications__ReadRequest · application/json
up_to_id
integer или null
Без него прочитанным считается всё
Ответы
200Успешный ответ · object
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/notifications/read' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"up_to_id": 0}'
GET/v1/devices
Устройства человека, куда сейчас уходят пуши: с действующей сессией
Нужен вход
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Ответы
200Успешный ответ · массив DeviceBody
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/devices' \
-H 'Authorization: Bearer <access>'
POST/v1/devices
Пуш-токен устройства, на котором человек работает в кабинете
Нужен вход
Устройство записывается на человека и его сессию, а не на бизнес: пуш о броне уходит каждому сотруднику с правом на брони — на те устройства, где он работает именно в этом бизнесе. Вышел или переключил бизнес (новая сессия) — устройство переписывается на новую сессию при следующей отправке токена. Повторный запуск — обновление.
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Тело запросаDeviceRegister · application/json
push_token
string
обязательно
Токен пушей устройства (Firebase Cloud Messaging)
platform
string
обязательно
android / ios / web
app_version
string или null
Версия клиента, который прислал запрос
language
string или null
Язык: en, ru, th или zh-Hans
timezone
string или null
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
Ответы
200Успешный ответ · DeviceBody
Поля ответа · 8
id
string (uuid)
обязательно
Идентификатор записи (UUID)
platform
string
обязательно
Платформа клиента: web, android, ios, …
app_version
string или null
Версия клиента, который прислал запрос
language
string или null
Язык: en, ru, th или zh-Hans
timezone
string или null
Часовой пояс IANA, например Asia/Bangkok; календарные даты объекта — в нём
current
boolean
по умолчанию false
Устройство этой сессии
created_at
string (date-time) или null
Момент в UTC, ISO 8601
last_seen_at
string (date-time) или null
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/devices' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"push_token": "…", "platform": "…"}'
POST/v1/devices/forget
Выключить пуши на этом устройстве — по его токену
Нужен вход
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Тело запросаDeviceForget · application/json
push_token
string
обязательно
Токен пушей устройства (Firebase Cloud Messaging)
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/devices/forget' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"push_token": "…"}'
DELETE/v1/devices/<span class="text-brand-ink">{device_id}</span>
Отключает устройство от пушей. Строка остаётся
Нужен вход
Доступ. только сотрудник после входа паролем — ключу API и приложению закрыто.
Параметры
device_id
путь · string (uuid)
обязательно
Ответы
204Успешный ответ
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Действие недоступно — api_key_forbidden
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X DELETE 'https://partner-api.bounty.travel/v1/devices/{device_id}' \
-H 'Authorization: Bearer <access>'
Отзывы
3 эндпоинтаОтзывы об объектах и ответы на них.
GET/v1/reviews
Отзывы гостей о моих объектах — только опубликованные
Нужен вход
Доступ. Нужно право: reviews:read.
Список страницами. Ответ отдаёт next_cursor; следующую страницу просите с ним в cursor. has_more: false или нет курсора — список кончился.
Параметры
listing_id
запрос · string (uuid) или null
Идентификатор объекта (UUID)
cursor
запрос · string или null
Курсор из next_cursor прошлого ответа; без него — первая страница
limit
запрос · integer или null
Сколько записей на странице
Ответы
200Успешный ответ · ReviewPage
Поля ответа · 3
items
массив ReviewBody
обязательно
Записи страницы
next_cursor
string или null
Курсор следующей страницы: передайте его в cursor. Нет — страница последняя. Непрозрачен: не разбирайте и не собирайте руками
has_more
boolean
по умолчанию false
Есть ли следующая страница
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/reviews' \
-H 'Authorization: Bearer <access>'
POST/v1/reviews
Отзыв о госте по закончившейся оплаченной брони
Нужен вход
Публикуется сразу: гость получает «Бизнес оставил о вас отзыв» и может пожаловаться, но не ответить. Чужая бронь — «не найдено», а не «нельзя»: второе подтверждало бы, что такая бронь существует.
Доступ. Нужно право: reviews:write.
Тело запросаReviewCreate · application/json
booking_id
string (uuid)
обязательно
Идентификатор брони (UUID)
rating
integer
обязательно
Общая оценка 1–5
scores
object
Критерии партнёра: rules, tidiness. Чужие отбрасываются молча
text
string или null
Ответы
201Успешный ответ · ReviewBody
Поля ответа · 15
id
string (uuid)
обязательно
Идентификатор записи (UUID)
booking_id
string (uuid)
обязательно
Идентификатор брони (UUID)
author_kind
string
обязательно
listing_id
string (uuid) или null
Идентификатор объекта (UUID)
rating
integer
обязательно
scores
object
text
string или null
status
string
обязательно
published_at
string (date-time) или null
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
reply
ReplyBody или null
author_name
string или null
Имя гостя без фамилии — как отзыв подписан на сайте
edited_at
string (date-time) или null
Когда гость поправил опубликованный отзыв
edit_until
string (date-time) или null
До какого момента гость ещё может поправить отзыв: 48 часов и до ответа
is_new
boolean
по умолчанию false
Опубликован меньше суток назад и без ответа
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/reviews' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"booking_id": "00000000-0000-0000-0000-000000000000", "rating": 0}'
POST/v1/reviews/<span class="text-brand-ink">{review_id}</span>/reply
Ответ на отзыв гостя. Один — переписка для этого есть в чате
Нужен вход
Доступ. Нужно право: reviews:write.
Параметры
review_id
путь · string (uuid)
обязательно
Идентификатор отзыва (UUID)
Тело запросаReplyRequest · application/json
text
string
обязательно
Ответы
200Успешный ответ · ReviewBody
Поля ответа · 15
id
string (uuid)
обязательно
Идентификатор записи (UUID)
booking_id
string (uuid)
обязательно
Идентификатор брони (UUID)
author_kind
string
обязательно
listing_id
string (uuid) или null
Идентификатор объекта (UUID)
rating
integer
обязательно
scores
object
text
string или null
status
string
обязательно
published_at
string (date-time) или null
Момент в UTC, ISO 8601
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
reply
ReplyBody или null
author_name
string или null
Имя гостя без фамилии — как отзыв подписан на сайте
edited_at
string (date-time) или null
Когда гость поправил опубликованный отзыв
edit_until
string (date-time) или null
До какого момента гость ещё может поправить отзыв: 48 часов и до ответа
is_new
boolean
по умолчанию false
Опубликован меньше суток назад и без ответа
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Не хватает прав — role_required; нужное право — в details.required
404Нет такого объекта или он вам не принадлежит — not_found
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/reviews/{review_id}/reply' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"text": "…"}'
Жалобы
2 эндпоинтаЖалобы партнёра на гостя и объявления.
GET/v1/report-reasons
Причины для вида цели — в порядке формы, «другое» последним
Без входа
Параметры
target_kind
запрос · user | review
Ответы
200Успешный ответ · массив ReportReason
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X GET 'https://partner-api.bounty.travel/v1/report-reasons'
POST/v1/reports
Жалоба на гостя своей брони или на отзыв о своём бизнесе
Нужен вход
Почта подтверждена
Тело запросаReportCreate · application/json
target_kind
user | review
обязательно
target_id
string (uuid) или null
Идентификатор цели (UUID)
booking_id
string (uuid) или null
Идентификатор брони (UUID)
reason_code
string
обязательно
Машинный код причины
comment
string или null
Комментарий
Ответы
201Успешный ответ · ReportAccepted
Поля ответа · 4
id
string (uuid)
обязательно
Идентификатор записи (UUID)
status
string
обязательно
repeated
boolean
обязательно
created_at
string (date-time)
обязательно
Момент в UTC, ISO 8601
400Неверные параметры или тело запроса — validation_error; в details.fields — какие поля
401Нет входа, токен истёк или сессия закрыта — unauthorized. Обновите пару POST /v1/auth/refresh и повторите; не вышло — на вход
403Вход есть, но действие недоступно: почта не подтверждена — email_not_confirmed, аккаунт ограничен — account_restricted, нет прав — forbidden
429Слишком часто — rate_limited. Подождите столько секунд, сколько в заголовке Retry-After
500Сбой на стороне сервиса — internal_error; request_id — для поддержки
Пример
curl -X POST 'https://partner-api.bounty.travel/v1/reports' \
-H 'Authorization: Bearer <access>' \
-H 'Content-Type: application/json' \
-d '{"target_kind": "user", "reason_code": "…"}'