# Get a hotel booking

> Retrieve the full hotel booking, including the pricing breakdown and the voucher PDF link, through the shared account booking endpoint.

Endpoint: `GET /api/v1/bookings/{booking_id}?product=hotels`

Source: https://fx-port.com/docs/hotels/get-booking

Read a hotel booking: its **status** (the one to poll after [`book_hotel`](https://fx-port.com/docs/hotels/book.md)), 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](https://fx-port.com/docs/account/booking-detail.md): pass `product=hotels`. This page says what to read for a hotel.

**Permission:** Read

## Request

`GET /api/v1/bookings/{booking_id}?product=hotels`

| Part | Description |
|---|---|
| `booking_id` (path) | The `bookingId` of [`book_hotel`](https://fx-port.com/docs/hotels/book.md) (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. |


**Request**

```bash
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):

~~~json
{
  "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](https://fx-port.com/docs/hotels/book.md#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`](https://fx-port.com/docs/hotels/hotel-details.md) 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`](https://fx-port.com/docs/hotels/voucher.md). |
| `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](https://fx-port.com/docs/legacy-names.md). The full field reference of the shared endpoint is in [Booking detail](https://fx-port.com/docs/account/booking-detail.md), and the list of your hotel bookings is [Booking history](https://fx-port.com/docs/account/history.md) 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](https://fx-port.com/docs/rate-limits.md). Stop at `confirmed` or `failed`.
- **Read before you retry.** After a timeout or a `5xx` on `book_hotel` or `cancel_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](https://fx-port.com/docs/authentication.md). |
| `429` | `rate_limit_exceeded` | Too many calls: [Rate limits](https://fx-port.com/docs/rate-limits.md). |

## Related


- [Book a hotel](https://fx-port.com/docs/hotels/book.md): Where the booking id comes from and how long `pending` lasts.
- [Get the hotel voucher](https://fx-port.com/docs/hotels/voucher.md): The voucher links alone.
- [Cancel a hotel booking](https://fx-port.com/docs/hotels/cancel.md): Free until 21:00 UTC on the check-in day in the sandbox.
- [Booking detail](https://fx-port.com/docs/account/booking-detail.md): The shared endpoint, every field.
