# Read one hotel for the hotel page

> Returns the content of a hotel for the page the user opens before checkout: description, photos, every room type, policies, facts and contact details, in camelCase (HotelInfo).

Endpoint: `POST /hotels/get_hotel_info`

Source: https://fx-port.com/docs/api/get-hotel-info

`POST /api/v1/hotels/get_hotel_info`

Requires an API key with **Read** permission; a **Read+Write** key works too.

It is the only content call that asks the supplier when FX-Port does not hold the hotel yet, and only for a single id (`hotel_id`): use it for the ids of `missing_hotel_ids`. With `hotel_ids` it returns only the hotels already cached and leaves out the others; an unknown single id answers `404 hotel_not_found`. With `detail_level=minimal` the answer is the compact card instead, which is what a result list needs. A hotel is looked up by its FX-Port id, then by its numeric supplier id (`hid`). Cached content is English whatever `language` you send; `language` only applies to the live fetch. The full document is 5 to 143 KB per hotel (26 KB in the middle, 38 KB on average): cache it by hotel id.

## Request

### Body

Required, JSON.

- `hotel_id` (string, optional): One hotel: its FX-Port id, or its numeric supplier id (`hid`, a JSON integer or digits). Only one id gets a live fetch when the hotel is not cached.
- `hotel_ids` (array of string, optional): Several hotels, at most 200. Only hotels already cached are returned (no live fetch). Wins over `hotel_id`. At most 200 items.
- `detail_level` (string, optional): `full` (default) returns the whole document, `minimal` (alias `mini`) the compact card for result lists. One of `full`, `minimal`, `mini`. Default `full`.
- `images_limit` (integer, optional): With `detail_level` `minimal`: keep only the first N photos of each hotel, 0 to 30. A whole number written as text is read as the number. Between 0 and 30.
- `language` (string, optional): Language of the live fetch of an uncached hotel. A cached hotel is English whatever you send. Default `en`.
- `hotelId` (string, deprecated, optional): Legacy name: use `hotel_id`. One hotel id, in its older spelling. Use `hotel_id`.
- `id` (string, deprecated, optional): Legacy name: use `hotel_id`. One hotel id, in an older spelling. Use `hotel_id`.
- `hid` (string, deprecated, optional): Legacy name: use `hotel_id`. The supplier's numeric hotel id, in an older spelling. Use `hotel_id`, which takes it as well.
- `hotelIds` (array of string, deprecated, optional): Legacy name: use `hotel_ids`. Several hotel ids, in their older spelling. Use `hotel_ids`.
- `ids` (array of string, deprecated, optional): Legacy name: use `hotel_ids`. Several hotel ids, in an older spelling. Use `hotel_ids`.
- `detailLevel` (string, deprecated, optional): Legacy name: use `detail_level`. The detail level, in its older spelling. Use `detail_level`.
- `imagesLimit` (integer, deprecated, optional): Legacy name: use `images_limit`. The photo limit, in its older spelling. Use `images_limit`.

### Example request

```bash
curl https://api.fx-port.com/api/v1/hotels/get_hotel_info \
  -H "Authorization: Bearer fxp_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "hotel_id": "test_hotel_do_not_book",
  "language": "en"
}'
```

## Response

### 200: The hotels that were found, in `data`. An empty list when none of several ids is cached.

- `environment` (string): The environment of the key that made the call: `sandbox` for fxp_test_ keys, `live` for fxp_live_ keys. Present in every JSON body. One of `sandbox`, `live`.
- `request_id` (string): The id of the request, also in the `X-Request-Id` header.
- `warnings` (array of object): Present only when the request used a previous spelling of a field or something the endpoint ignored.
  - `code` (string): What the warning is about. One of `deprecated_field`, `ignored_field`, `coerced_value`, `deprecated_value`, `deprecated_endpoint`.
  - `field` (string): The request field the warning is about.
  - `replacement` (string): The name to use instead, for `deprecated_*` warnings.
  - `message` (string): A sentence that says what happened and what to do.
  - `documentation_url` (string): Where the naming rules are explained.
- `data` (array of object): The hotels that were found, in no particular order: full camelCase documents (`HotelInfo`), or compact cards (`HotelMini`, snake_case) with `detail_level` `minimal`. Hotels that are not found are left out: the list is empty when none is.

