Every row gives you: name, stars, review score, nightly price (tax-inclusive), availability, cover image, address, geo. Two modes. Search a city for every hotel + homestay, or monitor specific properties across dates with price-change deltas and next-available on sold-out. Covers Agoda Homes.
All notable, user-visible shipments to the Agoda Property Scraper. Latest on top. Format follows keep-a-changelog .
v8 schema — findNextAvailable on discovery rows
Search-result rows now support the same "nearest available date" hop as monitor mode. When a requested check-in is sold out, set findNextAvailable: true and the row gains a nextAvailableCoverage block with the next bookable check-in, the price on that date, and how many days of the ± window were scanned. Useful for discovery runs where you want a signal even on fully-booked stretches.
sortBy + skipSeen + skipPropertyIds — multi-sort city fanout
Agoda paginates any single sort to roughly 650–1000 properties per city. Run the same input four times with bestMatch, reviewScore, lowestPriceFirst, and highestPriceFirst, then set skipSeen: true (or pass explicit IDs via skipPropertyIds) to dedup across runs. Typical uplift: 1.5–2× more unique properties versus a single sort. No external storage required — dedup state lives in the actor's key-value store.
canaryTtlMinutes — schema-drift early warning
A lightweight canary probe runs alongside your scrape on a configurable TTL. If Agoda changes the shape of their search or room-grid responses, the next run flags the drift in run-report.anomalies before rows start going blank in production.
Price monitoring API calls now route through the datacenter proxy pool by default. Validated byte-identical to residential on the endpoints we use, at a fraction of the cost. The initial property page load still uses residential (Agoda gates datacenter IPs there). Flip apiProxyDatacenter: false to route everything through residential if you need geo-accurate local pricing on every cell.
City-day summary rows
Every run now emits one city-day-summary row per cityId × checkIn, in addition to the per-property quote rows. Fields include priceRankInCity, priceCategory, median/p25/p75 price across the pool, and property counts. Feed this into a dashboard for instant "is today cheap or expensive for Bangkok?" visuals without post-processing the main dataset.
run-report row
Every run appends one run-report row to the dataset with totals, fill-rate percentages, and anomalies. Wire a webhook on anomalies.length > 0 to catch upstream breakage the moment it happens, instead of hours later when blank rows show up in your BI tool.