---
slug: "ostrovok-etg"
name: "Островок — ETG API (RateHawk)"
vendor: "Emerging Travel Group (Островок)"
industry: "travel"
docsUrl: "https://docs.emergingtravel.com/docs/overview/"
version: 2
updatedAt: "2026-10-24"
---

# Островок — ETG API (RateHawk)

Отрасль: Путешествия и транспорт. Актуально на 2026-10-24.

API Emerging Travel Group (Островок, RateHawk) версии V3 для бронирования отелей: поиск цен по региону, отелям или координатам, страница отеля со всеми тарифами, предбронирование, создание и завершение бронирования, проверка статуса, отмена, статический контент и дампы отелей. Есть B2B API (для турагентств) и Affiliate API; здесь — основные методы B2B. Перед использованием нужен договор, после интеграции может потребоваться сертификация.

## Сценарии

### Найти отели и цены в городе

Поиск отелей на даты поездки: от строки «Сочи» до списка отелей с ценами и всех тарифов выбранного отеля.

1. Найди регион по названию: POST /api/b2b/v3/search/multicomplete/ с query (часть названия) и language. В ответе — до 5 регионов и отелей; возьми id нужного региона.
2. Запроси цены по региону: POST /api/b2b/v3/search/serp/region/ с region_id, checkin, checkout, guests (adults и возраст детей по каждому номеру), residency (гражданство гостей), currency и language. Фильтры — filter.star_rating, filter.meal_type, filter.price_from / filter.price_to, размер выдачи — hotels_limit.
3. Не давай пользователю выбирать тариф прямо из выдачи по региону: совпадение с тарифами страницы отеля не гарантируется.
4. Когда пользователь выбрал отель, запроси все его тарифы: POST /api/b2b/v3/search/hp/ с hid (числовой ID отеля), теми же датами, гостями и residency. Тариф живёт около 30 минут — по истечении повтори запрос.
5. Авторизация — HTTP Basic: KEY_ID как имя пользователя, API_KEY как пароль. Отлаживай на песочнице api-sandbox.ratehawk.com.

```bash
AUTH='<KEY_ID>:<API_KEY>'
API=https://api.ratehawk.com/api/b2b/v3

curl --user "$AUTH" "$API/search/multicomplete/" -H 'Content-Type: application/json' \
  -d '{"query": "Сочи", "language": "ru"}'

curl --user "$AUTH" "$API/search/serp/region/" -H 'Content-Type: application/json' \
  -d '{"checkin": "2026-11-20", "checkout": "2026-11-23", "residency": "ru", "language": "ru",
       "guests": [{"adults": 2, "children": []}], "region_id": <region_id>, "currency": "RUB",
       "hotels_limit": 50, "filter": {"star_rating": [4, 5]}}'

curl --user "$AUTH" "$API/search/hp/" -H 'Content-Type: application/json' \
  -d '{"hid": <hid>, "checkin": "2026-11-20", "checkout": "2026-11-23", "residency": "ru",
       "language": "ru", "guests": [{"adults": 2, "children": []}], "currency": "RUB"}'
```

### Забронировать номер

Полный путь брони после выбора тарифа: проверка доступности, создание брони, запуск и ожидание подтверждения.

1. Проверь тариф перед бронью: POST /api/b2b/v3/hotel/prebook/ с hash — ID тарифа со страницы отеля — и price_increase_percent, если готов принять небольшой рост цены. Если тариф ушёл, API подберёт альтернативу с тем же типом номера и питанием и вернёт новый hash. Таймаут клиента — не меньше 30 секунд, лучше 60.
2. Сразу после prebook создай бронь: POST /api/b2b/v3/hotel/order/booking/form/ с partner_order_id (свой UUID, уникальный в рамках договора), book_hash из ответа prebook, language и user_ip конечного пользователя. Форма живёт 60 минут; в ответе — доступные способы оплаты.
3. Запусти бронирование: POST /api/b2b/v3/hotel/order/booking/finish/ с partner.partner_order_id, payment_type (type, amount, currency_code — из способов оплаты формы), rooms[].guests (first_name, last_name), user.email и user.phone менеджера.
4. Бронь асинхронная: опрашивай POST /api/b2b/v3/hotel/order/booking/finish/status/ с partner_order_id, пока статус не станет финальным (или подключи вебхук статуса). При оплате картой с 3D Secure в ответе придёт data_3ds.
5. Брони тестового отеля hid = 8473727 на test-ключе настоящие — после проверки их нужно отменить.

