Skip to content

Hotels API

Hotel API

Multi-supplier accommodation search, booking and cancellation behind one contract.

Design-partner previewBuilt and demonstrable; onboarding a limited number of design partners.

What does the TravelCore hotel booking API do?

The hotel API searches many supplier contracts through one request, returns properties already deduplicated by the mapping engine, and prices results with your own markup rules before they reach you. Booking requires an idempotency key. Suppliers that miss their time budget are named in the response instead of disappearing from it.

The Hotel API is the centre of the platform. It fans a single search out to every connected supplier in parallel, maps the returned properties onto one TravelCore property object, applies your pricing rules, and returns a single ranked result set. Booking, modification and cancellation run through the same normalised surface, whichever supplier ultimately holds the reservation.

Coverage

Coverage is the union of the suppliers you are contracted with. Large aggregators in this market publish counts in the range of 1M to 2.5M properties; the number you actually see depends on your own supplier agreements, the markets they cover, and the rate types you are entitled to. TravelCore does not own hotel inventory and does not resell a coverage figure it cannot verify for your account.

Latency behaviour

Search returns as soon as the fastest suppliers answer. The default per-supplier budget is 6000 ms; suppliers that exceed it are reported as `timeout` in the response and the result set is marked `partial: true` rather than the whole call failing.

Authentication

OAuth 2.0 client credentialsShort-lived bearer access tokenTenant scoping via X-TravelCore-Tenant
Stated plainly:This API is built and available to design partners. Sandbox responses are realistic but are not live supplier data.

Capabilities

  • Parallel multi-supplier search with per-supplier timeout budgets
  • Unified property object across suppliers (mapping and deduplication)
  • Room, rate plan, board basis and occupancy normalisation
  • Structured cancellation policies with absolute deadlines, not prose
  • Pricing engine applied server-side: net, markup, commission, tax, fees
  • Multi-currency quoting with the FX rate stamped on the quote
  • Booking, retrieval, modification where the supplier allows, and cancellation
  • Voucher generation from the stored booking record

What it does not do

  • Rate-level content (photos of the exact room) varies by supplier and is passed through, not synthesised.
  • Modification support is supplier-dependent; where a supplier has no modify path, the API reports it rather than silently cancelling and rebooking.
  • Loyalty-rate and negotiated-corporate-rate access requires your own agreement with the supplier.

Reference

Endpoints

The full surface, with real request and response shapes where the endpoint is implemented.

POST/v1/hotels/search

Fan out an availability search across every connected supplier and return one merged result set.

Request
POST /v1/hotels/search
Authorization: Bearer <access_token>
X-TravelCore-Tenant: tnt_8f2c41
Content-Type: application/json
 
{
"destination": { "type": "city", "code": "DXB" },
"checkIn": "2026-11-12",
"checkOut": "2026-11-16",
"occupancies": [
{ "adults": 2, "children": [7] }
],
"currency": "AED",
"nationality": "EG",
"filters": {
"minStarRating": 4,
"boardBasis": ["BB"],
"freeCancellationOnly": true
},
"timeoutMs": 6000
}
Response
200 OK
 
{
"searchId": "srch_01JQ8Y3M4K7B2R",
"currency": "AED",
"partial": true,
"suppliers": [
{ "id": "sup_alpha", "status": "ok", "tookMs": 812, "results": 214 },
{ "id": "sup_beta", "status": "ok", "tookMs": 1440, "results": 168 },
{ "id": "sup_gamma", "status": "timeout", "tookMs": 6000, "results": 0 }
],
"properties": [
{
"propertyId": "tvc_htl_92f0c1",
"name": "Downtown Grand Dubai",
"starRating": 5,
"geo": { "lat": 25.1972, "lng": 55.2744 },
"supplierRefs": [
{ "supplierId": "sup_alpha", "supplierPropertyId": "A-118322" },
{ "supplierId": "sup_beta", "supplierPropertyId": "HB-7741201" }
],
"cheapestRate": {
"rateId": "rt_01JQ8Y3M9F",
"boardBasis": "BB",
"refundable": true,
"cancellationDeadline": "2026-11-09T21:00:00Z",
"price": {
"net": 3120.00,
"markup": 468.00,
"tax": 187.20,
"serviceFee": 40.00,
"total": 3815.20,
"currency": "AED"
}
}
}
]
}

Worth knowing

  • `partial: true` means at least one supplier did not answer within its budget. Render what you have; do not block the page.
  • The `suppliers` array is always returned so you can attribute slowness and coverage gaps precisely.
  • `searchId` must be echoed on booking so the platform can re-validate the quoted price against the supplier.
GET/v1/hotels/properties/{propertyId}

Full unified content for one property: description, amenities, images, geo, policies and room types.

POST/v1/hotels/rates/{rateId}/check

Re-validate a rate against the supplier immediately before payment, returning the binding price.

Worth knowing

  • Always call this before charging the customer. Suppliers reprice; this endpoint is where you discover it, not after the card is captured.
POST/v1/hotels/bookingsIdempotency-Key required

Create a booking against a checked rate.

Request
POST /v1/hotels/bookings
Authorization: Bearer <access_token>
Idempotency-Key: 9d4f1c2a-77b0-4e33-9a51-3c0e9b1d6f21
Content-Type: application/json
 
{
"rateId": "rt_01JQ8Y3M9F",
"searchId": "srch_01JQ8Y3M4K7B2R",
"holder": {
"firstName": "Mahmoud",
"lastName": "Elminyawi",
"email": "holder@example.com",
"phone": "+201000000000"
},
"rooms": [
{
"guests": [
{ "type": "adult", "firstName": "Mahmoud", "lastName": "Elminyawi" },
{ "type": "adult", "firstName": "Sara", "lastName": "Elminyawi" },
{ "type": "child", "age": 7, "firstName": "Omar", "lastName": "Elminyawi" }
]
}
],
"payment": { "method": "agent_wallet", "walletId": "wal_3310ab" },
"clientReference": "OTA-2026-000148"
}
Response
201 Created
 
{
"bookingId": "bkg_01JQ8YB4T2N6",
"status": "confirmed",
"supplierReference": "A-CNF-882731",
"clientReference": "OTA-2026-000148",
"priceLocked": {
"total": 3815.20,
"currency": "AED",
"matchedSearchPrice": true
},
"cancellationPolicy": [
{ "from": "2026-11-09T21:00:00Z", "penalty": { "amount": 780.00, "currency": "AED" } },
{ "from": "2026-11-11T21:00:00Z", "penalty": { "amount": 3815.20, "currency": "AED" } }
],
"voucherUrl": "https://api.travelcore.tech/v1/hotels/bookings/bkg_01JQ8YB4T2N6/voucher",
"createdAt": "2026-08-28T09:14:03Z"
}

Worth knowing

  • An `Idempotency-Key` is mandatory. Replaying the same key returns the original booking instead of creating a second one.
  • `priceLocked.matchedSearchPrice` tells you whether the supplier honoured the searched price or repriced during the flow.
GET/v1/hotels/bookings/{bookingId}

Retrieve a booking with its current status, policies and supplier reference.

POST/v1/hotels/bookings/{bookingId}/cancelIdempotency-Key required

Cancel a booking and return the penalty actually applied by the supplier.

Worth knowing

  • The response carries the supplier's applied penalty, which may differ from the quoted policy if the deadline passed mid-request.