```json
{
  "environment": "sandbox",
  "data": [
    {
      "id": "test_hotel_do_not_book",
      "hid": 8473727,
      "name": "Test Hotel (Do Not Book) test",
      "kind": "Apartment",
      "hotelChain": "No chain",
      "isClosed": false,
      "isGenderSpecificationRequired": false,
      "address": "Avenida Roble, Frente al Mall Multiplaza, Tegucigalpa",
      "postalCode": null,
      "latitude": 14.079872,
      "longitude": -87.21677,
      "region": {
        "id": 3421,
        "name": "Tegucigalpa",
        "countryCode": "HN",
        "iata": "TGU",
        "type": "City"
      },
      "starRating": 0,
      "starCertificate": null,
      "contact": {
        "email": "test@example.com",
        "phone": "+15555550123"
      },
      "checkIn": "14:00:00",
      "checkOut": "12:00:00",
      "frontDeskHours": {
        "start": "00:00:00",
        "end": "00:00:00"
      },
      "images": [
        "https://cdn.worldota.net/t/{size}/extranet/b5/d3/b5d3d33394494c68321246882c1bd93a6832dcd5.jpeg"
      ],
      "amenityGroups": [
        {
          "groupName": "General",
          "amenities": [
            "24-hour reception",
            "Early check-in",
            "Late check-out"
          ],
          "paidAmenities": []
        }
      ],
      "serpFilters": [
        "has_internet",
        "has_parking",
        "kitchen"
      ],
      "descriptionStruct": [
        {
          "title": "Location",
          "paragraphs": [
            "A perfect fit for a big group of travellers: apartment «Test Hotel (Do Not Book)» ..."
          ],
          "html": "<h3>Location</h3><p>A perfect fit for a big group of travellers ...</p>"
        }
      ],
      "metapolicyExtraInfo": "Front desk is open 24/7.",
      "metapolicyStruct": {
        "addFee": [],
        "checkInCheckOut": [],
        "children": [
          {
            "age_start": 0,
            "age_end": 3,
            "price": "500.00",
            "currency": "CHF",
            "extra_bed": "available"
          }
        ],
        "childrenMeal": [
          {
            "inclusion": "not_included",
            "price": "200.00",
            "currency": "USD",
            "meal_type": "breakfast",
            "age_start": 0,
            "age_end": 5
          }
        ],
        "cot": [
          {
            "inclusion": "not_included",
            "price": "0.00",
            "currency": "USD",
            "price_unit": "per_room_per_night",
            "amount": 1
          }
        ],
        "deposit": [
          {
            "availability": "available",
            "price": "123.00",
            "currency": "HNL",
            "price_unit": "per_room_per_stay",
            "pricing_method": "fixed",
            "payment_type": "cash",
            "deposit_type": "unspecified"
          }
        ],
        "extraBed": [
          {
            "inclusion": "not_included",
            "price": "100.00",
            "currency": "ALL",
            "price_unit": "per_guest_per_night",
            "amount": 1
          }
        ],
        "internet": [
          {
            "inclusion": "included",
            "price": "0.00",
            "currency": null,
            "price_unit": "unspecified",
            "internet_type": "unspecified",
            "work_area": "hotel"
          }
        ],
        "meal": [
          {
            "inclusion": "not_included",
            "price": "300.00",
            "currency": "USD",
            "meal_type": "breakfast"
          }
        ],
        "noShow": {
          "availability": "available",
          "time": "09:00:00",
          "day_period": "after_midday"
        },
        "parking": [
          {
            "inclusion": "not_included",
            "price": "100.00",
            "currency": "USD",
            "price_unit": "per_car_per_night",
            "territory_type": "unspecified"
          }
        ],
        "pets": [
          {
            "inclusion": "not_included",
            "price": "560.00",
            "currency": "USD",
            "price_unit": "per_room_per_stay",
            "pets_type": "unspecified"
          }
        ],
        "shuttle": [
          {
            "inclusion": "not_included",
            "price": "100.00",
            "currency": "EUR",
            "shuttle_type": "one_way",
            "destination_type": "train"
          }
        ],
        "visa": {
          "visa_support": "support_enable"
        }
      },
      "roomGroups": [
        {
          "roomGroupId": 95,
          "name": "Standard Double room full double bed",
          "nameStruct": {
            "mainName": "Standard Double room",
            "beddingType": "full double bed",
            "bathroom": "shared bathroom"
          },
          "images": [
            "https://cdn.worldota.net/t/{size}/extranet/b5/d3/b5d3d33394494c68321246882c1bd93a6832dcd5.jpeg"
          ],
          "roomAmenities": [
            "bath",
            "heating"
          ],
          "roomClass": "room",
          "quality": "standard",
          "bathroom": "private-bathroom",
          "hasPrivateBathroom": true,
          "capacity": 2,
          "balcony": false,
          "view": null,
          "floor": null,
          "bedrooms": null,
          "beddingType": "double-bed",
          "isFamily": false,
          "isClub": false,
          "genderRestriction": null
        }
      ],
      "facts": {
        "floorsNumber": null,
        "roomsNumber": null,
        "yearBuilt": null,
        "yearRenovated": null,
        "electricity": {
          "voltage": [],
          "frequency": [
            60
          ],
          "sockets": [
            "a",
            "b"
          ]
        }
      },
      "paymentMethods": [
        "visa",
        "maestro",
        "cash"
      ],
      "keysPickup": {
        "type": "lockbox",
        "isContactless": true,
        "email": "test@example.com",
        "phone": "+15555550123",
        "officeAddress": null,
        "extraInfo": "The keys are in the box by the front door."
      }
    }
  ]
}
```

## Errors

| Status | Code | Example message |
| --- | --- | --- |
| 400 | `missing_field` | Hotel IDs are required (hotelId or hotelIds) |
| 400 | `invalid_hotel_ids` | 'hotel_ids' must be a list of hotel ids. |
| 400 | `too_many_ids` | At most 200 hotel ids per request. |
| 400 | `invalid_images_limit` | 'images_limit' must be an integer from 0 to 30. |
| 404 | `hotel_not_found` | No hotel with this id exists at the supplier. |
| 429 | `supplier_rate_limited` | The hotel supplier is receiving too many requests. Retry in a minute. |
| 502 | `supplier_error` | The hotel supplier could not process the request right now. Retry in a few minutes. |
| 502 | `supplier_invalid_response` | The hotel supplier returned an answer that could not be used. Retry in a few minutes. |
| 503 | `supplier_unavailable` | The hotel supplier could not be reached. Retry in a few minutes. |
| 503 | `supplier_timeout` | The hotel supplier did not answer in time, so the request may or may not have been processed: read the booking's status before you retry. |
| 503 | `supplier_busy` | The supplier is temporarily at capacity; retry after the time given in the Retry-After header. |

See [Errors](https://fx-port.com/docs/errors.md) for every code and how to react.

## Related guides

- [Hotel details](https://fx-port.com/docs/hotels/hotel-details.md)
- [Mini and full hotel data](https://fx-port.com/docs/hotels/hotel-data.md)