```python
import time, uuid, requests

API = "https://api.ratehawk.com/api/b2b/v3"
s = requests.Session()
s.auth = ("<KEY_ID>", "<API_KEY>")
s.headers["User-Agent"] = "MyTravelApp/1.0"

def call(path, body, timeout=60):
    r = s.post(f"{API}/{path}", json=body, timeout=timeout)
    r.raise_for_status()
    return r.json()

pre = call("hotel/prebook/", {"hash": rate_hash, "price_increase_percent": 5})
book_hash = pre["data"]["hotels"][0]["rates"][0]["book_hash"]

order_id = str(uuid.uuid4())
form = call("hotel/order/booking/form/", {"partner_order_id": order_id, "book_hash": book_hash,
                                          "language": "ru", "user_ip": client_ip})
pay = form["data"]["payment_types"][0]

call("hotel/order/booking/finish/", {
    "language": "ru",
    "partner": {"partner_order_id": order_id},
    "payment_type": {"type": pay["type"], "amount": pay["amount"], "currency_code": pay["currency_code"]},
    "rooms": [{"guests": [{"first_name": "Ivan", "last_name": "Petrov"}]}],
    "user": {"email": "manager@example.ru", "phone": "+79990001122"},
})

while True:
    st = call("hotel/order/booking/finish/status/", {"partner_order_id": order_id})
    if st["status"] != "processing":
        break
    time.sleep(5)
print(st["status"], st.get("data"))
```

### Отменить бронирование

Отмена по запросу гостя — с проверкой, во что она обойдётся.

1. Отменить можно только подтверждённую бронь: POST /api/b2b/v3/hotel/order/cancel/ с partner_order_id — тем же ID, что ты передавал при бронировании.
2. В ответе amount_payable — сумма штрафа и валюта. Для невозвратного тарифа штраф реальный, поэтому показывай условия отмены пользователю до вызова.
3. Апсейлы (ранний заезд, поздний выезд) автоматически не отменяются — учитывай их отдельно.

```bash
curl --user '<KEY_ID>:<API_KEY>' 'https://api.ratehawk.com/api/b2b/v3/hotel/order/cancel/' \
  -H 'Content-Type: application/json' \
  -d '{"partner_order_id": "9b2f6c1e-5d4a-4f7e-8c3b-1a2d3e4f5a6b"}'
```

### Загрузить описание и фото отеля

Карточка отеля для своей витрины: описание, адрес, удобства и фотографии.

1. Запроси контент: POST /api/b2b/v3/hotel/info/ с hid и language.
2. Лимит — не больше 30 запросов за 60 секунд, поэтому кэшируй карточки у себя, а не запрашивай их при каждом показе.
3. Передавай собственный User-Agent с названием своего приложения — без него запросы могут отклоняться.
4. Для полной базы отелей используй дампы статического контента, а hotel/info — для точечного обновления.

```bash
curl --user '<KEY_ID>:<API_KEY>' 'https://api.ratehawk.com/api/b2b/v3/hotel/info/' \
  -H 'Content-Type: application/json' -H 'User-Agent: MyTravelApp/1.0' \
  -d '{"hid": 8473727, "language": "ru"}'
```

## Базовые URL

- Боевой и тестовый: `https://api.ratehawk.com`
- Песочница: `https://api-sandbox.ratehawk.com`
- Старые хосты  и  устарели.: `api.worldota.net`

## Авторизация

Тип: Basic Auth

HTTP Basic Authentication ключом API вида `<KEY_ID>:<API_KEY>`: `KEY_ID` — имя пользователя, `API_KEY` — пароль. Ключи бывают трёх типов: sandbox, test (только тестовый отель `hid = 8473727`, брони реальные) и production. Ключи видны в разделе API настроек договора (доступ — у Master-аккаунта).

```
curl --user '<KEY_ID>:<KEY>' --data '{"id":"city_hotel_berlin_east","language":"en"}' "https://api.ratehawk.com/api/b2b/v3/hotel/info/"
```

## Методы

### POST /api/b2b/v3/search/multicomplete/ — Подсказки отелей и регионов

Автодополнение по части названия; до 5 результатов в каждой категории.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `query` | body | string | да | Часть названия отеля или региона |
| `language` | body | string | нет | Язык, например ru, en |

### POST /api/b2b/v3/search/serp/region/ — Поиск цен по региону

Не рекомендуется давать пользователю выбирать тарифы из этого ответа: точного совпадения с `search/hp` не гарантируется.

