Download OpenAPI specification:
Everything you need to integrate with our B2B API: flights (search, availability, booking and ticketing) and hotels (search, rooms, booking and confirmation).
{domain} used in every path below) and your API key. Send the key on every request:Authorization: Bearer <your API key>
live_booking: false in Create Order (flights) and Save Guest Details (hotels). Test bookings go through the full flow but are never booked with the airline or the hotel.domain and agency_token variables. It contains every request of these docs, grouped like the sections below.Start with the Flights and Hotels overviews in the menu: they show each flow step by step, with the endpoints to call. Contact your account manager once you start testing or if you need anything from our side.
All endpoints except autocomplete require your API key as a Bearer token:
Authorization: Bearer <your API key>
Some endpoints must be enabled for your account. If an endpoint returns 403, contact your account manager.
live_booking: false when saving the order details (Create Order for flights, Save Guest Details for hotels).live_booking: true.Our Flights API gives you a complete B2B gateway for searching, pricing, booking, and managing flight inventory with precision. It connects your system to real-time availability, rich flight content, multi-fare handling, instant confirmations, and full booking lifecycle controls.
Built for speed, stability, and clean integration, it lets your platform deliver consistent results, automate operations, and scale without friction. Whether you are powering a B2B portal, a mobile app, or a distribution engine, this API provides the structure you need to move fast, stay reliable, and serve your customers with confidence.
| Area | What it does | Endpoints |
|---|---|---|
| Airport Autocomplete | Find airports while the user types | Airports Autocomplete |
| Booking Flow | Search, price, book, hold, pay and issue tickets | Search, Collect Results, Fare Families, Check Availability, Fare Rules, Create Order, Hold, Pay and Issue Ticket, Booking Details |
| Balance | Check your agency balance before paying | Get Balance |
| Void Ticket | Cancel freshly issued tickets with a refund to your balance | Booking Details, Validate Void, Void Ticket |
Send what the user types (airport code, airport, city or country name) and show the matching airports. Use the selected airport's IATA_CODE as departure / arrival in Search. No token needed.
User types "cai" ──▶ Airports Autocomplete ──▶ CAI · Cairo International Airport
│
▼ IATA_CODE
Search Flights (departure: CAI)
Search returns priced offers (itineraries), either all at once or progressively with mode: poll and Collect Results. Pick one, optionally choose a branded fare and read its fare rules, confirm the price with Check Availability (its response has the exact trip that will be booked; use it instead of the search result for baggage, fare basis and fare type), then create the order with the passengers. Creating the order only saves it; the PNR and tickets come from the next step. Hold it without payment if the itinerary allows (can_hold), or pay and issue the tickets right away. Ticketing runs in the background, so poll Booking Details until the PNR and tickets appear.
┌─────────────────┐
│ Search Flights │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Fare Families │ (Optional - if has_fare_families=true)
└────────┬────────┘
│
▼
┌─────────────────┐
│Check Availability│
└────────┬────────┘
│
▼
┌─────────────────┐
│ Fare Rules │ (Optional)
└────────┬────────┘
│
▼
┌─────────────────┐
│ Create Order │
└────────┬────────┘
│
▼
┌─────────────────────────┐
│ Hold Booking (Optional) │
└────────┬────────────────┘
│
▼
┌─────────────────┐
│ Pay & Issue │
│ Ticket │
└────────┬────────┘
│
▼
┌─────────────────────────────────┐
│ Poll Booking Details │
│ (every 10 min for 2 hours) │
└────────┬────────────────────────┘
│
▼
┌─────────────────┐
│ PNR & Tickets │
│ Generated │
└─────────────────┘
After payment (Pay and Issue Ticket), you must poll the Booking Details endpoint to retrieve the final booking status:
┌──────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ PayAndIssue │────▶│ Poll Booking │────▶│ Check Status │
│ Ticket │ │ Details │ │ │
└──────────────┘ └─────────────────┘ └────────┬─────────┘
│
┌────────────────────────────────┼────────────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
│ PNR & Ticket │ │ Processing │ │ No PNR/Ticket │
│ Generated │ │ (Continue │ │ after 2 hours │
│ (Confirmed) │ │ Polling) │ │ │
└──────────────┘ └──────────────┘ └────────┬─────────┘
│
▼
┌──────────────────┐
│ Mark unconfirmed │
│ Contact Supplier │
└──────────────────┘
Bookings are paid from your agency balance (in your agency currency). Check it before Pay and Issue Ticket to avoid a payment failure.
Get Balance ──▶ balance ≥ itinerary price? ──yes──▶ Pay and Issue Ticket
│
no ──▶ top up your balance first
A freshly issued ticket can be voided (cancelled as if never issued) within the airline's void window, usually the day of issue. The ticket amount is refunded to your balance minus the void fee and any airline penalties. Not every ticket can be voided through the API; Booking Details tells you which ones can.
Booking Details
│
▼
order.available_actions has { action: "void", product_id }?
│
├── no ──▶ the ticket can't be voided through the API
│
└── yes ─▶ Validate Void (optional, shows the void fee)
│
▼
Void Ticket (product_id) ──▶ refund to your balance
Endpoints are served by different services, so their paths carry different prefixes (/api/v1/agency/..., /api/v1/..., /api/v2/...). Use each path exactly as documented; the prefixes are not interchangeable.
Error responses are JSON with at least a message field. Validation errors (422) also include an errors object keyed by field name.
Get Balance, Validate Void and Void Ticket must be enabled for your account. If they return 403, contact your account manager.
Airport lookup for building the search form. Use the returned IATA_CODE as departure/arrival in Search Flights.
Searches airports by code, name, city or country. No authentication is required.
Typical use: send what the user typed as q and show the hits. Use IATA_CODE (also returned as code) in Search Flights.
filter examples:
country_code = "EG"IATA_CODE = "CAI"| q | string Text typed by the user (code, airport, city or country name) |
| filter | string Filter expression, e.g. |
| sort | Array of strings Sort rules, e.g. |
| limit | integer Default: 20 |
| offset | integer Default: 0 |
{- "q": "CAI",
- "sort": [
- "order:desc"
]
}{- "hits": [
- {
- "id": 16,
- "IATA_CODE": "GRU",
- "order": 0,
- "name": {
- "en": "Guarulhos - Governador Andre Franco Montoro International Airport",
- "ar": "مطار غوارولهوس - غوفرنادور أندريه فرانكو مونتورو الدولي"
}, - "city": {
- "code": "SAO",
- "name": {
- "en": "Sao Paulo",
- "ar": "ساو باولو"
}
}, - "country": {
- "code": "BR",
- "name": {
- "en": "Brazil",
- "ar": "البرازيل"
}
}, - "type": "airport",
- "state": "",
- "_geo": {
- "lat": -23.43194444,
- "lng": -46.46944444
}, - "code": "GRU",
- "name_en": "Guarulhos - Governador Andre Franco Montoro International Airport",
- "name_ar": "مطار غوارولهوس - غوفرنادور أندريه فرانكو مونتورو الدولي",
- "city_code": "SAO",
- "city_name_en": "Sao Paulo",
- "city_name_ar": "ساو باولو",
- "city_tier": "big",
- "city_tier_rank": 2,
- "city_touristic_score": 8,
- "country_code": "BR",
- "country_name_en": "Brazil",
- "country_name_ar": "البرازيل",
- "tier": "major",
- "tier_rank": 1
}, - {
- "id": 17,
- "IATA_CODE": "VCP",
- "order": 0,
- "name": {
- "en": "Viracopos International Airport",
- "ar": "مطار فيراكوبوس الدولي"
}, - "city": {
- "code": "CPQ",
- "name": {
- "en": "Campinas",
- "ar": "كامبيناس"
}
}, - "country": {
- "code": "BR",
- "name": {
- "en": "Brazil",
- "ar": "البرازيل"
}
}, - "type": "airport",
- "state": "",
- "_geo": {
- "lat": -23.00805556,
- "lng": -47.13472222
}, - "code": "VCP",
- "name_en": "Viracopos International Airport",
- "name_ar": "مطار فيراكوبوس الدولي",
- "city_code": "CPQ",
- "city_name_en": "Campinas",
- "city_name_ar": "كامبيناس",
- "city_tier": null,
- "city_tier_rank": null,
- "city_touristic_score": null,
- "country_code": "BR",
- "country_name_en": "Brazil",
- "country_name_ar": "البرازيل",
- "tier": "major",
- "tier_rank": 1
}
], - "query": "",
- "limit": 20,
- "offset": 0,
- "estimatedTotalHits": 1000,
- "processingTimeMs": 0
}Searches all airlines and suppliers enabled for your agency and returns every bookable offer for the requested route, dates and passengers. Supports one-way (O), round-trip (R) and multi-city (M) searches.
Set mode in the request:
search (default): the response arrives once every supplier has answered, with the full results.poll: the response arrives immediately with the search_id and no results yet. Call Collect Results with that search_id every 2-3 seconds; each call returns everything found so far (not just the new results), so replace what you show each time. Stop when status is completed (at the latest about 60 seconds after the search).Search (mode: poll) ──▶ search_id, status: progress
│
▼
Collect Results ──▶ status: progress ──▶ show results, wait 2-3 s, call again
│
└──────────▶ status: completed ──▶ final results, stop polling
Polling shows the first results within seconds instead of waiting for the slowest supplier.
Narrow the results with the optional filters object:
direct_only: true returns only non-stop itineraries (every trip is a single flight).airlines: ["SV", "MS"] returns only itineraries operated entirely by those airlines.Filters are applied to every supplier's results. Combine them as needed, e.g. direct flights on one airline.
The response is split into itineraries (the offers you show and sell) and aggregations (shared reference data). To keep the payload small, an itinerary does not repeat flight or rule details. It lists their ids, and you look them up in aggregations.
Search response
├── search_id ─────────────────────► pass as {search_id} to every next call
│
├── itineraries[] one bookable offer each
│ ├── id ────────────────────────► pass as {itinerary_id} to every next call
│ ├── prices total for all passengers
│ ├── passengers[] price per passenger type
│ ├── trips[] one per direction / leg
│ │ └── flights[] ──── ids ───┐
│ ├── rules[] ────────── ids ───┼──┐
│ ├── has_fare_families │ │ true → call Get Fare Families
│ └── can_hold │ │ true → Hold Booking is allowed
│ │ │
└── aggregations │ │ reference data shared by all itineraries
├── flights[] ◄─────────────┘ │ segment details, find by `id`
├── rules{} ◄────────────────┘ mini fare rules, keyed by id
├── passengers[] passenger types in this search
├── taxes[] tax lines (supplier dependent)
├── fares[] fare components (supplier dependent)
└── translations airport and airline names
Each itinerary is one priced, bookable combination of flights.
prices is the total for all passengers. passengers[].prices is the price for one passenger of that type.trips holds one entry per direction: 1 for one-way, 2 for round-trip, one per leg for multi-city. Each trip lists its flight segments in travel order, so a trip with several flight ids has connections.currency and already include your agency markup.bags_per_pax is the baggage breakdown per passenger type (adult, child, infant), each with check_in and cabin allowance.free_baggage and cabin_baggage are short codes for the adult (ADT) allowance only.type is REFUND, CHANGE, REVALIDATE, ...) for showing badges such as "Refundable" in results. Several itineraries can point to the same rule. When the airline gives no detail, the rule says to contact support. For the full conditions of one itinerary, call Get Fare Rules.ADT, CHI, INF).locale.has_fare_families is true, optionally call Get Fare Families to offer branded fares.| adults required | integer >= 1 Number of adult passengers (16+ years) |
| children | integer >= 0 Number of child passengers (2-16 years) |
| infants | integer >= 0 Number of infant passengers (0-2 years) |
required | Array of objects (Itinerary) |
| currency required | string Account currency code (e.g., USD) |
| locale required | string Enum: "en" "ar" Language preference (e.g., en, ar) |
| direction required | string Enum: "R" "O" "M" Flight type: R (Round Trip), O (One way), M (Multi destination) |
| cabin required | string Enum: "E" "PE" "B" "F" Cabin class: E (Economy), PE (Premium Economy), B (Business), F (First) |
object Optional filters. Omit them to get all results. | |
| mode | string Default: "search" Enum: "search" "poll"
|
{- "adults": 1,
- "infants": 0,
- "children": 0,
- "itineraries": [
- {
- "departure": "CAI",
- "arrival": "JED",
- "date": "2024-12-18"
}, - {
- "departure": "JED",
- "arrival": "CAI",
- "date": "2024-12-19"
}
], - "currency": "USD",
- "locale": "en",
- "direction": "R",
- "cabin": "E",
- "mode": "search",
- "filters": {
- "direct_only": false,
- "airlines": [
- "SV",
- "MS"
]
}
}{- "search_id": "2db5e697-0a85-4907-ba41-68de00ecec48",
- "aggregations": {
- "flights": [
- {
- "id": 900000,
- "cabin": "E",
- "departure": {
- "date": "18-12-2024",
- "time": "02:45",
- "airport": "CAI",
- "terminal": "2"
}, - "arrival": {
- "date": "18-12-2024",
- "time": "06:00",
- "airport": "JED",
- "terminal": "1"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "seats": "9",
- "meal_code": null,
- "free_baggage": "1PC",
- "flight_number": 308,
- "booking_class": "V",
- "equipment": "330",
- "fare_base": "VARTEGB4",
- "code_share": null,
- "fare_type": "PUB",
- "duration": 135,
- "fare_family_name": null,
- "fare_family_amenities": [
- {
- "type": "seat",
- "description": "BASIC SEAT",
- "free": false,
- "importance": 2
}, - {
- "type": "other",
- "description": "CHANGE FEE",
- "free": false,
- "importance": 10
}, - {
- "type": "refundable",
- "description": "REFUNDABLE FOR A FEE",
- "free": false,
- "importance": 2
}
], - "bags_per_pax": {
- "adult": {
- "check_in": {
- "quantity": 1,
- "weight": null,
- "weight_unit": null
}, - "cabin": {
- "quantity": 1,
- "weight": null,
- "weight_unit": null
}
}, - "child": {
- "check_in": {
- "quantity": null,
- "weight": null,
- "weight_unit": null
}, - "cabin": {
- "quantity": null,
- "weight": null,
- "weight_unit": null
}
}, - "infant": {
- "check_in": {
- "quantity": null,
- "weight": null,
- "weight_unit": null
}, - "cabin": {
- "quantity": null,
- "weight": null,
- "weight_unit": null
}
}
}
}
], - "taxes": [ ],
- "passengers": [
- {
- "id": 1,
- "type": "ADT"
}
], - "fares": [ ],
- "translations": {
- "airports": {
- "CAI": {
- "name": "Cairo International Airport",
- "code": "CAI",
- "city": {
- "name": "Cairo",
- "code": "CAI"
}
}, - "JED": {
- "name": "King Abdulaziz International Airport",
- "code": "JED",
- "city": {
- "name": "Jeddah",
- "code": "JED"
}
}
}, - "airlines": {
- "SV": {
- "name": "Saudia",
- "code": "SV"
}
}
}, - "rules": {
- "900000": {
- "id": 900000,
- "type": "REFUND",
- "title": "REFUND Policy",
- "description": "contact support for pricing",
- "applicable": true,
- "free": false,
- "price": null,
- "before_date": null,
- "price_description": "Please contact our support team for detailed pricing information"
}
}
}, - "itineraries": [
- {
- "id": 900000,
- "cabin_class": "E",
- "passengers": [
- {
- "id": 1,
- "prices": {
- "currency": "SAR",
- "total": 944.13,
- "base": 279.95,
- "taxes": 492.68,
- "total_currency": "SAR944.13"
}
}
], - "prices": {
- "currency": "SAR",
- "total": 1694.29,
- "base": 279.95,
- "taxes": 492.68,
- "total_currency": "SAR1,694.29"
}, - "trips": [
- {
- "id": 900000,
- "departure": "CAI",
- "arrival": "JED",
- "total_flight_time": 135,
- "flights": [
- 900000
]
}, - {
- "id": 900001,
- "departure": "JED",
- "arrival": "CAI",
- "total_flight_time": 435,
- "flights": [
- 900001,
- 900002
]
}
], - "has_fare_families": false,
- "can_hold": true,
- "last_ticketing_date": "16-12-2024 18:00",
- "last_ticketing_tz": "UTC",
- "is_refundable": false,
- "rules": [
- 900000
]
}
]
}Returns the results of a search made with mode: poll. Call it every 2-3 seconds with the search_id of the search.
Each call returns all results found so far, in the same structure as the Search response, so replace what you show each time. Keep calling while status is progress; stop when it is completed.
| search_id required | string
|
{- "search_id": "d5826b15-4ef0-45f4-80df-3b8d5f941dd6",
- "aggregations": {
- "flights": [
- {
- "id": 0,
- "cabin": "E",
- "departure": {
- "date": "string",
- "time": "string",
- "airport": "string",
- "terminal": "string"
}, - "arrival": {
- "date": "string",
- "time": "string",
- "airport": "string",
- "terminal": "string"
}, - "marketing_carrier": "string",
- "operating_carrier": "string",
- "seats": "string",
- "meal_code": "string",
- "free_baggage": "string",
- "flight_number": 0,
- "booking_class": "string",
- "equipment": "string",
- "fare_base": "string",
- "code_share": "string",
- "fare_type": "string",
- "duration": 0,
- "cabin_baggage": "string",
- "hand_baggage": "string",
- "operated_by_carrier": "string",
- "operated_flight_number": "string",
- "fare_family_name": "string",
- "fare_family_amenities": [
- {
- "type": "check_in_baggage",
- "description": "string",
- "free": true,
- "importance": 0
}
], - "bags_per_pax": {
- "adult": {
- "check_in": {
- "quantity": 0,
- "weight": 0,
- "weight_unit": "string",
- "policy": "string",
- "dimensions": "string"
}, - "cabin": {
- "quantity": 0,
- "weight": 0,
- "weight_unit": "string",
- "policy": "string",
- "dimensions": "string"
}
}, - "child": {
- "check_in": {
- "quantity": 0,
- "weight": 0,
- "weight_unit": "string",
- "policy": "string",
- "dimensions": "string"
}, - "cabin": {
- "quantity": 0,
- "weight": 0,
- "weight_unit": "string",
- "policy": "string",
- "dimensions": "string"
}
}, - "infant": {
- "check_in": {
- "quantity": 0,
- "weight": 0,
- "weight_unit": "string",
- "policy": "string",
- "dimensions": "string"
}, - "cabin": {
- "quantity": 0,
- "weight": 0,
- "weight_unit": "string",
- "policy": "string",
- "dimensions": "string"
}
}
}
}
], - "translations": {
- "airports": {
- "property1": {
- "name": "string",
- "code": "string",
- "city": {
- "name": "string",
- "code": "string"
}
}, - "property2": {
- "name": "string",
- "code": "string",
- "city": {
- "name": "string",
- "code": "string"
}
}
}, - "airlines": {
- "property1": {
- "name": "string",
- "code": "string"
}, - "property2": {
- "name": "string",
- "code": "string"
}
}
}, - "passengers": [
- {
- "id": 0,
- "type": "string"
}
], - "fares": [
- { }
], - "taxes": [
- {
- "id": 0,
- "code": "string",
- "currency": "string",
- "price": 0,
- "was": 0,
- "included": true
}
], - "rules": {
- "property1": {
- "id": 0,
- "type": "REFUND",
- "title": "string",
- "description": "string",
- "applicable": true,
- "free": true,
- "price": {
- "currency": "string",
- "total": 0,
- "base": 0,
- "taxes": 0
}, - "before_date": "2019-08-24T14:15:22Z",
- "price_description": "string"
}, - "property2": {
- "id": 0,
- "type": "REFUND",
- "title": "string",
- "description": "string",
- "applicable": true,
- "free": true,
- "price": {
- "currency": "string",
- "total": 0,
- "base": 0,
- "taxes": 0
}, - "before_date": "2019-08-24T14:15:22Z",
- "price_description": "string"
}
}
}, - "itineraries": [
- {
- "id": 0,
- "cabin_class": "string",
- "passengers": [
- {
- "id": 0,
- "prices": {
- "currency": "string",
- "total": 0.1,
- "base": 0.1,
- "taxes": 0.1,
- "total_currency": "string"
}, - "type": "string"
}
], - "prices": {
- "currency": "string",
- "total": 0.1,
- "base": 0.1,
- "taxes": 0.1,
- "total_currency": "string"
}, - "trips": [
- {
- "id": 0,
- "departure": "string",
- "arrival": "string",
- "total_flight_time": 0,
- "flights": [
- 0
]
}
], - "has_fare_families": true,
- "is_refundable": true,
- "can_hold": true,
- "last_ticketing_date": "string",
- "rules": [
- 0
], - "has_single_marketing_carrier": true,
- "has_single_operating_carrier": true,
- "last_ticketing_tz": "string",
- "is_id_optional": true
}
], - "is_cached": true,
- "status": "progress",
- "search_time": 0
}This step is optional. If the itinerary has has_fare_family set to true, you can use it to fetch the branded fare offers.
| itinerary_id required | string Unique identifier of the selected itinerary |
| search_id required | string Search session identifier from the search response |
[- {
- "id": 0,
- "itinerary": { },
- "brandedFare": [
- "string"
], - "prices": 0.1,
- "amenities": [
- {
- "flight_id": "string",
- "amenities": [
- {
- "type": "check_in_baggage",
- "description": "string",
- "free": true,
- "importance": 0,
- "price": 0.1,
- "obj": { }
}
]
}
]
}
]Confirms that the selected itinerary is still available, re-prices it, and returns the full details of the trip that will be booked. Call it before Create Order.
If you intend to book a specific branded fare (fare family), pass the corresponding fare_family_id.
The flights in order_details.data.flights are the trip that will actually be booked. Baggage (bags_per_pax, free_baggage), fare basis (fare_base), fare type, booking class and branded fare can differ from what Search returned, so replace the flight details you show with these before Create Order; don't rely on the search result.
Also check price_changed / price_change: if the price changed, show the new price to the customer before continuing.
| itinerary_id required | string Unique identifier of the selected itinerary |
| search_id required | string Search session identifier from the search response |
| fare_family_id | string Optional fare family ID to book a specific branded fare |
{- "available": true,
- "price_changed": false,
- "price_change": 0,
- "formatted_price_change": "SAR 0.00",
- "price": "SAR 854.49",
- "session_id": "46a7beae-b13b-4f36-811c-faaa5f919a59",
- "order_session_id": "8500000-46a7beae-b13b-4f36-811c-faaa5f919a59",
- "order_details": {
- "data": {
- "search_id": "46a7beae-b13b-4f36-811c-faaa5f919a59",
- "itinerary": {
- "id": "8500000",
- "trips": [
- {
- "id": "8500000",
- "departure": "CAI",
- "arrival": "JED",
- "total_flight_time": 330,
- "flights": [
- 8500000,
- 8500001
]
}, - {
- "id": "8500001",
- "departure": "JED",
- "arrival": "CAI",
- "total_flight_time": 80,
- "flights": [
- 8500002
]
}
], - "passengers": [
- {
- "id": 25660,
- "prices": {
- "currency": "SAR",
- "total": 854.49,
- "base": 424.34,
- "taxes": 430.14,
- "total_currency": "SAR 854.49"
}, - "ancillaries": [ ]
}
], - "prices": {
- "currency": "SAR",
- "total": 854.49,
- "base": 424.34,
- "taxes": 430.15,
- "total_currency": "SAR 854.49"
}, - "PaxNameCharacterLimit": null,
- "MiddleNameRequired": false,
- "can_hold": true,
- "last_ticketing_date": "18-12-2026 00:00",
- "last_ticketing_tz": null,
- "is_id_optional": false
}, - "taxes": [ ],
- "passengers": [
- {
- "id": 25660,
- "type": "ADT"
}
], - "fares": [ ],
- "search": {
- "meta": "b2b",
- "cabin": "E",
- "adults": 1,
- "children": 0,
- "infants": 0,
- "locale": "en",
- "currency": "SAR",
- "direction": "R",
- "created_at": "2026-10-07T17:13:37.300613",
- "itineraries": [
- {
- "date": "2026-12-18",
- "departure": "CAI",
- "arrival": "JED"
}, - {
- "date": "2026-12-19",
- "departure": "JED",
- "arrival": "CAI"
}
]
}, - "flights": [
- {
- "id": 8500000,
- "departure": {
- "date": "18-12-2026",
- "time": "10:40",
- "airport": "CAI",
- "terminal": "2"
}, - "arrival": {
- "date": "18-12-2026",
- "time": "14:15",
- "airport": "RUH",
- "terminal": "4"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "310",
- "seats": null,
- "cabin": "E",
- "bookingClass": "V",
- "duration": 215,
- "fare_type": "PUB",
- "fare_base": "VARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "330",
- "fare_family_name": "NBASICE",
- "fare_family_code": "",
- "fare_family_amenities": [ ],
- "bags_per_pax": {
- "adult": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": 1,
- "dimensions": null,
- "weight_unit": null
}
}, - "child": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}, - "infant": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}
}
}, - {
- "id": 8500001,
- "departure": {
- "date": "18-12-2026",
- "time": "16:00",
- "airport": "RUH",
- "terminal": "5"
}, - "arrival": {
- "date": "18-12-2026",
- "time": "17:55",
- "airport": "JED",
- "terminal": "1"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "1039",
- "seats": null,
- "cabin": "E",
- "bookingClass": "Y",
- "duration": 115,
- "fare_type": "PUB",
- "fare_base": "QARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "320",
- "fare_family_name": "NBASICE",
- "fare_family_code": "",
- "fare_family_amenities": [ ],
- "bags_per_pax": {
- "adult": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": 1,
- "dimensions": null,
- "weight_unit": null
}
}, - "child": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}, - "infant": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}
}
}, - {
- "id": 8500002,
- "departure": {
- "date": "19-12-2026",
- "time": "00:10",
- "airport": "JED",
- "terminal": "1"
}, - "arrival": {
- "date": "19-12-2026",
- "time": "01:30",
- "airport": "CAI",
- "terminal": "2"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "309",
- "seats": null,
- "cabin": "E",
- "bookingClass": "Q",
- "duration": 80,
- "fare_type": "PUB",
- "fare_base": "QARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "330",
- "fare_family_name": "NBASICE",
- "fare_family_code": "",
- "fare_family_amenities": [ ],
- "bags_per_pax": {
- "adult": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": 1,
- "dimensions": null,
- "weight_unit": null
}
}, - "child": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}, - "infant": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}
}
}
], - "price_changed": false,
- "price_change": "SAR 0.00",
- "isDomestic": false,
- "is_national_id_allowed": false
}, - "order": {
- "id": 17785,
- "name": "",
- "session_id": "8500000-46a7beae-b13b-4f36-811c-faaa5f919a59",
- "status": "shadow_order",
- "booking_status": "",
- "pnr": "",
- "supplier_reference": "",
- "order_number": "184939193",
- "email": "agent@example.com",
- "phone1": "+966565565655",
- "phone2": null,
- "ancillaries": [ ],
- "created_at": "2026-10-07T16:08:59.000000Z",
- "passengers": [
- {
- "id": 25660,
- "title": "",
- "first_name": "",
- "last_name": "",
- "identity_number": "",
- "identity_expire_at": null,
- "nationality": null,
- "birth_date": null,
- "tickets": null
}
]
}
}
}Returns the fare rules (cancellation, change and no-show conditions) for a selected itinerary.
This step is optional and informational — it does not affect pricing or booking. It can be called any time after search, within the same search session.
If the customer selected a branded fare (fare family), pass the same fare_family_id you use for Check Availability, so the returned rules match that fare.
If no rules are available for the itinerary, rules is an empty object and text is null.
| itinerary_id required | string Unique identifier of the selected itinerary |
| search_id required | string Search session identifier from the search response |
| fare_family_id | string Optional fare family ID, to get the rules of a specific branded fare |
{- "rule_level": "ITINERARY",
- "rules": {
- "10400000": {
- "id": 10400000,
- "title": "",
- "structured": true,
- "rules": [
- {
- "id": null,
- "type": "FULLTEXT",
- "title": "CANCELLATION",
- "description": "CAI -> JED:\n\nAFTER_DEP: INR 6720.00\nNO_SHOW: Not permitted (before 2026-11-26 07:25 UTC)\nPRIOR_TO_DEP: INR 6720.00\n\nJED -> CAI:\n\nAFTER_DEP: INR 6720.00\nNO_SHOW: Not permitted (before 2026-11-28 03:15 UTC)\nPRIOR_TO_DEP: INR 6720.00",
- "free": null,
- "price": null,
- "converted_price": null,
- "applicable": null,
- "before_date": null,
- "price_description": null
}, - {
- "id": null,
- "type": "FULLTEXT",
- "title": "CHANGE",
- "description": "CAI -> JED:\n\nAFTER_DEP: INR 3360.00\nNO_SHOW: INR 17760.00 (before 2026-11-26 07:25 UTC)\nPRIOR_TO_DEP: INR 3360.00\n\nJED -> CAI:\n\nAFTER_DEP: INR 3360.00\nNO_SHOW: INR 17760.00 (before 2026-11-28 03:15 UTC)\nPRIOR_TO_DEP: INR 3360.00",
- "free": null,
- "price": null,
- "converted_price": null,
- "applicable": null,
- "before_date": null,
- "price_description": null
}
]
}
}, - "text": "CAI -> JED:\n\nAFTER_DEP: INR 3360.00\nNO_SHOW: INR 17760.00 (before 2026-11-26 07:25 UTC)\nPRIOR_TO_DEP: INR 3360.00\n\nJED -> CAI:\n\nAFTER_DEP: INR 3360.00\nNO_SHOW: INR 17760.00 (before 2026-11-28 03:15 UTC)\nPRIOR_TO_DEP: INR 3360.00\n\nCAI -> JED:\n\nAFTER_DEP: INR 6720.00\nNO_SHOW: Not permitted (before 2026-11-26 07:25 UTC)\nPRIOR_TO_DEP: INR 6720.00\n\nJED -> CAI:\n\nAFTER_DEP: INR 6720.00\nNO_SHOW: Not permitted (before 2026-11-28 03:15 UTC)\nPRIOR_TO_DEP: INR 6720.00"
}Creates the order for the selected itinerary and saves the passengers and contact details.
This endpoint does not book with the airline. It doesn't create a PNR, take payment or issue tickets; it only saves the order so you can continue with one of the next steps:
- Hold Booking: creates the PNR without payment (only when the itinerary allows hold), then pay later with Pay and Issue Ticket.
- Pay and Issue Ticket: pays from your agency balance, creates the PNR and issues the tickets.
Call Check Availability before this endpoint to confirm the price.
| itinerary_id required | string |
| search_id required | string Search session identifier from the search response |
required | Array of objects (BookingPassenger) One entry per passenger. The count must match the adults + children + infants of the search. |
| mobile required | string <= 20 characters Contact mobile number with country code, digits only with optional leading |
| phone | string or null <= 20 characters Alternative contact number |
| email required | string <email> Contact email for booking confirmation |
| live_booking | boolean or null
|
{- "passengers": [
- {
- "identity_number": "A1231231312",
- "nationality_code": "EG",
- "last_name": "Doe",
- "first_name": "John",
- "title": "Mr",
- "type": "ADT",
- "birthDate": "1997-06-15",
- "IdentityExpireDate": "2038-05-14"
}
], - "mobile": "+966565565655",
- "phone": "",
- "email": "John.Doe@example.com",
- "live_booking": false
}{- "data": {
- "id": 2725,
- "name": "Mr John Doe",
- "session_id": "900000-57109609-f631-4999-b01a-6f856e52edea",
- "pnr": "",
- "supplier_reference": "",
- "order_number": "561230182",
- "email": "john.doe@example.com",
- "phone1": "+966565565655",
- "phone2": null,
- "passengers": [
- {
- "id": 3766,
- "title": "Mr",
- "first_name": "John",
- "last_name": "Doe",
- "identity_number": "A1231231312",
- "identity_expire_at": "2038-05-13T21:00:00.000000Z",
- "nationality": "Egypt",
- "birth_date": "1997-06-14T21:00:00.000000Z",
- "tickets": ""
}
], - "ancillaries": [ ],
- "created_at": "2024-12-03T10:49:31.000000Z"
}, - "message": "passenger information stored successfully"
}This endpoint retrieves comprehensive details of a specific flight booking, including:
This ensures timely and accurate updates to the booking status while minimizing manual intervention.
Baggage breakdown per passenger type (adult, child, infant), each with check_in and cabin allowance. Use this for the exact allowance of every passenger. free_baggage and cabin_baggage on the flight are short codes for the adult (ADT) allowance only.
order.available_actions lists what you can do on the booking now. Currently only void, and only when the ticket can be voided through the API; see Void Ticket.
| itinerary_id required | string The unique identifier of the itinerary |
| search_id required | string Search session identifier from the search response |
{- "data": {
- "search_id": "9db3b1de-7be1-4028-9b61-23f3624a1dcf",
- "itinerary": {
- "id": "10400003",
- "trips": [
- {
- "id": "10400008",
- "departure": "CAI",
- "arrival": "JED",
- "total_flight_time": 480,
- "flights": [
- 10400004,
- 10400005
]
}, - {
- "id": "10400009",
- "departure": "JED",
- "arrival": "CAI",
- "total_flight_time": 470,
- "flights": [
- 10400014,
- 10400015
]
}
], - "passengers": [
- {
- "id": 25418,
- "prices": {
- "currency": "USD",
- "total": 1619.14,
- "base": 1491.75,
- "taxes": 127.39,
- "total_currency": "$1,619.14"
}, - "ancillaries": [ ]
}
], - "prices": {
- "currency": "USD",
- "total": 1619.14,
- "base": 1491.75,
- "taxes": 127.39,
- "total_currency": "$1,619.14"
}, - "PaxNameCharacterLimit": null,
- "MiddleNameRequired": false,
- "can_hold": true,
- "last_ticketing_date": "08-10-2026 16:05",
- "last_ticketing_tz": "UTC",
- "is_id_optional": false
}, - "taxes": [ ],
- "passengers": [
- {
- "id": 25418,
- "type": "ADT"
}
], - "fares": [ ],
- "search": {
- "meta": "b2b",
- "cabin": "E",
- "adults": 1,
- "children": 0,
- "infants": 0,
- "locale": "en",
- "currency": "USD",
- "direction": "R",
- "created_at": "2026-10-01T16:11:22.633070",
- "itineraries": [
- {
- "date": "2026-11-26",
- "departure": "CAI",
- "arrival": "JED"
}, - {
- "date": "2026-11-28",
- "departure": "JED",
- "arrival": "CAI"
}
]
}, - "flights": [
- {
- "id": 10400004,
- "departure": {
- "date": "26-11-2026",
- "time": "07:25",
- "airport": "CAI",
- "terminal": "2"
}, - "arrival": {
- "date": "26-11-2026",
- "time": "12:45",
- "airport": "AUH",
- "terminal": "A"
}, - "marketing_carrier": "EY",
- "operating_carrier": "EY",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "712",
- "seats": null,
- "cabin": "E",
- "bookingClass": "B",
- "duration": 200,
- "fare_type": "PUB",
- "fare_base": "BNN05C3R",
- "free_baggage": "45.0 KG",
- "cabin_baggage": "7.0 KG",
- "code_share": null,
- "equipment": "321",
- "fare_family_name": "Economy Comfort",
- "fare_family_code": "EY-YCOMFORT",
- "fare_family_amenities": [
- {
- "type": "other",
- "description": "CHARGEABLE CANCELLATION / REFUND - EXTRA FEES APPLY FOR CANCELLATION. PLEASE REFER TO THE TERMS OF YOUR TICKET FOR MORE INFORMATION",
- "free": false,
- "importance": 10
}, - {
- "type": "mileage",
- "description": "MILES EARNED PER GUEST - 75%",
- "free": true,
- "importance": 2
}, - {
- "type": "cabin_baggage",
- "description": "FREE BAG 7.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "check_in_baggage",
- "description": "FREE BAG 45.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "seat_selection",
- "description": "SEAT SELECTION - STANDARD SEATS INCLUDED",
- "free": true,
- "importance": 2
}
], - "bags_per_pax": {
- "adult": {
- "cabin": {
- "policy": "Max width 56 cm, height 36 cm and depth 23 cm. One bag only. Charges apply if your baggage exceeds your allowance.",
- "weight": 7,
- "quantity": 1,
- "dimensions": null,
- "weight_unit": "KG"
}, - "check_in": {
- "policy": "Checked.",
- "weight": 45,
- "quantity": null,
- "dimensions": null,
- "weight_unit": "KG"
}
}, - "child": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}, - "infant": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}
}
}, - {
- "id": 10400005,
- "departure": {
- "date": "26-11-2026",
- "time": "14:15",
- "airport": "AUH",
- "terminal": "A"
}, - "arrival": {
- "date": "26-11-2026",
- "time": "16:25",
- "airport": "JED",
- "terminal": "1"
}, - "marketing_carrier": "EY",
- "operating_carrier": "EY",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "611",
- "seats": null,
- "cabin": "E",
- "bookingClass": "B",
- "duration": 190,
- "fare_type": "PUB",
- "fare_base": "BNN05C3R",
- "free_baggage": "45.0 KG",
- "cabin_baggage": "7.0 KG",
- "code_share": null,
- "equipment": "321",
- "fare_family_name": "Economy Comfort",
- "fare_family_code": "EY-YCOMFORT",
- "fare_family_amenities": [
- {
- "type": "other",
- "description": "CHARGEABLE CANCELLATION / REFUND - EXTRA FEES APPLY FOR CANCELLATION. PLEASE REFER TO THE TERMS OF YOUR TICKET FOR MORE INFORMATION",
- "free": false,
- "importance": 10
}, - {
- "type": "mileage",
- "description": "MILES EARNED PER GUEST - 75%",
- "free": true,
- "importance": 2
}, - {
- "type": "cabin_baggage",
- "description": "FREE BAG 7.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "check_in_baggage",
- "description": "FREE BAG 45.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "seat_selection",
- "description": "SEAT SELECTION - STANDARD SEATS INCLUDED",
- "free": true,
- "importance": 2
}
], - "bags_per_pax": {
- "adult": {
- "cabin": {
- "policy": "Max width 56 cm, height 36 cm and depth 23 cm. One bag only. Charges apply if your baggage exceeds your allowance.",
- "weight": 7,
- "quantity": 1,
- "dimensions": null,
- "weight_unit": "KG"
}, - "check_in": {
- "policy": "Checked.",
- "weight": 45,
- "quantity": null,
- "dimensions": null,
- "weight_unit": "KG"
}
}, - "child": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}, - "infant": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}
}
}, - {
- "id": 10400014,
- "departure": {
- "date": "28-11-2026",
- "time": "05:55",
- "airport": "JED",
- "terminal": "1"
}, - "arrival": {
- "date": "28-11-2026",
- "time": "09:20",
- "airport": "AUH",
- "terminal": "A"
}, - "marketing_carrier": "EY",
- "operating_carrier": "EY",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "604",
- "seats": null,
- "cabin": "E",
- "bookingClass": "B",
- "duration": 145,
- "fare_type": "PUB",
- "fare_base": "BNN05C3R",
- "free_baggage": "45.0 KG",
- "cabin_baggage": "7.0 KG",
- "code_share": null,
- "equipment": "321",
- "fare_family_name": "Economy Comfort",
- "fare_family_code": "EY-YCOMFORT",
- "fare_family_amenities": [
- {
- "type": "other",
- "description": "CHARGEABLE CANCELLATION / REFUND - EXTRA FEES APPLY FOR CANCELLATION. PLEASE REFER TO THE TERMS OF YOUR TICKET FOR MORE INFORMATION",
- "free": false,
- "importance": 10
}, - {
- "type": "mileage",
- "description": "MILES EARNED PER GUEST - 75%",
- "free": true,
- "importance": 2
}, - {
- "type": "cabin_baggage",
- "description": "FREE BAG 7.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "check_in_baggage",
- "description": "FREE BAG 45.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "seat_selection",
- "description": "SEAT SELECTION - STANDARD SEATS INCLUDED",
- "free": true,
- "importance": 2
}
], - "bags_per_pax": {
- "adult": {
- "cabin": {
- "policy": "Max width 56 cm, height 36 cm and depth 23 cm. One bag only. Charges apply if your baggage exceeds your allowance.",
- "weight": 7,
- "quantity": 1,
- "dimensions": null,
- "weight_unit": "KG"
}, - "check_in": {
- "policy": "Checked.",
- "weight": 45,
- "quantity": null,
- "dimensions": null,
- "weight_unit": "KG"
}
}, - "child": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}, - "infant": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}
}
}, - {
- "id": 10400015,
- "departure": {
- "date": "28-11-2026",
- "time": "10:25",
- "airport": "AUH",
- "terminal": "A"
}, - "arrival": {
- "date": "28-11-2026",
- "time": "12:45",
- "airport": "CAI",
- "terminal": "2"
}, - "marketing_carrier": "EY",
- "operating_carrier": "EY",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "713",
- "seats": null,
- "cabin": "E",
- "bookingClass": "B",
- "duration": 260,
- "fare_type": "PUB",
- "fare_base": "BNN05C3R",
- "free_baggage": "45.0 KG",
- "cabin_baggage": "7.0 KG",
- "code_share": null,
- "equipment": "321",
- "fare_family_name": "Economy Comfort",
- "fare_family_code": "EY-YCOMFORT",
- "fare_family_amenities": [
- {
- "type": "other",
- "description": "CHARGEABLE CANCELLATION / REFUND - EXTRA FEES APPLY FOR CANCELLATION. PLEASE REFER TO THE TERMS OF YOUR TICKET FOR MORE INFORMATION",
- "free": false,
- "importance": 10
}, - {
- "type": "mileage",
- "description": "MILES EARNED PER GUEST - 75%",
- "free": true,
- "importance": 2
}, - {
- "type": "cabin_baggage",
- "description": "FREE BAG 7.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "check_in_baggage",
- "description": "FREE BAG 45.0 KG",
- "free": true,
- "importance": 1
}, - {
- "type": "seat_selection",
- "description": "SEAT SELECTION - STANDARD SEATS INCLUDED",
- "free": true,
- "importance": 2
}
], - "bags_per_pax": {
- "adult": {
- "cabin": {
- "policy": "Max width 56 cm, height 36 cm and depth 23 cm. One bag only. Charges apply if your baggage exceeds your allowance.",
- "weight": 7,
- "quantity": 1,
- "dimensions": null,
- "weight_unit": "KG"
}, - "check_in": {
- "policy": "Checked.",
- "weight": 45,
- "quantity": null,
- "dimensions": null,
- "weight_unit": "KG"
}
}, - "child": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}, - "infant": {
- "cabin": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}, - "check_in": {
- "policy": null,
- "weight": null,
- "quantity": null,
- "dimensions": null,
- "weight_unit": null
}
}
}
}
], - "price_changed": false,
- "price_change": "$0.00",
- "isDomestic": false,
- "is_national_id_allowed": false
}, - "order": {
- "id": 17687,
- "name": "Mr John Doe",
- "session_id": "10400003-9db3b1de-7be1-4028-9b61-23f3624a1dcf",
- "status": "confirmed",
- "booking_status": "",
- "pnr": "TGOA48",
- "supplier_reference": "",
- "order_number": "892892810",
- "email": "john.doe@example.com",
- "phone1": "+966565565655",
- "phone2": null,
- "ancillaries": [ ],
- "created_at": "2026-10-01T16:05:01.000000Z",
- "passengers": [
- {
- "id": 25418,
- "title": "Mr",
- "first_name": "John",
- "last_name": "Doe",
- "identity_number": "A1231231312",
- "identity_expire_at": "2028-07-04",
- "nationality": "Egypt",
- "birth_date": "1994-03-14",
- "tickets": ""
}
], - "available_actions": [
- {
- "action": "void",
- "product_id": 12001
}
]
}
}This endpoint allows placing a hold on a booking.
can_hold = true. (Needs to be activated on the account)| itinerary_id required | string The unique identifier of the itinerary |
| search_id required | string Search session identifier from the search response |
{- "order": {
- "id": 2725,
- "name": "Mr John Doe",
- "session_id": "900000-57109609-f631-4999-b01a-6f856e52edea",
- "pnr": "TGOA48",
- "supplier_reference": "",
- "order_number": "561230182",
- "email": "john.doe@example.com",
- "phone1": "+966565565655",
- "phone2": null,
- "passengers": [
- {
- "id": 3766,
- "title": "Mr",
- "first_name": "John",
- "last_name": "Doe",
- "identity_number": "A1231231312",
- "identity_expire_at": "2038-05-13T21:00:00.000000Z",
- "nationality": "Egypt",
- "birth_date": "1997-06-14T21:00:00.000000Z",
- "tickets": "SBN4BJK"
}
], - "ancillaries": [ ],
- "created_at": "2024-12-03T10:49:31.000000Z"
}, - "data": {
- "search_id": "57109609-f631-4999-b01a-6f856e52edea",
- "itinerary": {
- "id": "900000",
- "trips": [
- {
- "id": "900000",
- "departure": "CAI",
- "arrival": "JED",
- "total_flight_time": 415,
- "flights": [
- 900000,
- 900001
]
}, - {
- "id": "900001",
- "departure": "JED",
- "arrival": "CAI",
- "total_flight_time": 145,
- "flights": [
- 900002
]
}
], - "passengers": [
- {
- "id": 3766,
- "prices": {
- "currency": "SAR",
- "total": 884.57,
- "base": 224.98,
- "total_currency": "SAR 884.57",
- "taxes": 492.68
}, - "ancillaries": [ ]
}
], - "PaxNameCharacterLimit": null,
- "MiddleNameRequired": false,
- "prices": {
- "currency": "SAR",
- "total": 1663.57,
- "base": 1663.57,
- "total_currency": "SAR 1,663.57",
- "taxes": 0
}
}, - "taxes": [ ],
- "passengers": [
- {
- "id": 3766,
- "type": "ADT"
}
], - "fares": [ ],
- "search": {
- "meta": "b2b",
- "cabin": "E",
- "adults": 1,
- "locale": "en",
- "infants": 0,
- "children": 0,
- "currency": "SAR",
- "direction": "R",
- "created_at": "2024-12-03T09:31:33.574658",
- "itineraries": [
- {
- "date": "2024-12-18",
- "arrival": "JED",
- "departure": "CAI"
}, - {
- "date": "2024-12-19",
- "arrival": "CAI",
- "departure": "JED"
}
]
}, - "flights": [
- {
- "departure": {
- "date": "18-12-2024",
- "time": "15:00",
- "airport": "CAI",
- "terminal": "2"
}, - "arrival": {
- "date": "18-12-2024",
- "time": "18:45",
- "airport": "RUH",
- "terminal": "4"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "418",
- "seats": null,
- "cabin": "E",
- "bookingClass": "V",
- "duration": 165,
- "fare_type": "PUB",
- "fare_base": "VARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "330",
- "cabin_baggage": "1PC",
- "id": 900000
}, - {
- "departure": {
- "date": "18-12-2024",
- "time": "21:00",
- "airport": "RUH",
- "terminal": "5"
}, - "arrival": {
- "date": "18-12-2024",
- "time": "22:55",
- "airport": "JED",
- "terminal": "1"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "1049",
- "seats": null,
- "cabin": "E",
- "bookingClass": "E",
- "duration": 115,
- "fare_type": "PUB",
- "fare_base": "VARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "773",
- "cabin_baggage": "1PC",
- "id": 900001
}, - {
- "departure": {
- "date": "19-12-2024",
- "time": "03:20",
- "airport": "JED",
- "terminal": "1"
}, - "arrival": {
- "date": "19-12-2024",
- "time": "04:45",
- "airport": "CAI",
- "terminal": "2"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "383",
- "seats": null,
- "cabin": "E",
- "bookingClass": "V",
- "duration": 145,
- "fare_type": "PUB",
- "fare_base": "VARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "333",
- "cabin_baggage": "1PC",
- "id": 900002
}
]
}
}Pays for the booking from your agency balance and issues the tickets.
Previously named
payWallet. The old path/api/v2/orders/payWallet/{itinerary_id}-{search_id}still works, but is deprecated; use this one.
Important Notes:
This polling mechanism ensures accurate tracking of the booking lifecycle after payment.
| itinerary_id required | string The unique identifier of the itinerary |
| search_id required | string Search session identifier from the search response |
{- "order": {
- "id": 2725,
- "name": "Mr John Doe",
- "session_id": "900000-57109609-f631-4999-b01a-6f856e52edea",
- "pnr": "TGOA48",
- "supplier_reference": "",
- "order_number": "561230182",
- "email": "john.doe@example.com",
- "phone1": "+966565565655",
- "phone2": null,
- "passengers": [
- {
- "id": 3766,
- "title": "Mr",
- "first_name": "John",
- "last_name": "Doe",
- "identity_number": "A1231231312",
- "identity_expire_at": "2038-05-13T21:00:00.000000Z",
- "nationality": "Egypt",
- "birth_date": "1997-06-14T21:00:00.000000Z",
- "tickets": "SBN4BJK"
}
], - "ancillaries": [ ],
- "created_at": "2024-12-03T10:49:31.000000Z"
}, - "data": {
- "search_id": "57109609-f631-4999-b01a-6f856e52edea",
- "itinerary": {
- "id": "900000",
- "trips": [
- {
- "id": "900000",
- "departure": "CAI",
- "arrival": "JED",
- "total_flight_time": 415,
- "flights": [
- 900000,
- 900001
]
}, - {
- "id": "900001",
- "departure": "JED",
- "arrival": "CAI",
- "total_flight_time": 145,
- "flights": [
- 900002
]
}
], - "passengers": [
- {
- "id": 3766,
- "prices": {
- "currency": "SAR",
- "total": 884.57,
- "base": 224.98,
- "total_currency": "SAR 884.57",
- "taxes": 492.68
}, - "ancillaries": [ ]
}
], - "PaxNameCharacterLimit": null,
- "MiddleNameRequired": false,
- "prices": {
- "currency": "SAR",
- "total": 1663.57,
- "base": 1663.57,
- "total_currency": "SAR 1,663.57",
- "taxes": 0
}
}, - "taxes": [ ],
- "passengers": [
- {
- "id": 3766,
- "type": "ADT"
}
], - "fares": [ ],
- "search": {
- "meta": "b2b",
- "cabin": "E",
- "adults": 1,
- "locale": "en",
- "infants": 0,
- "children": 0,
- "currency": "SAR",
- "direction": "R",
- "created_at": "2024-12-03T09:31:33.574658",
- "itineraries": [
- {
- "date": "2024-12-18",
- "arrival": "JED",
- "departure": "CAI"
}, - {
- "date": "2024-12-19",
- "arrival": "CAI",
- "departure": "JED"
}
]
}, - "flights": [
- {
- "departure": {
- "date": "18-12-2024",
- "time": "15:00",
- "airport": "CAI",
- "terminal": "2"
}, - "arrival": {
- "date": "18-12-2024",
- "time": "18:45",
- "airport": "RUH",
- "terminal": "4"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "418",
- "seats": null,
- "cabin": "E",
- "bookingClass": "V",
- "duration": 165,
- "fare_type": "PUB",
- "fare_base": "VARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "330",
- "cabin_baggage": "1PC",
- "id": 900000
}, - {
- "departure": {
- "date": "18-12-2024",
- "time": "21:00",
- "airport": "RUH",
- "terminal": "5"
}, - "arrival": {
- "date": "18-12-2024",
- "time": "22:55",
- "airport": "JED",
- "terminal": "1"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "1049",
- "seats": null,
- "cabin": "E",
- "bookingClass": "E",
- "duration": 115,
- "fare_type": "PUB",
- "fare_base": "VARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "773",
- "cabin_baggage": "1PC",
- "id": 900001
}, - {
- "departure": {
- "date": "19-12-2024",
- "time": "03:20",
- "airport": "JED",
- "terminal": "1"
}, - "arrival": {
- "date": "19-12-2024",
- "time": "04:45",
- "airport": "CAI",
- "terminal": "2"
}, - "marketing_carrier": "SV",
- "operating_carrier": "SV",
- "operated_by_carrier": null,
- "operated_flight_number": null,
- "flight_number": "383",
- "seats": null,
- "cabin": "E",
- "bookingClass": "V",
- "duration": 145,
- "fare_type": "PUB",
- "fare_base": "VARTEGB4",
- "free_baggage": "1PC",
- "code_share": null,
- "equipment": "333",
- "cabin_baggage": "1PC",
- "id": 900002
}
]
}
}Cancel freshly issued tickets within the airline's void window; the ticket amount is refunded to your agency balance minus the void fee and any airline penalties.
Flow
action: void in order.available_actions. If it isn't there, the ticket can't be voided through the API.product_id to see the void fee.product_id.Returns the void fee for the product's tickets, in your agency currency, before voiding.
Only call it for a product listed with action: void in order.available_actions of Booking Details. This endpoint must be enabled for your account. If it returns 403, contact your account manager.
| session_id required | string Example: 10400003-9db3b1de-7be1-4028-9b61-23f3624a1dcf Order session, |
| product_id required | integer
|
{- "product_id": 12001
}{- "data": {
- "amount": 20,
- "currency": "USD",
- "per_ticket_amount": 10,
- "tickets": 2,
- "original_amount": 75,
- "original_currency": "SAR",
- "per_ticket_original_amount": 37.5,
- "airline": "SV",
- "pcc": "CAIEG2100",
- "configured": true
}, - "message": "Void Validation Result",
- "status": true
}Voids the product's tickets. The tickets are cancelled as if never issued, and the ticket amount minus the void fee and any airline penalties is returned to your agency balance.
Only products listed with action: void in order.available_actions of Booking Details can be voided; any other product is rejected. This endpoint must be enabled for your account. If it returns 403, contact your account manager.
| session_id required | string Example: 10400003-9db3b1de-7be1-4028-9b61-23f3624a1dcf Order session, |
| product_id required | integer
|
{- "product_id": 12001
}{- "data": [ ],
- "message": "Ticket Voided Successfully",
- "status": true
}Run these flight scenarios with test bookings (live_booking: false in Create Order) and send us the session ID, PNR and ticket number of each. Download the flight test cases (CSV).
| # | Test case | Session ID | PNR | Ticket |
|---|---|---|---|---|
| 1 | 1 ADT, 1 CHD, 1 INF, One Way | |||
| 2 | 1 ADT, 1 CHD, 1 INF, One Way with Fare Family | |||
| 3 | 1 ADT, 1 CHD, 1 INF, Round Trip | |||
| 4 | 1 ADT, 1 CHD, 1 INF, Round Trip with Fare Family | |||
| 5 | 4 ADT, 2 CHD, 2 INF, One Way - Connecting Point | |||
| 6 | 4 ADT, 2 CHD, 2 INF, Round Trip - Connecting Point (Hold) | |||
| 7 | 4 ADT, 2 CHD, 2 INF, One Way - Connecting Point with Fare Family (Hold) | |||
| 8 | 4 ADT, 2 CHD, 2 INF, Round Trip - Connecting Point with Fare Family |
Our Hotels API gives you a complete B2B gateway for searching, pricing, booking, and managing hotel inventory with precision. It connects your system to real-time availability, rich hotel content, multi-rate handling, instant confirmations, and full booking lifecycle controls.
Built for speed, stability, and clean integration, it lets your platform deliver consistent results, automate operations, and scale without friction. Whether you are powering a B2B portal, a mobile app, or a distribution engine, this API provides the structure you need to move fast, stay reliable, and serve your customers with confidence.
| Area | What it does | Endpoints |
|---|---|---|
| Autocomplete | Find cities, hotels and nationalities while the user types | Location Autocomplete, Nationality Autocomplete |
| Booking Flow | Search hotels, pick rooms, book, hold, pay and confirm | Search Hotels, Collect Results, Get Hotel Details, Get Available Rooms, Check Availability, Save Guest Details, Hold Booking, Pay and Confirm Booking, Retrieve Order Details |
| Hold | Reserve free-cancellation rooms now and pay later | Hold Booking, then Pay and Confirm Booking |
| Cancel Booking | Cancel a free-cancellation booking before its deadline | Retrieve Order Details, Cancel Booking |
| Balance | Check your agency balance before paying | Get Balance |
| Hotels Dump | Download all our hotels once, then only what changed | Hotels Dump |
Build the search form from two lookups (no token needed):
User types "cairo" ──▶ Location Autocomplete
├── city hit: code CAI, country.code EG ──▶ Search: city + country_code
└── hotel hit: id 2135352 ──────────────▶ Search: hotels_ids (only this hotel)
or requested_hotel_ids + city
User types "eg" ────▶ Nationality Autocomplete ──▶ code EG ──────▶ Search: nationality
Search returns hotels with their cheapest price, either all at once or progressively with mode: poll and Collect Results. Get the rooms of the chosen hotel, then call Check Availability with the selected room combination: it confirms the rooms and price and creates the order. Save the guests on the order, then either hold it (when can_hold is true) or pay and confirm right away. Confirmation with the supplier runs in the background, so poll Retrieve Order Details until booking_status is final.
Search Hotels ──(mode: poll)──▶ Collect Results until status: completed
│
▼
Get Hotel Details (optional)
│
▼
Get Available Rooms ──────────▶ room_combinations[].can_hold / deadline
│
▼
Check Availability ───────────▶ creates the order, returns can_hold / deadline
│
▼
Save Guest Details
│
├── can_hold = true ──▶ Hold Booking ──▶ (pay before deadline) ──┐
│ │
▼ ▼
Pay and Confirm Booking ◀─────────────────────────────────────────────┘
│
▼
Poll Retrieve Order Details (every 10 min, up to 3 hours)
│
▼
booking_status: book_success or book_failed
can_hold tells you whether the booking can be held without payment, and deadline until when (pay before it, or the hold is released). They are returned by Get Available Rooms (per room combination), Check Availability and Retrieve Order Details; always use the latest one. A hold is offered only for fully free-cancellation rooms from suppliers that support it, and must be enabled for your account.
can_hold = true ──▶ Hold Booking ──▶ order status: hold
│
before `deadline` ▼
Pay and Confirm Booking ──▶ booking confirmed
│
after `deadline` ▼
hold released, book again
Hold can still be refused (403 with the reason) when your account's hold limits are reached, e.g. the number or total amount of active holds, or a check-in date that is too close.
Cancel a booking free of charge before its free-cancellation deadline. The amount is refunded to your agency balance.
Before cancelling
cancellation_policy in Get Available Rooms): free cancellation ends at last_cancellation_deadline, after which policies show the charges.action: cancel in order.available_actions. It is listed only while the booking can be cancelled through the API (free-cancellation booking, before its deadline data.deadline). If it isn't there, the booking can't be cancelled through the API; contact your account manager.product_id.Retrieve Order Details
│
▼
order.available_actions has { action: "cancel", product_id }?
│
├── no ──▶ can't be cancelled through the API (non-refundable, or past the deadline)
│
└── yes ─▶ Cancel Booking (product_id) ──▶ booking cancelled, refund to your balance
Bookings are paid from your agency balance (in your agency currency). Check it before Pay and Confirm Booking to avoid a payment failure.
Get Balance ──▶ balance ≥ booking price? ──yes──▶ Pay and Confirm Booking
│
no ──▶ top up your balance first
Keep your own copy of our hotels, to map them to your inventory or build your own search pages.
GET /api/agency/api-out/hotels/dump first time: all hotels
GET /api/agency/api-out/hotels/dump?since=<version> every day: only what changed
since. You get type: full with a link to a file of all hotels (gzip-compressed JSON Lines, one hotel per line). Download it, import it, and keep its version.since set to your version. You get type: delta with the files of what changed, to apply in order, or type: up_to_date when nothing changed. Keep the new version. If you get type: full, replace all your hotels with it.Links are valid for 1 hour; call the endpoint again for fresh links. A new version is published every day.
first time ──▶ Hotels Dump ─────────────▶ type: full ──▶ download, check sha256, import all, keep version
│
every day ───▶ Hotels Dump?since=<version> ◀─────────────────────────────────────────────────────┘
├── type: up_to_date ──▶ nothing to do
├── type: delta ───────▶ apply each file of `deltas` in order, keep its version
└── type: full ────────▶ replace all your hotels, keep version
Hotel IDs:
id in hotels_ids or requested_hotel_ids of Search Hotels. These are the same IDs as Location Autocomplete and Sample Hotels.linked_hotel_ids. Map those to the hotel id.delete line with replaced_by means the hotel now has another ID. Move your mapping to replaced_by.Get Balance, Hold Booking, Cancel Booking, Sample Hotels and Hotels Dump must be enabled for your account. If they return 403, contact your account manager.
Send live_booking: false in Save Guest Details to make the order a test booking, or true for a live booking. When not sent, your account environment decides: live for accounts enabled for live bookings, test otherwise. Accounts not enabled for live bookings always make test bookings.
Test bookings go through the full flow (hold, pay, order details) but are never sent to the supplier. Their supplier reference and hcn start with TEST-.
Need known hotels to test with? Sample Hotels returns up to 100 4- and 5-star hotels for each test city (IST, CAI, DXB, PAR, JED); use their id in hotels_ids or requested_hotel_ids.
To test the pending flow, use a check-in date on the 17th of any month:
check-in on the 17th ──▶ Pay and Confirm ──▶ booking_status: book_pending (reference set, no HCN)
│ next confirmation run (within ~5 minutes)
▼
booking_status: book_success, hcn: TEST-HCN-...
any other check-in ────▶ Pay and Confirm ──▶ booking_status: book_success, hcn: TEST-HCN-...
The order has two status fields:
payment_pending, hold, payment_success)book_success: confirmed by the supplier.book_pending: the supplier accepted the booking but hasn't confirmed it yet. Keep polling; it moves to book_success or book_failed.book_failed: the supplier refused the booking.reference: the supplier's booking reference, available as soon as the supplier accepts the booking.hcn (hotel confirmation number): the hotel's own confirmation number, to give the guest at check-in. It depends on the supplier:book_success;book_pending first and set the HCN later, when the hotel confirms;reference.Keep polling Retrieve Order Details while booking_status is book_pending, or until hcn is set if you need it.
After Pay and Confirm Booking, you must poll the Order Details endpoint to retrieve the final booking status:
┌──────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ PayAndConfirm│────▶│ Poll Order │────▶│ Check Status │
│ Booking │ │ Details │ │ │
└──────────────┘ └─────────────────┘ └────────┬─────────┘
│
┌────────────────────────────────┼────────────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
│ book_success │ │ book_failed │ │ No final status │
│ (Confirmed) │ │ (Failed) │ │ after 3 hours │
└──────────────┘ └──────────────┘ └────────┬─────────┘
│
▼
┌──────────────────┐
│ Mark unconfirmed │
│ Contact Account │
│ Manager │
└──────────────────┘
book_success or book_failed. book_pending is not final: keep polling.book_success; see Supplier Reference and HCNDestination, hotel and nationality lookup for building the search form. No authentication needed.
Searches cities and hotels in one call while the user types. No authentication is required.
Send one query per index in queries, usually both with the same q:
cities: use the hit's code as city and country.code as country_code in Search Hotels.hotels: use the hit's id in hotels_ids (search only this hotel) or in requested_hotel_ids together with a city (show this hotel first among the city's hotels).Results come back in results, one entry per query, in the same order.
Optional per query: limit, filter (e.g. country_code = "EG") and sort (e.g. ["combined_score:desc"] for cities, to rank popular destinations first).
required | Array of objects |
{- "queries": [
- {
- "indexUid": "cities",
- "q": "cairo",
- "limit": 5,
- "sort": [
- "combined_score:desc"
]
}, - {
- "indexUid": "hotels",
- "q": "cairo",
- "limit": 10
}
]
}{- "results": [
- {
- "indexUid": "cities",
- "hits": [
- {
- "id": 1857,
- "code": "CAI",
- "type": "tk_city",
- "name": {
- "en": "Cairo",
- "ar": "القاهرة"
}, - "country": {
- "code": "EG",
- "name": {
- "en": "Egypt",
- "ar": "مصر"
}, - "permalink": "egypt"
}, - "country_code": "EG",
- "_geo": {
- "lat": 30.044388,
- "lng": 31.235726
}, - "time_zone": "Africa/Cairo"
}
], - "query": "cairo",
- "limit": 5,
- "offset": 0,
- "estimatedTotalHits": 1,
- "processingTimeMs": 1
}, - {
- "indexUid": "hotels",
- "hits": [
- {
- "id": 2135352,
- "name": {
- "en": "InterContinental Cairo Semiramis, an IHG Hotel"
}, - "address": {
- "street": "Corniche El Nil PO Casilla 60 Cairo, 11511 Egypt",
- "latitude": "30.04306",
- "longitude": "31.23199",
- "postal_code": "11511"
}, - "country": {
- "code": "EG",
- "name": {
- "en": "Egypt",
- "ar": "مصر"
}
}, - "country_code": "EG",
- "stars": 5,
- "thumbnail": null,
- "type": "hotel"
}, - {
- "id": 2137311,
- "name": {
- "en": "Sofitel Cairo Downtown Nile"
}, - "address": {
- "street": "1191 Nile Corniche, Souq Al Asr Bulaq, PO BOX 2044, Cairo, 11221, Egypt",
- "latitude": "30.06547171",
- "longitude": "31.22761542",
- "postal_code": "11221"
}, - "country": {
- "code": "EG",
- "name": {
- "en": "Egypt",
- "ar": "مصر"
}
}, - "country_code": "EG",
- "stars": 5,
- "thumbnail": null,
- "type": "hotel"
}
], - "query": "cairo",
- "limit": 10,
- "offset": 0,
- "estimatedTotalHits": 75,
- "processingTimeMs": 0
}
]
}Searches countries by name or code while the user types, for the guest nationality. No authentication is required.
Use the hit's code as nationality in Search Hotels.
| q required | string Text typed by the user |
| limit | integer Default: 20 |
{- "q": "eg"
}{- "hits": [
- {
- "id": 68,
- "code": "EG",
- "type": "country",
- "name": {
- "en": "Egypt",
- "ar": "مصر"
}, - "code3": "EGY",
}
], - "query": "eg",
- "limit": 20,
- "offset": 0,
- "estimatedTotalHits": 1,
- "processingTimeMs": 0
}Hotel search operations give your system the ability to query real-time availability, pricing, and room options across all connected suppliers. You can filter by destination, dates, occupancy, and other parameters to retrieve accurate, structured results ready for display or further processing.
Search for available hotels with comprehensive filtering options. Supports searching by city or by specific hotel IDs. Multiple rooms with different guest configurations can be searched.
Set mode in the request:
search (default): the response arrives once every supplier has answered, with the full results.poll: the response arrives immediately with the search_id, status: progress and up to 100 skeleton hotels (skeleton: true): hotel content (name, stars, photos, location) without price, so you can render the list right away. Call Collect Results with that search_id every 2-3 seconds. Each call returns everything found so far, with skeletons replaced by priced hotels as suppliers answer, so replace what you show each time. Stop when status is completed (at the latest about 60 seconds after the search).Search (mode: poll) ──▶ search_id, status: progress, skeleton hotels (no price)
│
▼
Collect Results ──▶ status: progress ──▶ priced hotels replace skeletons, call again in 2-3 s
│
└──────────▶ status: completed ──▶ final results, stop polling
Show skeleton hotels as "loading" and don't let users select them; only hotels with skeleton: false have rooms and prices.
| Field | Searches | Limit |
|---|---|---|
city + country_code |
All hotels of the city | |
hotels_ids |
Only the listed hotels | up to 1000 |
city + country_code + requested_hotel_ids |
The city and the listed hotels; the listed hotels come first (is_requested_hotel: true) and are always returned, with is_available: false when no supplier has them |
up to 10 |
Use requested_hotel_ids when the user picked a specific hotel but should still see alternatives in the same city.
Optional: min_price, max_price (total for the stay), stars, boarding (meal plans) and free_cancellation. They narrow the city results; requested hotels are never filtered out.
Search response
├── search_id ──────────────────────▶ use as `session` in every next call
├── search the destination and number of nights
├── fact_groups ◀────────────────┐ facilities and services, grouped by category
│ └── <group>.facts.<code>.id │
└── hotels[] │ one entry per available hotel
├── index ────────────────────┼─▶ use as `hotel` in Hotel Details, Rooms and Check Availability
├── name, stars, address, location, zone, thumbnail, reviews
├── amenities[] ── fact ids ──┘
├── price cheapest price for all rooms and the whole stay
├── free_cancellation at least one room option can be cancelled for free
└── boarding_type[] meal plans available (room only, breakfast, ...)
hotels[] as your results list. The price is a starting price ("from"); the exact options and prices come from Get Available Rooms.index is the hotel identifier for the next calls.amenities holds fact IDs: find each one in fact_groups (the facts are keyed by code; match on their id) to show the hotel's facilities and to build facility filters.price.display_price, stars, reviews, free_cancellation, boarding_type and amenities.required | Array of objects (RoomSearch) non-empty Array of room objects with guest configurations |
| nationality required | string = 2 characters Guest nationality code (ISO 3166-1 alpha-2) |
| country_code | string = 2 characters Country code for a city search (required with |
| city | string City code for a city search (required with |
| hotels_ids | Array of integers <= 1000 items Search only these hotels (up to 1000). When provided, |
| check_in required | string <date> Check-in date (YYYY-MM-DD) |
| check_out required | string <date> Check-out date (YYYY-MM-DD) |
| currency required | string = 3 characters Currency code (ISO 4217) |
| language required | string = 2 characters Language preference (ISO 639-1) |
| requested_hotel_ids | Array of integers <= 10 items Hotels to highlight in a normal city search (up to 10). The search still returns the city's hotels, and these hotels are searched as well and listed first, flagged with |
| mode | string Default: "search" Enum: "search" "poll"
|
| min_price | number or null Minimum total price for the stay ( |
| max_price | number or null Maximum total price for the stay ( |
| stars | Array of integers or null[ items [ 0 .. 5 ] ] Only hotels with one of these star ratings |
| boarding | Array of strings or null Only hotels offering at least one of these meal plans (values of |
| free_cancellation | boolean or null
|
{- "rooms": [
- {
- "adults": "2",
- "children": [ ]
}
], - "nationality": "EG",
- "country_code": "AE",
- "city": "DXB",
- "check_in": "2025-12-14",
- "check_out": "2025-12-16",
- "currency": "USD",
- "language": "en"
}{- "search_id": "575f395a-e8c9-4cc4-a85b-a12551678eeb",
- "search": {
- "code": "DXB",
- "country_code": "AE",
- "city": "Dubai",
- "city_geo": { },
- "nights": 2,
- "country": "United Arab Emirates"
}, - "hotels": [
- {
- "type": "HOTEL",
- "check_in": "2025-12-14",
- "check_out": "2025-12-16",
- "name": "Movenpick Grand Al Bustan Hotel",
- "description": "This hotel is located on Casablanca Road...",
- "amenities": [
- "81",
- "78"
], - "address": "Casablanca Street, Po Box 30880 Dubai Airport",
- "location": {
- "latitude": 25.247893,
- "longitude": 55.345302
}, - "rooms": { },
- "zone": {
- "id": 21,
- "name": "Dubai",
- "code": "DXB-1"
}, - "featured": false,
- "reviews": {
- "rate": 5,
- "count": 7,
- "max_rate": 5
}, - "accommodations": { },
- "stars": 5,
- "free_cancellation": true,
- "boarding_type": [
- "HALF BOARD",
- "ROOM ONLY",
- "BED AND BREAKFAST",
- "FULL BOARD"
], - "index": "0",
- "price": {
- "currency": "USD",
- "display_price": 270.4,
- "base_price": 240,
- "taxes": 30.4,
- "included_taxes": 0,
- "excluded_taxes": 0,
- "included_taxes_list": [
- { }
], - "excluded_taxes_list": [
- { }
]
}, - "skeleton": true,
- "is_requested_hotel": true,
- "is_available": true
}
], - "status": "progress",
- "requested_hotel": true,
- "is_available": true,
- "fact_groups": {
- "General": {
- "name": "General",
- "facts": {
- "adults_only": {
- "id": 82,
- "name": "Adults only",
- "description": "Adults only",
- "type_hint": "bool",
- "code": "adults_only",
- "icon": "",
- "is_popular": true,
- "identifiers": [ ]
}, - "accessible_rooms": {
- "id": 81,
- "name": "Accessible rooms",
- "description": "Accessible rooms",
- "type_hint": "bool",
- "code": "accessible_rooms",
- "icon": "ri-wheelchair-fill",
- "is_popular": true,
- "identifiers": [ ]
}, - "luggage_storage": {
- "id": 78,
- "name": "Luggage storage",
- "description": "Luggage storage",
- "type_hint": "bool",
- "code": "luggage_storage",
- "icon": "las la-luggage-cart",
- "is_popular": true,
- "identifiers": [ ]
}
}
}
}, - "fact_sheet": [
- { }
]
}Returns the results of a search made with mode: poll. Call it every 2-3 seconds with the search_id of the search.
Each call returns all hotels found so far, in the same structure as the Search response; skeleton hotels are replaced by priced hotels as suppliers answer, so replace what you show each time. Keep calling while status is progress; stop when it is completed.
| search_id required | string
|
{- "search_id": "575f395a-e8c9-4cc4-a85b-a12551678eeb",
- "search": {
- "code": "DXB",
- "country_code": "AE",
- "city": "Dubai",
- "city_geo": { },
- "nights": 2,
- "country": "United Arab Emirates"
}, - "hotels": [
- {
- "type": "HOTEL",
- "check_in": "2025-12-14",
- "check_out": "2025-12-16",
- "name": "Movenpick Grand Al Bustan Hotel",
- "description": "This hotel is located on Casablanca Road...",
- "amenities": [
- "81",
- "78"
], - "address": "Casablanca Street, Po Box 30880 Dubai Airport",
- "location": {
- "latitude": 25.247893,
- "longitude": 55.345302
}, - "rooms": { },
- "zone": {
- "id": 21,
- "name": "Dubai",
- "code": "DXB-1"
}, - "featured": false,
- "reviews": {
- "rate": 5,
- "count": 7,
- "max_rate": 5
}, - "accommodations": { },
- "stars": 5,
- "free_cancellation": true,
- "boarding_type": [
- "HALF BOARD",
- "ROOM ONLY",
- "BED AND BREAKFAST",
- "FULL BOARD"
], - "index": "0",
- "price": {
- "currency": "USD",
- "display_price": 270.4,
- "base_price": 240,
- "taxes": 30.4,
- "included_taxes": 0,
- "excluded_taxes": 0,
- "included_taxes_list": [
- { }
], - "excluded_taxes_list": [
- { }
]
}, - "skeleton": true,
- "is_requested_hotel": true,
- "is_available": true
}
], - "status": "progress",
- "requested_hotel": true,
- "is_available": true,
- "fact_groups": {
- "General": {
- "name": "General",
- "facts": {
- "adults_only": {
- "id": 82,
- "name": "Adults only",
- "description": "Adults only",
- "type_hint": "bool",
- "code": "adults_only",
- "icon": "",
- "is_popular": true,
- "identifiers": [ ]
}, - "accessible_rooms": {
- "id": 81,
- "name": "Accessible rooms",
- "description": "Accessible rooms",
- "type_hint": "bool",
- "code": "accessible_rooms",
- "icon": "ri-wheelchair-fill",
- "is_popular": true,
- "identifiers": [ ]
}, - "luggage_storage": {
- "id": 78,
- "name": "Luggage storage",
- "description": "Luggage storage",
- "type_hint": "bool",
- "code": "luggage_storage",
- "icon": "las la-luggage-cart",
- "is_popular": true,
- "identifiers": [ ]
}
}
}
}, - "fact_sheet": [
- { }
]
}Retrieve comprehensive hotel information including descriptions, amenities, images, and location data to enrich your user experience.
Retrieves comprehensive details about a specific hotel including full description, amenities, gallery images, and location information.
| session required | string <uuid> Search session ID from search response |
| hotel required | string Hotel index from search results |
| currency required | string Currency code |
| language required | string Language preference |
{- "session": "575f395a-e8c9-4cc4-a85b-a12551678eeb",
- "hotel": "0",
- "currency": "USD",
- "language": "en"
}{- "id": 989573,
- "name": "Movenpick Grand Al Bustan Hotel",
- "type": "HOTEL",
- "description": "This hotel is located on Casablanca Road in the Al Garhoud district, just 5 minutes from Dubai International Airport...",
- "stars": 5,
- "address": "Casablanca Street, Po Box 30880 Dubai Airport",
- "city": {
- "id": 5,
- "name": "Dubai",
- "code": "DXB"
}, - "country": {
- "id": 8,
- "name": "United Arab Emirates",
- "code": "AE"
}, - "postal_code": "",
- "phones": [
- {
- "type": "voice",
- "number": "+97142820000"
}
], - "provider": "hotel_beds",
- "coordinates": {
- "latitude": 25.247893,
- "longitude": 55.345302
}, - "emails": [
- "string"
], - "website": "",
- "featured": false,
- "check_in_time": "None",
- "check_out_time": "None",
- "check_in_out_policy": "string",
- "zone": {
- "id": 21,
- "name": "Dubai",
- "code": "DXB-1"
}, - "amenities": [
- "1",
- "2",
- "3"
], - "fact_details": { },
- "facts_groups": {
- "property1": {
- "name": "Object Information",
- "facts": {
- "property1": {
- "id": 1,
- "name": "Hotel Chain",
- "description": "Hotel Chain",
- "type_hint": "bool",
- "code": "hotel_chain",
- "icon": "string",
- "is_popular": false,
- "identifiers": [
- "hotel_chain",
- "Hotel Chain"
]
}, - "property2": {
- "id": 1,
- "name": "Hotel Chain",
- "description": "Hotel Chain",
- "type_hint": "bool",
- "code": "hotel_chain",
- "icon": "string",
- "is_popular": false,
- "identifiers": [
- "hotel_chain",
- "Hotel Chain"
]
}
}
}, - "property2": {
- "name": "Object Information",
- "facts": {
- "property1": {
- "id": 1,
- "name": "Hotel Chain",
- "description": "Hotel Chain",
- "type_hint": "bool",
- "code": "hotel_chain",
- "icon": "string",
- "is_popular": false,
- "identifiers": [
- "hotel_chain",
- "Hotel Chain"
]
}, - "property2": {
- "id": 1,
- "name": "Hotel Chain",
- "description": "Hotel Chain",
- "type_hint": "bool",
- "code": "hotel_chain",
- "icon": "string",
- "is_popular": false,
- "identifiers": [
- "hotel_chain",
- "Hotel Chain"
]
}
}
}
}
}Access detailed room availability, pricing options, meal plans, and cancellation policies for selected hotels to help customers make informed booking decisions.
Retrieves all available room options for a selected hotel, including room types, pricing, meal plans, and cancellation policies.
Each room combination is one complete, bookable option: one room for each room you searched for, with a single total price for all rooms and the whole stay. Similar options are grouped in accommodations.
Rooms response
├── lowest_price the cheapest room combination (same shape as below)
├── free_cancellation at least one combination can be cancelled for free
└── accommodations[] groups of similar options
└── room_combinations[] one bookable option each
├── room_ids[] ─────────────▶ send as `rooms[]` to Check Availability
├── rooms[] one room per room searched for (name, meal, amenities, gallery)
├── total_price price for all rooms and the whole stay
├── meal meal plan of the option
├── refundable false when any room can't be cancelled
├── cancellation_policy when cancellation becomes chargeable
├── can_hold the option can be held without payment
└── deadline hold deadline, when known at this step
total_price.display_price as its price.room_ids to Check Availability. When saving guests, room_index is the position of the room in rooms[] (0 for the first room).use_combination_policy is true, use the combination's cancellation_policy; when false, ignore it and use the cancellation_policy of each room in rooms.can_hold / deadline here are a first indication: confirm them with Check Availability.| session required | string <uuid> Search session ID from search response |
| hotel required | string Hotel index from search results |
| currency required | string Currency code |
| language required | string Language preference |
{- "session": "575f395a-e8c9-4cc4-a85b-a12551678eeb",
- "hotel": "0",
- "currency": "USD",
- "language": "en"
}{- "accommodations": [
- {
- "room_combinations": [
- {
- "room_ids": [
- "0",
- "1"
], - "cancellation_policy": {
- "last_cancellation_deadline": "2019-08-24T14:15:22Z",
- "free_cancellation": true,
- "policies": [
- {
- "from_date": "2025-11-26T16:04:09.771752",
- "to_date": "2025-12-09T23:59:00+04:00",
- "type": "fixed",
- "charge": 182.54,
- "currency": "USD"
}
], - "norms": "string"
}, - "use_combination_policy": true,
- "total_price": {
- "currency": "USD",
- "display_price": 270.4,
- "base_price": 240,
- "taxes": 30.4,
- "included_taxes": 0,
- "excluded_taxes": 0,
- "included_taxes_list": [
- { }
], - "excluded_taxes_list": [
- { }
]
}, - "meal": "ROOM ONLY",
- "rooms": [
- {
- "id": "0",
- "name": "Classic Room With 2 Single Beds",
- "description": "",
- "meal": "ROOM ONLY",
- "meal_amount": 0,
- "meal_description": "",
- "group": "1",
- "gallery": [
- "string"
], - "amenities": [
- "string"
], - "cancellation_policy": {
- "last_cancellation_deadline": "2019-08-24T14:15:22Z",
- "free_cancellation": true,
- "policies": [
- {
- "from_date": null,
- "to_date": null,
- "type": null,
- "charge": null,
- "currency": null
}
], - "norms": "string"
}, - "supplements": { },
- "comments": {
- "rate_comments_id": "string"
}, - "refundable": true,
- "display_price": 0,
- "minStay": 0,
- "dateApplyMinStay": "string"
}
], - "refundable": true,
- "can_hold": true,
- "deadline": "2019-08-24T14:15:22Z"
}
]
}
], - "lowest_price": {
- "room_ids": [
- "0",
- "1"
], - "cancellation_policy": {
- "last_cancellation_deadline": "2019-08-24T14:15:22Z",
- "free_cancellation": true,
- "policies": [
- {
- "from_date": "2025-11-26T16:04:09.771752",
- "to_date": "2025-12-09T23:59:00+04:00",
- "type": "fixed",
- "charge": 182.54,
- "currency": "USD"
}
], - "norms": "string"
}, - "use_combination_policy": true,
- "total_price": {
- "currency": "USD",
- "display_price": 270.4,
- "base_price": 240,
- "taxes": 30.4,
- "included_taxes": 0,
- "excluded_taxes": 0,
- "included_taxes_list": [
- { }
], - "excluded_taxes_list": [
- { }
]
}, - "meal": "ROOM ONLY",
- "rooms": [
- {
- "id": "0",
- "name": "Classic Room With 2 Single Beds",
- "description": "",
- "meal": "ROOM ONLY",
- "meal_amount": 0,
- "meal_description": "",
- "group": "1",
- "gallery": [
- "string"
], - "amenities": [
- "string"
], - "cancellation_policy": {
- "last_cancellation_deadline": "2019-08-24T14:15:22Z",
- "free_cancellation": true,
- "policies": [
- {
- "from_date": "2025-11-26T16:04:09.771752",
- "to_date": "2025-12-09T23:59:00+04:00",
- "type": "fixed",
- "charge": 182.54,
- "currency": "USD"
}
], - "norms": "string"
}, - "supplements": { },
- "comments": {
- "rate_comments_id": "string"
}, - "refundable": true,
- "display_price": 0,
- "minStay": 0,
- "dateApplyMinStay": "string"
}
], - "refundable": true,
- "can_hold": true,
- "deadline": "2019-08-24T14:15:22Z"
}, - "free_cancellation": true
}Confirm the rooms, save the guests, then hold or pay and confirm.
can_hold tells you whether the booking can be held without payment, and deadline until when (pay before it, or the hold is released). They are returned by Get Available Rooms (per room combination), Check Availability and Retrieve Order Details; always use the latest one. A hold is offered only for fully free-cancellation rooms from suppliers that support it, and must be enabled for your account.
Confirms that the selected room combination is still available at the same price, and creates the order for it.
| product_type required | string Value: "hotel" |
| search_id required | string Session ID from the search |
| hotel required | string Hotel code |
| rooms[] required | Array of strings Room IDs of the selected room combination ( |
| currency required | string Example: currency=USD |
| language required | string Example: language=en |
{- "success": true,
- "message": "Product availability checked successfully",
- "available": true,
- "price_changed": false,
- "price_change": 0,
- "price": null,
- "session_id": "575f395a-e8c9-4cc4-a85b-a12551678eeb",
- "order_id": 9120,
- "can_hold": true,
- "deadline": "2026-11-20 23:59:00"
}Saves the contact details and guests on the order created by Check Availability.
This does not book the hotel. Continue with Hold Booking (when
can_holdistrue) or Pay and Confirm Booking.
| session required | string <uuid> Example: 575f395a-e8c9-4cc4-a85b-a12551678eeb Session ID returned by Check Availability ( |
required | object |
required | Array of objects non-empty One entry per guest. The first guest is the lead guest. |
| live_booking | boolean or null
|
{- "contact": {
- "terms": true,
- "email": "john.doe@example.com",
- "mobile": "+966565565655"
}, - "passengers": [
- {
- "title": "Mr",
- "first_name": "John",
- "last_name": "Doe",
- "type": "ADT",
- "room_index": 0,
- "nationality_code": "EG"
}, - {
- "title": "Mrs",
- "first_name": "Jane",
- "last_name": "Doe",
- "type": "ADT",
- "room_index": 0,
- "nationality_code": "EG"
}
], - "live_booking": false
}{- "message": "order stored successfully"
}Reserves the booking without payment. Available only when can_hold is true (see Hold in the overview). Pay with Pay and Confirm Booking before deadline, or the hold is released.
This must be enabled for your account. If it is refused, the response is 403 with the reason (for example, your account's hold limits were reached).
| session required | string <uuid> Example: 575f395a-e8c9-4cc4-a85b-a12551678eeb Session ID returned by Check Availability ( |
{- "message": "Order held successfully",
- "data": [ ],
- "order": {
- "session_id": "575f395a-e8c9-4cc4-a85b-a12551678eeb",
- "status": "hold"
}
}Pays for the booking from your agency balance and confirms it with the supplier. Works for new and held bookings.
Important: After payment, you must poll the Order Details endpoint every 10 minutes for up to 3 hours to receive the final booking status (book_success or book_failed). If no final status is received, mark the booking as "unconfirmed" and contact your account manager.
| session required | string <uuid> Example: 575f395a-e8c9-4cc4-a85b-a12551678eeb Search session ID used in booking creation |
{- "message": "Order confirmed successfully",
- "data": [
- { }
], - "order": {
- "id": 3150,
- "name": "Mr John Doe",
- "session_id": "6b189be6-3139-4398-9a39-b4316e7e3d1a",
- "status": "payment_pending",
- "order_number": "968412709",
- "email": "john.doe@mail.com",
- "phone1": "+19517475601",
- "phone2": "string",
- "ancillaries": [
- { }
], - "created_at": "2025-11-26T16:09:45.000000Z",
- "booking_status": "book_success",
- "reference": "",
- "hcn": "HCN123456",
- "available_actions": [
- {
- "action": "cancel",
- "product_id": 12001
}
]
}
}Retrieve order details and monitor booking status. After payment, poll order details every 10 minutes for up to 3 hours to receive final booking status (book_success or book_failed).
Retrieves comprehensive details of a specific hotel booking, including guest information, room details, pricing, and booking status.
Polling Instructions:
booking_status for the final status: book_success or book_failed (book_pending means keep polling)order.hcn is set when the hotel confirms; it can arrive later than book_success, and some suppliers never return itHold: data.can_hold and data.deadline show whether the booking can be held and until when a held booking must be paid.
Cancel: order.available_actions lists cancel (with its product_id) while the booking can be cancelled through the API; see Cancel Booking.
| session required | string <uuid> Example: 575f395a-e8c9-4cc4-a85b-a12551678eeb Search session ID from booking |
{- "data": {
- "id": 338,
- "hotel_name": "Le Meridien Dubai Hotel & Conference Centre",
- "check_in": "14-12-2025",
- "check_out": "16-12-2025",
- "num_of_pax": 4,
- "num_of_rooms": 2,
- "total_amount": "2,729.99 SAR",
- "rooms": [
- {
- "id": 433,
- "name": "Room DELUXE",
- "meal_type": "BED AND BREAKFAST",
- "guests": [
- {
- "id": 625,
- "type": "ADT",
- "title": "Mr",
- "first_name": "John",
- "last_name": "Boone",
- "age": 6
}
]
}
], - "can_hold": true,
- "deadline": "string"
}, - "order": {
- "id": 3150,
- "name": "Mr John Doe",
- "session_id": "6b189be6-3139-4398-9a39-b4316e7e3d1a",
- "status": "payment_pending",
- "order_number": "968412709",
- "email": "john.doe@mail.com",
- "phone1": "+19517475601",
- "phone2": "string",
- "ancillaries": [
- { }
], - "created_at": "2025-11-26T16:09:45.000000Z",
- "booking_status": "book_success",
- "reference": "",
- "hcn": "HCN123456",
- "available_actions": [
- {
- "action": "cancel",
- "product_id": 12001
}
]
}
}Cancel a booking free of charge before its free-cancellation deadline. The amount is refunded to your agency balance.
Before cancelling
cancellation_policy in Get Available Rooms): free cancellation ends at last_cancellation_deadline, after which policies show the charges.action: cancel in order.available_actions. It is listed only while the booking can be cancelled through the API (free-cancellation booking, before its deadline data.deadline). If it isn't there, the booking can't be cancelled through the API; contact your account manager.product_id.Retrieve Order Details
│
▼
order.available_actions has { action: "cancel", product_id }?
│
├── no ──▶ can't be cancelled through the API (non-refundable, or past the deadline)
│
└── yes ─▶ Cancel Booking (product_id) ──▶ booking cancelled, refund to your balance
Cancels the booking with the supplier and refunds it to your agency balance. Retrieve Order Details then shows booking_status: cancel_success.
Only call it for a product listed with action: cancel in order.available_actions of Retrieve Order Details; any other booking is rejected. Check the rooms' cancellation policy before cancelling.
This endpoint must be enabled for your account. If it returns 403, contact your account manager.
| session required | string <uuid> Example: 575f395a-e8c9-4cc4-a85b-a12551678eeb Session ID returned by Check Availability ( |
| product_id required | integer
|
{- "product_id": 12001
}{- "data": [ ],
- "message": "Hotel Booking Cancelled Successfully",
- "status": true
}All our hotels, to keep in your own system and keep up to date. See Hotels Dump for the download flow.
One line of the full dump file, and the hotel of a delta upsert line.
| id | integer Hotel ID. Use in |
| linked_hotel_ids | Array of integers Other IDs of the same hotel. Search results may show the hotel under one of them. |
object (LocalizedName) Text per language | |
| stars | integer or null |
| type | string or null |
object (LocalizedName) Text per language | |
| postal_code | string or null |
| phone | string or null |
object | |
object or null | |
object | |
object (LocalizedName) Text per language | |
| thumbnail | string or null <uri> |
| images | Array of strings <uri> [ items <uri > ] |
| check_in_time | string or null |
| check_out_time | string or null |
{- "id": 2135352,
- "linked_hotel_ids": [
- 2241871,
- 3011456
], - "name": {
- "en": "InterContinental Cairo Semiramis, an IHG Hotel",
- "ar": ""
}, - "stars": 5,
- "type": "hotel",
- "address": {
- "en": "Corniche El Nil, Cairo 11511",
- "ar": ""
}, - "postal_code": "11511",
- "phone": "+20227957171",
- "geo": {
- "lat": 30.04306,
- "lng": 31.23199
}, - "city": {
- "code": "CAI",
- "name": {
- "en": "Cairo",
- "ar": "القاهرة"
}
}, - "country": {
- "code": "EG",
- "name": {
- "en": "Egypt",
- "ar": "مصر"
}
}, - "description": {
- "en": "Overlooking the Nile…",
- "ar": ""
}, - "check_in_time": "15:00:00",
- "check_out_time": "12:00:00"
}One line of a delta file.
| op required | string Value: "upsert" |
required | object (DumpHotel) One line of the full dump (and the |
{- "op": "upsert",
- "hotel": {
- "id": 2135352,
- "linked_hotel_ids": [
- 2241871,
- 3011456
], - "name": {
- "en": "InterContinental Cairo Semiramis, an IHG Hotel",
- "ar": ""
}, - "stars": 5,
- "type": "hotel",
- "address": {
- "en": "Corniche El Nil, Cairo 11511",
- "ar": ""
}, - "postal_code": "11511",
- "phone": "+20227957171",
- "geo": {
- "lat": 30.04306,
- "lng": 31.23199
}, - "city": {
- "code": "CAI",
- "name": {
- "en": "Cairo",
- "ar": "القاهرة"
}
}, - "country": {
- "code": "EG",
- "name": {
- "en": "Egypt",
- "ar": "مصر"
}
}, - "description": {
- "en": "Overlooking the Nile…",
- "ar": ""
}, - "check_in_time": "15:00:00",
- "check_out_time": "12:00:00"
}
}Links to download all our hotels, or only what changed since the version you last applied.
GET /api/agency/api-out/hotels/dump first time: all hotels
GET /api/agency/api-out/hotels/dump?since=<version> every day: only what changed
type |
When | What to do |
|---|---|---|
full |
First call (no since), or when your copy needs a full reload |
Download url, check sha256, replace all your hotels, keep version |
delta |
Daily call with since |
Download each file of deltas in order, apply its lines, keep its version |
up_to_date |
Nothing changed since your version |
Nothing to do |
A new version is published every day. Links are valid until expires_at (1 hour); call this endpoint again for fresh links.
Full dump (hotels.jsonl.gz): gzip-compressed JSON Lines, one DumpHotel per line. Decompress and read it line by line; the file is large (tens of MB compressed).
Delta (delta.jsonl.gz): one DumpDeltaLine per line:
{"op": "upsert", "hotel": {…}}: add the hotel, or replace the hotel with the same id.{"op": "delete", "id": 3011456, "replaced_by": 2135352}: remove the hotel. When replaced_by is set, the hotel now has that ID; move your mapping to it.Use id in hotels_ids or requested_hotel_ids of Search Hotels; linked_hotel_ids are other IDs of the same hotel that search results may show.
The full dump response has an ETag (its version). Send it back in If-None-Match to get 304 Not Modified while it is still the latest.
This endpoint must be enabled for your account. If it returns 403, contact your account manager.
| since | string^\d{8}T\d{6}Z$ Example: since=20261011T040000Z The |
| If-None-Match | string Example: "20261012T040000Z" The |
{- "data": {
- "type": "full",
- "version": "20261012T040000Z",
- "schema_version": 1,
- "generated_at": "2026-10-12T04:03:51Z",
- "format": "jsonl",
- "compression": "gzip",
- "hotels_count": 183412,
- "size_bytes": 78217765,
- "sha256": "4ac21198d7f5c3479d3434a563d6c19263116e2df9c25c34133c8e62238b9f49",
- "expires_at": "2026-10-12T11:15:00Z"
}, - "message": "Hotels dump retrieved successfully",
- "status": true
}Returns up to 100 hotels rated 4 or 5 stars for each test city: Istanbul (IST), Cairo (CAI), Dubai (DXB), Paris (PAR) and Jeddah (JED). Hotels are in the same format as the hotel hits of Location Autocomplete, with the same IDs as Hotels Dump.
Use a hotel's id in hotels_ids or requested_hotel_ids of Search Hotels, with city_code and country_code for a city search. The list is refreshed daily.
This endpoint must be enabled for your account. If it returns 403, contact your account manager.
{- "data": {
- "CAI": [
- {
- "id": 2135352,
- "name": {
- "en": "InterContinental Cairo Semiramis, an IHG Hotel"
}, - "display_name": {
- "en": "",
- "ar": ""
}, - "description": "InterContinental Cairo Semiramis, an IHG Hotel",
- "display_description": {
- "en": "",
- "ar": ""
}, - "address": {
- "street": "Corniche El Nil PO Casilla 60 Cairo, 11511 Egypt",
- "latitude": "30.04306",
- "longitude": "31.23199",
- "postal_code": "11511"
}, - "display_address": {
- "en": "",
- "ar": ""
}, - "location": {
- "city": "Cairo",
- "country": "Egypt",
- "address": "Corniche El Nil PO Casilla 60 Cairo, 11511 Egypt"
}, - "country": {
- "code": "EG",
- "name": {
- "en": "Egypt",
- "ar": "مصر"
}
}, - "city": {
- "id": 1857,
- "code": "CAI",
- "name": {
- "en": "Cairo",
- "ar": "القاهرة"
}
}, - "_geo": {
- "lat": 30.04306,
- "lng": 31.23199
}, - "city_code": "CAI",
- "country_code": "EG",
- "country_iso_code_2alph": "EG",
- "hotel_type": "hotel",
- "type": "hotel",
- "stars": 5,
- "featured": false,
- "thumbnail": null
}
]
}, - "message": "Sample hotels retrieved successfully",
- "status": true
}Run these hotel scenarios with test bookings (live_booking: false in Save Guest Details) and send us the session ID, supplier reference, HCN and cancellation result of each. Download the hotel test cases (CSV).
| # | Test case | Session ID | Supplier reference | HCN | Cancellation |
|---|---|---|---|---|---|
| 1 | 2 adults | ||||
| 2 | 2 adults + 1 child (11 years old) | ||||
| 3 | 2 adults + 2 children (8 and 9 years old) | ||||
| 4 | 2 rooms: 1 single + 1 double | ||||
| 5 | 1 single room, cancelled before the cancellation deadline (free) | ||||
| 6 | 2 rooms (1 single + 1 triple), within the cancellation penalty period |
How to run the hotel test cases. Each one is a full test booking: Search Hotels, Get Available Rooms, Check Availability, Save Guest Details (live_booking: false), then Pay and Confirm Booking, and Retrieve Order Details until booking_status is final. Record the session ID, the supplier reference and the hcn. Use different hotels and suppliers across the cases.
"rooms": [{"adults": "2", "children": []}]. Send both adults in Save Guest Details with room_index: 0. Expected: booking_status: book_success (possibly after book_pending), with reference and hcn set."rooms": [{"adults": "2", "children": ["11"]}]. Send the 2 adults (type: ADT) and the child (type: CHI, birth matching 11 years), all with room_index: 0."rooms": [{"adults": "2", "children": ["8", "9"]}]. Send the children as type: CHI with their birth dates. room_index starts at 0: the first room is 0."rooms": [{"adults": "1", "children": []}, {"adults": "2", "children": []}] and pick a room combination with 2 rooms. Send the single-room guest with room_index: 0 and the double-room guests with room_index: 1 (their position in the combination's rooms).refundable: true and a future last_cancellation_deadline, and book it. Retrieve Order Details must list cancel in order.available_actions; call Cancel Booking with its product_id. Expected: booking_status: cancel_success, no penalty, and the amount refunded to your balance."rooms": [{"adults": "1", "children": []}, {"adults": "3", "children": []}] and book a combination whose cancellation policy already charges a penalty (non-refundable, or past last_cancellation_deadline). Expected: Retrieve Order Details does not list cancel, Cancel Booking is refused (417), and the penalty you show matches cancellation_policy.policies. Such bookings are cancelled through your account manager.Validations (all cases).
last_cancellation_deadline, then the charges in policies (from_date, to_date, charge, type, currency). Use the combination's policy when use_combination_policy is true, otherwise each room's own policy. If your application adds its own buffer to our deadlines, tell us how much.total_price returns included_taxes_list / excluded_taxes_list, show them. Excluded taxes are paid at the hotel and must be shown to the guest before booking.cancellation_policy.norms (the supplier's remarks) with the room and on the booking confirmation.