Bounty API Партнёры

Открытый 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 — токен сотрудника, выбравшего бизнес, или ключ API bnt_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.

Аутентификация

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. Адреса — необязательно. Действующих ключей — не больше

  1. Владельцам бизнеса уходит письмо «Выпущен ключ 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": "…"}'