Также есть поиск по ID отелей (`/api/b2b/v3/search/serp/hotels/`) и по координатам.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `checkin` | body | string | да | Дата заезда, не позже 730 дней от текущей |
| `checkout` | body | string | да | Дата выезда, не позже 30 дней от заезда |
| `region_id` | body | integer | да | ID региона |
| `residency` | body | string | нет | Гражданство гостей, ISO 3166-1 alpha-2 |
| `guests` | body | array | нет | Гости по номерам |
| `guests[].adults` | body | integer | да | Число взрослых в номере |
| `guests[].children` | body | array | нет | Возраст детей |
| `currency` | body | string | нет | Валюта цен |
| `language` | body | string | нет | Язык данных отеля |
| `hotels_limit` | body | integer | нет | Максимум отелей в ответе |
| `timeout` | body | number | нет | Максимальное время поиска, секунд |
| `filter.star_rating` | body | array | нет | Звёздность 1–5 |
| `filter.kind` | body | array | нет | Тип отеля |
| `filter.meal_type` | body | string | нет | Тип питания, например all-inclusive |
| `filter.price_from` | body | integer | нет | Минимальная цена |
| `filter.price_to` | body | integer | нет | Максимальная цена |

Пример запроса:

```
curl --user '<KEY_ID>:<API_KEY>' 'https://api.ratehawk.com/api/b2b/v3/search/serp/region/' \
--header 'Content-Type: application/json' \
--data '{
 "checkin": "2026-10-22",
 "checkout": "2026-10-25",
 "residency": "gb",
 "language": "en",
 "guests": [
 {
 "adults": 2,
 "children": []
 }
 ],
 "region_id": 6053839,
 "currency": "EUR",
 "filter": {
 "star_rating": [],
 "kind": [],
 "meal_type": [
 "all-inclusive"
 ]
 }
}'
```

### POST /api/b2b/v3/search/hp/ — Страница отеля (все тарифы)

Вызывается, когда пользователь выбрал отель; рекомендуемое время жизни тарифа — 30 минут.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `hid` | body | integer | да | ID отеля (числовой); старое поле id устарело |
| `checkin` | body | string | да | Дата заезда |
| `checkout` | body | string | да | Дата выезда |
| `residency` | body | string | нет | Гражданство гостей |
| `guests[].adults` | body | integer | да | Число взрослых в номере |
| `guests[].children` | body | array | нет | Возраст детей |
| `currency` | body | string | нет | Валюта |
| `language` | body | string | нет | Язык |
| `timeout` | body | number | нет | Время поиска, секунд |
| `filter` | body | object | нет | Фильтры: star_rating, kind, meal_type, price_from, price_to |

### POST /api/b2b/v3/hotel/prebook/ — Предбронирование тарифа

Проверяет доступность тарифа перед бронированием; при недоступности ищет альтернативу того же типа номера и питания и возвращает новые `book_hash`/`match_hash`. Рекомендуемый таймаут — 60 секунд, минимальный — 30.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `hash` | body | string | да | ID тарифа |
| `price_increase_percent` | body | integer | нет | На сколько процентов допускается рост цены |

### POST /api/b2b/v3/hotel/order/booking/form/ — Создание процесса бронирования

Вызывается сразу после prebook; форма живёт 60 минут.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `partner_order_id` | body | string | да | Внешний ID брони (UUID) |
| `book_hash` | body | string | да | ID выбранного тарифа |
| `language` | body | string | да | Язык |
| `user_ip` | body | string | да | IP конечного пользователя |

### POST /api/b2b/v3/hotel/order/booking/finish/ — Запуск бронирования

Бронирование асинхронное — дальше опрашивайте статус. Невалидные данные пользователя могут попасть в стоп-лист.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `language` | body | string | да | Язык |
| `partner.partner_order_id` | body | string | да | Внешний ID брони |
| `partner.comment` | body | string | нет | Внутренний комментарий партнёра |
| `partner.amount_sell_b2b2c` | body | string | нет | Цена перепродажи в валюте договора |
| `payment_type.type` | body | string | да | Тип оплаты (например, hotel, deposit) |
| `payment_type.amount` | body | string | да | Сумма |
| `payment_type.currency_code` | body | string | да | Валюта, ISO 4217 |
| `rooms` | body | array | да | Номера |
| `rooms[].guests` | body | array | да | Гости: first_name, last_name, is_child, age |
| `user.email` | body | string | да | Email менеджера партнёра |
| `user.phone` | body | string | да | Телефон менеджера партнёра |
| `user.comment` | body | string | нет | Комментарий для отеля |
| `supplier_data` | body | object | нет | Контакты инициатора брони: first_name_original, last_name_original, email, phone |
| `arrival_datetime` | body | string | нет | Ожидаемое время прибытия |
| `return_path` | body | string | нет | URL возврата после 3D Secure |

