Expedia Hotel Prices
Pricing
from $1.75 / 1,000 hotel scrapeds
Expedia Hotel Prices
One search, one flat table: hotel name, id, neighbourhood, all-in price for the stay, nightly rate, guest score and review count, and the Expedia URL.
Pricing
from $1.75 / 1,000 hotel scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 hours ago
Last modified
Categories
Share
One search in, one flat table out. Give it a destination and a date; it returns the hotels Expedia would show you, each with its all-in price for the whole stay, Expedia's own nightly rate, the guest score and review count, the neighbourhood, and the URL of the property page.
Built to be called by an agent or a script: small input, small output, one row per hotel, no nested objects, no HTML.
Field names match the Booking.com Hotel Prices actor wherever the two sites
publish the same measurement, so you can run both for one stay and join the rows
on name or compare total_price directly.
Input
| field | default | meaning |
|---|---|---|
destination | required | City, region, district or landmark: Bangkok, Osaka, Bali, Times Square |
checkIn | 30 days out | Check-in date, YYYY-MM-DD |
nights | 1 | Length of stay; check-out is derived from it |
adults | 2 | Adult guests per room |
rooms | 1 | Rooms requested |
currency | USD | Which Expedia point of sale to search — see below |
maxResults | 50 | Stop after this many hotels have been delivered; 100 is the ceiling |
includeUnpriced | false | Also emit properties with nothing bookable, at a null price |
Output
One item per hotel:
| field | meaning |
|---|---|
hotel_id | Expedia's numeric property id, stable across searches |
name | Property name as Expedia displays it |
url | Property page on Expedia, carrying your dates and nothing else |
area | Neighbourhood as Expedia labels the card, e.g. Silom |
star_rating | Official star rating — always null today, see below |
review_score | Expedia guest score out of 10 |
review_count | Number of guest reviews behind that score |
total_price | All-in price for the whole stay |
price_per_night | Expedia's own nightly figure, never divided out of the total |
lead_price | The headline number on Expedia's card, exactly as shown |
lead_price_basis | TOTAL or NIGHTLY — which of the two lead_price is |
currency | Currency the prices are quoted in |
check_in, check_out, nights, adults, rooms | The search the prices belong to |
requested_destination | The destination string you sent, echoed back |
resolved_destination, resolved_region_id | The region Expedia actually searched |
destination_matched | false when Expedia searched somewhere other than what you asked for |
Currency picks the Expedia site
Expedia sets the currency per point of sale, not per request — asking
expedia.com for JPY returns USD, and no cookie or query parameter changes that.
So currency here chooses which Expedia site is searched:
USD expedia.com · GBP .co.uk · EUR .ie · CAD .ca · AUD .com.au ·
NZD .co.nz · SGD .com.sg · MYR .com.my · THB .co.th · HKD .com.hk ·
INR .co.in · JPY .co.jp · PHP .com.ph
Anything outside that list stops the run instead of quietly returning USD: a price column in a currency nobody asked for is worse than no run at all. Property names and price labels are requested in English on every one of those sites.
Note that inventory and price differ genuinely between points of sale — the same hotel is not guaranteed to cost the converted-equivalent on two of them.
Two prices, and which is which
Expedia's card leads with a different number depending on the site: expedia.com
shows the total for the stay and expedia.co.th shows the nightly rate.
Nothing in the payload types the difference, so this actor reads the companion
message Expedia prints beside it — "$147 nightly" next to a total,
"฿16,986 total" next to a nightly rate — and reports the answer in
lead_price_basis.
- When the basis is known,
total_priceandprice_per_nightare both filled. - When it is not — a few points of sale write "for 3 nights, 1 room" with no
figure —
lead_priceis still there and both resolved fields arenull.
price_per_night is never computed by dividing the total by nights, because a
stay whose rate changes from night to night has no single nightly price and
inventing one would be wrong for exactly the bookings people care about.
star_rating is always null right now
Expedia's search cards stopped carrying an official star rating. The field is
still declared in their schema and answered null on 100% of the rows measured
on 2026-08-25, and the older selection that used to carry it returns an empty
list on every point of sale tested. The column is kept — it is part of the
vocabulary shared with the Booking.com actor, and Expedia may start filling it
again — but it is never populated with a guess derived from the review score.
A null here means "Expedia did not say", not "unrated".
Always check destination_matched
Expedia resolves free text on its own side and answers nearly any string with
some region, so a typo or a bad input can produce a complete, successful,
charged run about somewhere else. This actor cannot refuse that outright
without also refusing legitimate variants — Expedia answers Bangkok with
Bangkok, Thailand (BKK-All Airports). So every row carries what you asked for,
what Expedia searched, and a boolean saying whether they agree. Check it before
you trust the prices.
A string Expedia cannot place at all comes back as a failed run with no rows and no per-hotel charges, not as an empty success.
50-100 hotels per search, and why the number moves
Expedia serves 50 properties per page and only two distinct pages per search — every offset above the first page returns the same second page — so 100 is the hard ceiling. Ask for more and the run ends early rather than charging you for repeats.
The second page is also session-bound: Expedia serves it only to a connection that has already asked for the first. When the exit address is rotated mid-walk because of a rate limit, that session is gone, and the actor rebuilds it before retrying. That usually works and sometimes does not, so a search asking for 90 can legitimately deliver 46 or 50. You are charged for rows delivered, never for the repeats, and the run log says how many pages it reached.
To go wider, search narrower — a district instead of a city, or several dates.
Proxy
Residential is required in practice, and it is not optional the way it is on gentler sites. Measured on 2026-08-25: from an ordinary connection the API answers cold, but from a shared proxy pool a bare request was answered HTTP 429 on six consecutive exit addresses. So the actor opens by loading the search page like a browser would, carries those cookies through the walk, and on a refusal backs off with jitter, takes a new address, and rebuilds the session before trying again.
Expedia also occasionally serves an interstitial as HTTP 200. That is treated as "this address is refused" rather than "no results" — an empty dataset is never reported as a successful empty search.
When the pool is contended a run can still exhaust all six of its addresses and
finish with no rows; the log says HTTP 429 and no per-hotel charge is made.
Non-US points of sale are the ones that see it. Re-running usually clears it
within a minute — the same Osaka search that came back empty returned 47 rows on
the next attempt.
Billing
Pay per event: a small fixed charge when the run starts — taken only after the input parses, so a run rejected for a bad date or an unsupported currency is never billed — and one charge per hotel row delivered. Properties skipped for having no price are not charged for.