Get a hotel booking
Retrieve the full hotel booking, including the pricing breakdown and the voucher PDF link, through the shared account booking endpoint.
GET/api/v1/bookings/{booking_id}?product=hotels
Read a hotel booking: its status (the one to poll after book_hotel), what the traveler pays and what you were debited, the hotel and the dates, and the voucher links. Hotel bookings are read through the shared booking endpoint of the account area, documented in Booking detail: pass product=hotels. This page says what to read for a hotel.
Permission: Read
Request
GET /
| Part | Description |
|---|---|
booking_id (path) | The bookingId of book_hotel (the partnerOrderId of pre_book). The internal id (a UUID) works too. |
product (query) | hotels. Without it the products are tried one after the other: it is slower and can match a booking of another product. |
curl 'https://api.fx-port.com/api/v1/bookings/HMVXX4ZQ3?product=hotels' \
-H "Authorization: Bearer fxp_test_YOUR_KEY"A booking is visible to your agency only, in the environment of your key: a sandbox booking is not found with a live key, and the other way round. An id that matches nothing answers 404 booking_not_found.
Response
A real answer of the sandbox for a confirmed booking (trimmed; the id and the links are replaced):
{
"environment": "sandbox",
"success": true,
"data": {
"product": "hotels",
"id": "24fec1e5-a09f-48ec-8050-1adaab0a8de1",
"bookingId": "HMVXX4ZQ3",
"status": "confirmed",
"environment": "sandbox",
"currency": "DZD",
"totalPrice": 1484.97,
"netPrice": 1482,
"agencyCommission": 2.97,
"providerName": "ETG - RateHawk",
"supplierId": "ratehawk",
"createdAt": "2026-11-01T15:32:10.51714+00:00",
"updatedAt": "2026-11-01T15:32:26.802414+00:00",
"hotelId": "test_hotel_do_not_book",
"hotelName": "Test Hotel (Do Not Book) test",
"checkinDate": "2026-12-01",
"checkoutDate": "2026-12-04",
"voucherUrl": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith.pdf",
"voucherUrlWithPrice": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith.pdf",
"voucherUrlNoPrice": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith-no-price.pdf",
"record": {
"id": "24fec1e5-a09f-48ec-8050-1adaab0a8de1",
"booking_id": "HMVXX4ZQ3",
"status": "confirmed",
"currency": "DZD",
"total_price": 1484.97,
"agency_commission": 2.97,
"hotel_id": "test_hotel_do_not_book",
"hotel_name": "Test Hotel (Do Not Book) test",
"checkin_date": "2026-12-01",
"checkout_date": "2026-12-04",
"bucket_link": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith.pdf",
"bucket_link_no_price": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith-no-price.pdf",
"supplier_id": "ratehawk",
"created_at": "2026-11-01T15:32:10.51714+00:00",
"updated_at": "2026-11-01T15:32:26.802414+00:00",
"environment": "sandbox",
"refund_amount": null,
"refund_currency": null
},
"pricing": [
{
"id": "2cf80a07-f588-4a2a-afc6-c732ee205f8c",
"created_at": "2026-11-01T15:32:16.39859+00:00",
"agency_currency": "DZD",
"total_price": 1484.97,
"agency_commission": 2.97,
"environment": "sandbox",
"b2b_price": 1482
}
],
"balanceOperations": []
},
"meta": {
"agencyId": "0b1c2d3e-4f50-4a6b-8c7d-9e0f1a2b3c4d",
"environment": "sandbox"
}
}What to read
| Field | Description |
|---|---|
data.status | pending, confirmed, failed, refunded, partial_refund or cancelled. Poll while it is pending, every 2 seconds: it changes in 4 to 14 seconds. See From pending to confirmed. |
data.totalPrice | What the traveler pays, in the currency of your agency. |
data.netPrice | What was debited from your agency: totalPrice - agencyCommission. It is pricing[0].b2b_price. Nothing is debited in the sandbox. |
data.agencyCommission | Your commission. |
data.hotelId, hotelName, checkinDate, checkoutDate | The hotel and the stay. The dates have no time. Send hotelId to get_hotel_info to show the hotel again. |
data.voucherUrl, voucherUrlWithPrice, voucherUrlNoPrice | The voucher PDFs: voucherUrl and voucherUrlWithPrice are the same link (the voucher with the price), voucherUrlNoPrice is the voucher without it. null until they are made, a few seconds after confirmed. The same links as get_voucher. |
data.supplierId, providerName | The supplier of the booking: ratehawk, ETG - RateHawk. |
record.refund_amount, refund_currency | What was refunded to your agency, after a cancellation. null before. |
pricing[] | The price lines of the booking: total_price, agency_commission and b2b_price (what you pay). |
balanceOperations[] | The debits and credits of the booking on your balance. Empty in the sandbox. |
The hotel keys of the summary also come as snake_case twins: hotel_id, hotel_name, checkin, checkout, voucher_url, voucher_url_with_price and voucher_url_no_price. See Legacy names. The full field reference of the shared endpoint is in Booking detail, and the list of your hotel bookings is Booking history with product=hotels.
Good practice
- Poll every 2 seconds, not faster. A booking changes within 4 to 14 seconds, and faster polling only uses your rate limits. Stop at
confirmedorfailed. - Read before you retry. After a timeout or a
5xxonbook_hotelorcancel_hotel, this is the call that tells what happened. - Keep
bookingId. It is the key of the booking everywhere: the detail, the voucher, the cancellation.
Errors
| HTTP | Code | Cause |
|---|---|---|
400 | invalid_booking_id | The reference is not a booking id. |
404 | booking_not_found | No booking of your agency in this environment has this id, or it belongs to another product. |
401, 403 | The key is missing, wrong or not allowed: Authentication. | |
429 | rate_limit_exceeded | Too many calls: Rate limits. |