### POST /api/b2b/v3/hotel/order/booking/finish/status/ — Проверка статуса бронирования

Обязателен, если не используется вебхук статуса бронирования; при 3D Secure в ответе приходит `data_3ds`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `partner_order_id` | body | string | да | ID брони партнёра, 1–256 символов |

### POST /api/b2b/v3/hotel/order/cancel/ — Отмена бронирования

Отменяются только успешно подтверждённые брони; при отмене невозвратного тарифа штраф реальный. Апсейлы автоматически не отменяются.

В ответе — `amount_payable` (сумма штрафа и валюта).

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `partner_order_id` | body | string | да | ID брони партнёра |

### POST /api/b2b/v3/hotel/info/ — Контент отеля

Не больше 30 запросов за 60 секунд; передавайте собственный `User-Agent`, например `RatehawkPartner/1.0 (python-requests/2.18.4)`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `hid` | body | integer | нет | Числовой ID отеля (нужен он или устаревший id) |
| `id` | body | string | нет | Устаревший строковый ID отеля |
| `language` | body | string | нет | Язык |

## Нюансы

- GET — для получения данных (параметры в `data` строки запроса), POST — для создания, изменения и удаления; тело — JSON-объект.
- Рекомендуемый поток: поиск → `search/hp` → `hotel/prebook` → `booking/form` → `booking/finish` → `booking/finish/status` (или вебхук).
- `partner_order_id` уникален в рамках договора и используется во всех вызовах после создания брони.
- Брони тестового отеля `hid = 8473727` реальные — их нужно отменять.
- В песочнице язык всегда `en`, валюта обычно USD/EUR, число тарифов ограничено 5, 3D Secure не поддерживается.
- Лимиты и доступные эндпоинты ключа — метод Retrieve endpoints; лимиты повышают только после сертификации.

## Ошибки

| Код | Описание |
|---|---|
| `invalid_params` | 400 — не переданы обязательные данные (см. debug.validation_error) |
| `decoding_json` | Тело запроса не разобрано как JSON |
| `not_allowed_host` | Запросы с вашего хоста или IP запрещены |
| `unexpected_method` | Неподдерживаемый HTTP-метод (используйте GET или POST) |

## Ограничения

Лимит задаётся на каждый эндпоинт и возвращается в заголовках: `X-RateLimit-SecondsNumber` (период, сек), `X-RateLimit-RequestsNumber` (максимум запросов за период), `X-RateLimit-Remaining` (остаток), `X-RateLimit-Reset` (окончание периода, UTC). Пример: 10 запросов в секунду.

## Источники

- [ETG API V3 — Overview](https://docs.emergingtravel.com/docs/overview/)
- [Authorization](https://docs.emergingtravel.com/docs/fundamentals/authorization/)
- [Request limits](https://docs.emergingtravel.com/docs/fundamentals/request-limits/)
- [Requests](https://docs.emergingtravel.com/docs/fundamentals/requests/)
- [Errors](https://docs.emergingtravel.com/docs/fundamentals/errors/)
- [Sandbox](https://docs.emergingtravel.com/docs/fundamentals/sandbox/)
- [Search by region](https://docs.emergingtravel.com/docs/b2b-api/hotel-search/search-by-region/)
- [Retrieve hotelpage](https://docs.emergingtravel.com/docs/b2b-api/hotel-search/retrieve-hotelpage/)
- [Prebook](https://docs.emergingtravel.com/docs/b2b-api/hotel-search/prebook-rate-from-hotelpage-step/)
- [Create booking process](https://docs.emergingtravel.com/docs/b2b-api/booking/create-booking-process/)
- [Start booking process](https://docs.emergingtravel.com/docs/b2b-api/booking/start-booking-process/)
- [Check booking process](https://docs.emergingtravel.com/docs/b2b-api/booking/check-booking-process/)
- [Cancel booking](https://docs.emergingtravel.com/docs/b2b-api/post-booking/cancel-booking/)
- [Retrieve hotel content](https://docs.emergingtravel.com/docs/b2b-api/static-content/retrieve-hotel-content/)

---

Если этого недостаточно — официальная документация: https://docs.emergingtravel.com/docs/overview/
JSON: https://mcp-everything.ru/api/integrations/ostrovok-etg. MCP: https://mcp-everything.ru/mcp
