# Островок — ETG API (RateHawk): Забронировать номер

Сценарий из mcp-everything. Актуально на 2026-10-24.

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

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"))
```

## Базовые 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/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 символов |

## Нюансы

- 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; лимиты повышают только после сертификации.

## Другие сценарии

- [Найти отели и цены в городе](https://mcp-everything.ru/integrations/ostrovok-etg/scenarios/nayti-oteli-i-tseny-v-gorode.md)
- [Отменить бронирование](https://mcp-everything.ru/integrations/ostrovok-etg/scenarios/otmenit-bronirovanie.md)
- [Загрузить описание и фото отеля](https://mcp-everything.ru/integrations/ostrovok-etg/scenarios/zagruzit-opisanie-i-foto-otelya.md)

---

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