10 min read
How to track hotel prices and rate parity
Collect room rates, taxes and member rates from Booking.com, Expedia and hotel websites, by date.
| Site | Shown as | Rate |
|---|---|---|
| Booking.com | Before taxes | $309 |
| Expedia | Nightly | $309 |
| Expedia | Total with taxes | $358 |
| Hyatt.com | Standard rate | $309 |
| Hyatt.com | Member rate | $278 |
The String Web Access API is the best way to track hotel prices and rate parity. It returns any Booking.com, Expedia or hotel brand page for the dates you pick, or just each room's rate, taxes and cancellation terms as JSON. It returned 97% of requests across 100 bot-protected sites in our September 2026 benchmark, the most of 16 providers, and was the only one to fetch all 9 travel sites on every attempt.
Quickstart
Add the hosted MCP server to Claude, Cursor, ChatGPT or any MCP client. Then give your agent a Booking.com, Expedia or hotel website URL with your check-in and check-out dates. It calls the web_access_fetch tool and reads the room rates.
https://mcp.usestring.ai/v1/mcp
One call returns every room on a Booking.com hotel page for one night, with its price, currency and the taxes Booking.com leaves out of the price. If the page has no rooms, you get "extracted": false back instead of a guess.
curl https://request.usestring.ai/v1/fetch \
-H "Authorization: Bearer $STRING_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.booking.com/hotel/us/hyatt-place-new-york-city-times-square.html?checkin=2026-11-20&checkout=2026-11-21&group_adults=2&no_rooms=1&selected_currency=USD",
"countryCode": "US",
"jsonSchema": {
"type": "object",
"properties": {
"hotel": { "type": "string" },
"rooms": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"room": { "type": "string" },
"price": { "type": "number" },
"currency": { "type": "string" },
"excluded_taxes": { "type": "string" },
"free_cancellation": { "type": "boolean" }
},
"required": ["room", "price", "currency"]
}
}
},
"required": ["hotel", "rooms"]
}
}'Response
{
"hotel": "Hyatt Place New York City - Times Square",
"rooms": [
{
"room": "King Room with Sofa Bed - High Floor",
"price": 309,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
},
{
"room": "King Room with Sofa Bed and City View",
"price": 323,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
},
{
"room": "Specialty King Room with Sofa Bed",
"price": 329,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
},
{
"room": "Standard Double Room with Two Double Beds",
"price": 598,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
},
{
"room": "Double Room with Two Double Beds - High Floor",
"price": 627,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
},
{
"room": "Double Room with Two Double Beds and City View",
"price": 639,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
},
{
"room": "Standard Double Room with Two Double Beds and Sofa Bed",
"price": 842,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
},
{
"room": "Double Room with Two Double Beds and Sofa Bed",
"price": 884,
"currency": "USD",
"excluded_taxes": "14.75 % TAX, $4 City tax per night",
"free_cancellation": true
}
]
}Why track hotel prices?
A hotel's rate for a given night changes as the date gets closer, and it can differ between Booking.com, Expedia and the hotel's own website. A rate tracker fetches the same hotel, room and dates from each site on a schedule and records what each one charges. Hotels and travel apps use it to answer questions like these:
- Are we at rate parity? On October 26, 2026, the High Floor King at Hyatt Place New York City / Times Square was $309 a night on Booking.com, Expedia and hyatt.com for November 20. Hyatt's member rate was $278.
- What are the hotels around us charging? Revenue managers set tonight's rate against a set of nearby competitors, night by night.
- When is the best time to book? Travel apps and corporate travel teams watch a booked rate and rebook when the same room drops.
What you can collect
Room rates by date
The price of each room type for any check-in and check-out dates and number of guests, in the currency you choose.
Taxes and fees
Booking.com lists the taxes it leaves out of the price, and Expedia shows a total with taxes and fees next to the nightly rate.
Rate plans and conditions
Member and standard rates on hotel websites, free cancellation, breakfast and pay-at-the-property terms.
Availability
Which room types are on sale, and notes such as "We have 3 left at this price".
Why does hotel price tracking break?
- Booking sites block scrapers. In our September 2026 benchmark, 8 of the 15 other scraping APIs couldn't fetch booking.com on every attempt, and 5 got 0 of 5: Apify, Oxylabs, Zyte, Browserbase and ScrapingAnt. Context.dev, Scrapingdog and Browserbase got 0 of 5 on expedia.com, and Bright Data got 1. Across booking.com, expedia.com and hyatt.com, only String and Firecrawl returned all 15 attempts.
- Rates load after the page does. A plain fetch of the Expedia hotel page returned the hotel's description and a "Loading" placeholder where the rooms go, with HTTP 200. Hyatt.com's rate page came back with the hotel's address and no rates.
- The same rate looks different on each site. Booking.com showed $309 with a 14.75% tax and a city tax listed separately. Expedia showed $309 nightly and $358 total. Compare the wrong two numbers and a hotel at parity looks $49 apart.
Why do teams choose String?
- It fetches the most pages. String returned 97% of requests across 100 bot-protected sites in our September 2026 benchmark, the most of 16 providers, and every attempt on Booking.com, Expedia, Hyatt, Airbnb and Tripadvisor.
- Waiting for the rates is one action. Booking.com carries its room table in the HTML. For Expedia and hotel websites, add a
waitaction and String returns the page once the rooms have loaded. - You pay only for pages that come back. Blocks and errors are free.
- There's nothing to maintain. You don't run proxies, fingerprints or captcha solvers.
How do I build a hotel rate tracker?
Put the dates and guests in every URL
A hotel page without dates has no room rates on it. Booking.com takes
checkin,checkout,group_adultsandselected_currency. Expedia takeschkin,chkoutandrm1=a2for one room with two adults. Keep the guests and currency the same on every run.Match rooms, not hotels
Each site names the same room differently. Hyatt.com's "High Floor | King Bed (Plus Sofa Bed)" is Booking.com's "King Room with Sofa Bed - High Floor" and Expedia's "Room, 1 King Bed with Sofa bed (High Floor)". Map each site's room name to one room code. Don't compare the cheapest room on each site: hyatt.com sold a $294 Standard King that Booking.com didn't list and Expedia listed without a price.
Fetch each page once its rates have loaded
Booking.com hotel pages carry the room table in the HTML. Expedia and hyatt.com load rates with JavaScript after the page arrives.
With String: Add a
waitaction on the room list for Expedia and hotel websites, and pass ajsonSchemato get only the rooms and rates. Blocked requests are retried, and you don't pay for the ones that fail.Compare totals with taxes, or nightly rates without them
Store the nightly rate, the taxes and fees, and the total separately, with a flag for which one each site showed. Booking.com's $309 plus 14.75% tax and $3.50 city tax comes to $358.08, the same as Expedia's $358 total.
Treat a missing rate as a failure
A page with no rooms was probably blocked, still loading, or sold out for those dates. Flag it and keep the last good rate, so the gap never gets saved as a price. Check optional fields too: in our hyatt.com run, extraction filled in a member rate for a room that showed only a standard rate. Make fields like
member_ratenullable and check them against the page.Check the dates that matter, on a schedule
For most hotels, check the next 30 to 90 nights once a day, and add checks for nights with an event in town. Save each run with the date it was fetched and the stay date, and alert when a site breaks parity or a competitor moves its rate.
Get a free sample rate feed
Tell us which hotels, dates and sites you track. We'll run String on Booking.com, Expedia and the hotels' own websites and email you a sample feed of room rates, taxes and terms, free.
| Site | Shown as | Rate |
|---|---|---|
| Booking.com | Before taxes | $309 |
| Expedia | Nightly | $309 |
| Expedia | Total with taxes | $358 |
| Hyatt.com | Standard rate | $309 |
| Hyatt.com | Member rate | $278 |
Frequently asked questions
What's the best way to track hotel prices?
Fetch each hotel's Booking.com, Expedia and brand website pages for the dates you care about, on a schedule, and store each room's rate with its taxes and terms. The hard part is getting the pages, because booking sites block most scrapers and Expedia and hotel websites load rates with JavaScript. The String Web Access API returned 97% of requests across 100 bot-protected sites in our September 2026 benchmark, the most of 16 providers, and every attempt on all 9 travel sites.
How do I scrape Booking.com hotel prices?
Fetch the hotel's Booking.com page with checkin, checkout, group_adults and selected_currency in the URL, and read the room table. Without dates, the page has no rates. For a whole city, the search results page lists each property's cheapest room and price; for New York on November 20, 2026, it reported 474 properties. Booking.com was the hardest hotel site in our September 2026 benchmark: 8 of the 15 other scraping APIs couldn't fetch it on every attempt. String fetched it on all 5.
How do hotels monitor rate parity?
Rate parity monitoring checks that a hotel's rate for the same room, dates and conditions is the same on its own website and on online travel agencies such as Booking.com and Expedia. Fetch all three for each stay date, map the rooms to one code, compare like for like (both before tax or both with tax), and alert when a site is lower than the hotel's own public rate. Keep member rates separate, since they are meant to undercut the public rate.
How much does it cost to track hotel prices?
Booking.com hotel pages billed at String's premium fetch rate on our fetches, $3.00 per 1,000 successful requests on the Starter plan ($20 a month). Expedia and hyatt.com pages with a wait action billed at the browser standard rate, $1.50 per 1,000. On Growth ($100 a month) the rates are $2.00 and $1.00. Tracking 20 hotels for the next 30 nights, once a day, is 18,000 requests a month per site: $54 in usage on Booking.com and $27 on Expedia, on Starter. Structured extraction with jsonSchema adds a per-request fee that scales with page size. The first 5,000 standard requests are free, and failed requests aren't billed. See pricing.
Is it legal to scrape hotel prices?
Room rates on public booking pages are facts, and collecting public prices is the best-supported case in scraping law. Booking site terms of service often restrict automated access, and guest reviews carry personal data, so leave reviewer details out. Stay on public pages, keep your request rate reasonable, and check with your counsel. We go through the cases in Is it legal to scrape competitor prices?
Can I get prices from every booking site in one call?
Yes, String's Google Hotels integration returns the offers Google Hotels shows for a property, one per booking site, each with the nightly price, the total with taxes, free cancellation and a booking link. Use it to see which sites sell the room, then fetch those sites directly for room-level rates. See the Google Hotels integration docs.
Can I see the rates guests see in other countries?
Yes, String fetches the page from the country you set in countryCode. Set the currency in the URL too, such as Booking.com's selected_currency, so prices from different markets stay comparable.
How do I know a fetch returned the real rates?
Check for the rates, not the status code. Our plain fetches of the Expedia and hyatt.com rate pages came back as HTTP 200 with no room prices on them, because the rates load afterwards. Require the room list in your schema with minItems: 1, and see how to detect a bot block behind an HTTP 200. For airfares, see how to scrape flight prices.
Does String work on the hotel sites I need?
Send us the URLs and we'll run them and show you what comes back before you commit. Ask for a free sample rate feed, or test them yourself with your first 5,000 free requests.