Hotels.com rooms
Hotels.com room types and rate plans for one stay window.
/v1/ota/hotels/roomsOne request: the same document as /v1/ota/hotels with the room grid included. Each rate plan keeps its price (the card's lead price; on the US and DE points-of-sale the stay total including taxes and fees) and adds the labelled total and nightly, a derived taxes_and_fees, the payment model and the inventory source.
~100-200 KB against ~6 KB for the headline price, so use it on the dates that matter rather than sweeping a horizon.
Request
https://api.scrapercompany.com/v1/ota/hotels/roomsAuthenticate with your API key in the x-api-key header (see Authentication).
Body
JSON object. Unknown fields are rejected with 422.
- property_idstringrequiredmin length 1
Numeric id returned by
POST /v1/ota/hotels/search, or fromhotels.com/h38766175.Hotel-Information(not the legacyho…number). - check_instring (date)required
First night of the stay,
YYYY-MM-DD. - nightsintegerdefault
1min 1, max 30Length of stay. Ignored when
check_outis supplied. - adultsintegerdefault
2min 1, max 8Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
- marketstringdefault
USPoint-of-sale; also selects the currency.
One of
AUCADEEUFRGBIEITNLNZUS
Example request
curl -X POST "https://api.scrapercompany.com/v1/ota/hotels/rooms" \
-H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"property_id": "12570",
"check_in": "2026-11-30",
"nights": 1,
"market": "US"
}'Response
200 — Room types with rate plans, measured on www.hotels.com (Hilton Chicago, one night). `price` is the card's lead price - here the stay total including taxes and fees - and `total`/`nightly` are the labelled figures. A plan sold pay-now and pay-at-property is two rows. Metered responses carry x-credits-charged and x-credits-remaining headers (see credit headers).
{
"property_id": "12570",
"market": "US",
"check_in": "2029-04-10",
"check_out": "2029-04-11",
"nights": 1,
"currency": "USD",
"requested_currency": "USD",
"currency_verified": true,
"available": true,
"sold_out": false,
"cheapest_rate": 475,
"wire_bytes": 181614,
"egress_mode": "direct",
"rooms": [
{
"name": "Room, 2 Double Beds",
"unit_id": "16572",
"cheapest_rate": 635,
"rate_plans": [
{
"plan_id": "266071193",
"price": 635,
"price_text": "$635 total",
"currency": "USD",
"refundable": false,
"refundable_until": "",
"pay_now": true,
"provenance": {
"schema_version": 1,
"observation_id": "rateobs_0123456789abcdef0123456789abcdef",
"collection_id": "ratecol_0123456789abcdef0123456789abcdef",
"observed_at": "2026-08-07T01:23:45.678Z",
"source": "hotels_com",
"source_kind": "ota_rate_plan",
"collector": "scrapingme.ota.hotels_rooms",
"source_property_id": "12570",
"requested_market": "US",
"requested_currency": "USD",
"returned_currency": "USD",
"egress_mode": "direct",
"price_basis": "stay_rate_plan",
"derivation": "upstream",
"upstream_rate_id": "266071193"
},
"room_type_id": "16572",
"payment_model": "PAY_NOW",
"hotel_collect": false,
"total": 635,
"nightly": 509,
"taxes_and_fees": 126,
"taxes_and_fees_provenance": {
"schema_version": 1,
"observation_id": "rateobs_0123456789abcdef0123456789abcdef",
"collection_id": "ratecol_0123456789abcdef0123456789abcdef",
"observed_at": "2026-08-07T01:23:45.678Z",
"source": "hotels_com",
"source_kind": "ota_rate_plan",
"collector": "scrapingme.ota.hotels_rooms",
"source_property_id": "12570",
"requested_market": "US",
"requested_currency": "USD",
"returned_currency": "USD",
"egress_mode": "direct",
"price_basis": "taxes_and_fees_combined",
"derivation": "total_minus_nightly_times_nights",
"upstream_rate_id": "266071193"
},
"total_text": "$635 total",
"nightly_text": "$509 nightly",
"taxes_and_fees_included": true,
"cancellation_text": "Non-Refundable",
"extras_text": "No extras",
"member_only": false,
"inventory_type": "MERCHANT",
"business_model": "EXPEDIA_COLLECT"
},
{
"plan_id": "266071191",
"price": 742,
"price_text": "$742 total",
"currency": "USD",
"refundable": true,
"refundable_until": "Nov 14",
"pay_now": false,
"room_type_id": "16572",
"payment_model": "PAY_LATER",
"hotel_collect": true,
"total": 742,
"nightly": 599,
"taxes_and_fees": 143,
"total_text": "$742 total",
"nightly_text": "$599 nightly",
"taxes_and_fees_included": true,
"cancellation_text": "Fully refundable before Nov 14",
"extras_text": "No extras",
"member_only": false,
"inventory_type": "DIRECT_AGENCY",
"business_model": "HOTEL_COLLECT"
}
]
},
{
"name": "Suite, Multiple Beds, Non Smoking",
"unit_id": "325392434",
"rate_plans": []
}
]
}Response fields
Fields marked required are always present; others appear when they apply.
- property_idstringrequired
- marketstringrequired
- check_instring (date)required
- check_outstring (date)required
- nightsintegerrequired
- currencystringrequired
- sold_outbooleanrequired
- cheapest_ratenumber | nullrequired
- wire_bytesintegerrequired
- collection_idstringrequired
- observed_atstringrequired
- roomsarray of objectrequired
Show 4 child fieldsHide child fields
- rooms[].namestringrequired
- rooms[].unit_idstringrequired
- rooms[].cheapest_ratenumber | nullrequired
- rooms[].rate_plansarray of objectrequired
Show 8 child fieldsHide child fields
- rooms[].rate_plans[].plan_idstringrequired
- rooms[].rate_plans[].pricenumber | nullrequired
- rooms[].rate_plans[].price_textstringrequired
- rooms[].rate_plans[].currencystringrequired
- rooms[].rate_plans[].refundableboolean | nullrequired
Tri-state: null means the source stated nothing, which is not the same as non-refundable.
- rooms[].rate_plans[].refundable_untilstringrequired
- rooms[].rate_plans[].pay_nowbooleanrequired
- rooms[].rate_plans[].provenanceobjectrequired
Where, when and how one normalized price was observed.
Errors
Errors return a JSON body with a detail field. Failed requests are not charged. See Errors for the full list and retry advice.
| Status | Meaning | Retry? |
|---|---|---|
401Unauthorized | Missing or invalid API key. {"detail":"missing or invalid API key"} | No, fix the request |
402Payment Required | Not enough credits for this request. Only returned once credit enforcement is switched on; during the beta metering runs in shadow mode and never blocks. {"detail":"insufficient credits: this request costs 5, 0 available. Credits renew 2026-11-01."} | No, fix the request |
422Unprocessable Content | Request validation failed. {"detail":[{"loc":["body","token"],"msg":"Field required","type":"missing"}]} | No, fix the request |
429Too Many Requests | Too many requests: the key's requests-per-minute limit was exceeded, or (once credit enforcement is on) the plan's concurrent-request limit. No rate-limit or Retry-After headers are sent; back off and retry. {"detail":"rate limit 60/min exceeded"} | Yes, with backoff |
502Bad Gateway | The upstream source failed, blocked the request or returned an unusable answer. Safe to retry later; failed requests are not charged. {"detail":"RuntimeError"} | Yes, with backoff |
Try it
- Export your key:
export SCRAPERCOMPANY_API_KEY=sk_...(no key yet? request access). - Copy the cURL example above and run it in a terminal.
- Or open the interactive playground on api.scrapercompany.com, paste your key and pick this endpoint.