# AITravel.az — Hotel API Guide

A concise standalone guide to the **live** AITravel.az hotel API. It exposes real contract
hotel inventory and prices from the **Sejour contract** snapshot. The API is implemented as
a Supabase Edge Function and is public, CORS-open, and needs no auth for reads.

- Site: <https://aitravel.az>
- Full agent API guide: [`agent-tools.md`](./agent-tools.md)
- MCP tools spec: [`mcp-tools-spec.md`](./mcp-tools-spec.md)

## Base URL

```
https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/hotel
```

All endpoint paths below are relative to this base URL. For example, `POST /search-prices`
means `POST https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/hotel/search-prices`.
Send and expect `Content-Type: application/json` for POST endpoints.

## Pricing rules and guarantees

> **`public_price` only.** This API returns **only `public_price`**. The provider / net /
> contract price is **never** exposed by any endpoint.

- **Markup rule:** `public_price = provider_price * 1.05` (a fixed **5% markup**).
- **Provider-price-hidden guarantee:** the provider / net price is never returned, never
  echoed, and must never be reconstructed or shown by an agent. Agents may show
  `public_price` only.
- **Approximate prices:** every `public_price` is **approximate and may change**; it is
  never a final quote. Each price-bearing response carries a `price_note` to this effect.
- **Operator confirmation required:** no endpoint books, pays, or confirms anything.
  Booking always requires **AITravel operator confirmation**. `POST /create-lead` only
  creates a draft with status `draft_pending_operator`.

## Dataset (current snapshot)

The data is a snapshot of the **Sejour contract**:

- **85 Turkey hotels.**
- **~41,877 sellable price rows.**
- Currency is mostly **EUR**.
- Check-in dates span **June–October 2026**.
- Nights available: **3, 5, 7, 10, 14**.
- Boards are mostly **All-Inclusive** variants.
- The source has **no city / stars / photos yet** — region/city mapping is pending, so
  `city` and `stars` may be `null` or approximate.

## The 5 endpoints

| # | Endpoint                     | Method | Purpose |
|---|------------------------------|--------|---------|
| 1 | `/list`                      | GET    | List the available contract hotels with light metadata. |
| 2 | `/get?id=<uuid>`             | GET    | Fetch one hotel and its sellable offers (`public_price` only). |
| 3 | `/search-prices`             | POST   | Search hotel prices by destination, dates, occupancy. |
| 4 | `/check-availability`        | POST   | Approximate availability indication for a hotel/destination. |
| 5 | `/create-lead`               | POST   | Create an operator-reviewed draft hotel request (lead). |

### 1. GET /list

Returns all contract hotels.

```json
{
  "hotels": [
    {
      "id": "0b8c5a4e-7f2d-4a1b-9c3e-2d6f8a1b4c5d",
      "name": "Example Resort & Spa",
      "country": "Turkey",
      "city": null,
      "region": "Antalya",
      "stars": null,
      "meal_types": ["All Inclusive", "Ultra All Inclusive"]
    }
  ],
  "count": 85
}
```

```bash
curl "https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/hotel/list"
```

### 2. GET /get?id=&lt;uuid&gt;

Returns one hotel and its offers. Offers expose **`public_price` only**.

```json
{
  "hotel": {
    "id": "0b8c5a4e-7f2d-4a1b-9c3e-2d6f8a1b4c5d",
    "name": "Example Resort & Spa",
    "country": "Turkey",
    "city": null,
    "region": "Antalya",
    "stars": null,
    "meal_types": ["All Inclusive"]
  },
  "offers": [
    {
      "check_in_from": "2026-07-01",
      "nights": 7,
      "room_type": "Standard Room",
      "meal_type": "All Inclusive",
      "adults": 2,
      "children": 0,
      "public_price": 1260.00,
      "currency": "EUR",
      "availability": "approximate"
    }
  ]
}
```

```bash
curl "https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/hotel/get?id=0b8c5a4e-7f2d-4a1b-9c3e-2d6f8a1b4c5d"
```

### 3. POST /search-prices

Body: `{ destination, check_in, check_out, adults, children?, children_ages?, budget?, stars?, meal_type? }`

```json
{
  "results": [
    {
      "hotel_id": "0b8c5a4e-7f2d-4a1b-9c3e-2d6f8a1b4c5d",
      "hotel_name": "Example Resort & Spa",
      "city": null,
      "region": "Antalya",
      "stars": null,
      "public_price": 1260.00,
      "currency": "EUR",
      "meal_type": "All Inclusive",
      "room_type": "Standard Room",
      "nights": 7,
      "availability": "approximate",
      "price_note": "Approximate public price; may change. Booking requires AITravel operator confirmation."
    }
  ],
  "count": 1,
  "nights": 7
}
```

```bash
curl -X POST \
  "https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/hotel/search-prices" \
  -H "Content-Type: application/json" \
  -d '{
    "destination": "Antalya",
    "check_in": "2026-07-01",
    "check_out": "2026-07-08",
    "adults": 2,
    "children": 1,
    "children_ages": [7],
    "budget": 1500,
    "meal_type": "All Inclusive"
  }'
```

### 4. POST /check-availability

Body: `{ destination | hotel_id, check_in?, check_out? }` (one of `destination` / `hotel_id`
is required).

```json
{
  "status": "approximate",
  "available": true,
  "note": "Likely available; subject to operator confirmation.",
  "price_note": "Approximate public price; may change. Booking requires AITravel operator confirmation."
}
```

```bash
curl -X POST \
  "https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/hotel/check-availability" \
  -H "Content-Type: application/json" \
  -d '{ "destination": "Antalya", "check_in": "2026-07-01", "check_out": "2026-07-08" }'
```

### 5. POST /create-lead

Body: `{ customer_name?, phone | email, hotel_id?, destination?, check_in?, check_out?, adults?, children?, selected_public_price?, notes? }`
(one of `phone` / `email` is required). Always returns a **draft** for operator review.

```json
{
  "request_id": "req_hotel_4a91",
  "status": "draft_pending_operator",
  "message": "Your hotel request was received and is pending operator confirmation.",
  "price_note": "Approximate public price; may change. Booking requires AITravel operator confirmation."
}
```

```bash
curl -X POST \
  "https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/hotel/create-lead" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_name": "Aysel",
    "phone": "+994 50 000 00 00",
    "hotel_id": "0b8c5a4e-7f2d-4a1b-9c3e-2d6f8a1b4c5d",
    "destination": "Antalya",
    "check_in": "2026-07-01",
    "check_out": "2026-07-08",
    "adults": 2,
    "children": 1,
    "selected_public_price": 1260.00,
    "notes": "All Inclusive, near the beach if possible."
  }'
```

## The `price_note` disclaimer

Every price-bearing response includes a `price_note` field carrying the standard disclaimer:

> Approximate public price; may change. Booking requires AITravel operator confirmation.

Agents should surface this disclaimer to users and must never present a `public_price` as a
final, guaranteed quote.

## Safety summary

- Agents may show **only `public_price`**; the provider / net price must **never** be shown
  or reconstructed.
- Agents must **not confirm a final booking**; booking always requires **AITravel operator
  confirmation**.
- All hotel prices are **approximate and may change**.
- Read endpoints (`/list`, `/get`, `/check-availability`, `/search-prices`) are public and
  require no authentication; `/create-lead` only creates an operator-reviewed draft.

## Languages

- **Primary language:** `az` (Azerbaijani).
- **Supported languages:** `az`, `ru`, `en`.
- Human-readable text (notes, messages) is localized where possible; structured fields
  (ids, currency codes, dates) remain stable across languages.
