Agoda Reviews Scraper
Pricing
from $3.00 / 1,000 reviews
Agoda Reviews Scraper
Scrape public Agoda hotel guest reviews: rating, text, stay dates, room type, traveler type, and country. HTTP reviews API alternative for hotel comps.
Pricing
from $3.00 / 1,000 reviews
Rating
0.0
(0)
Developer
Andrej Kiva
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
19 days ago
Last modified
Categories
Share
Disclaimer: Unofficial tool — not affiliated with, sponsored by, or endorsed by Agoda Company Pte. Ltd. or its affiliates. Data is read from publicly accessible hotel review pages only. No login. You are responsible for complying with applicable law (including GDPR where personal data appears) and the site’s terms. No warranty on accuracy or availability. Provided for informational and research use.
Agoda reviews scraper for public hotel guest reviews: rating, title, text, stay dates, room type, traveler type, and country. Paste a hotel URL or a numeric hotel ID and export one JSON row per review. This is an Agoda API alternative for reputation tracking and hotel comps. Run it from Python, Node.js, cURL, or Apify MCP.
| Hotel reviews | Room rates and calendar | Vacation rental pace | OTA price board |
|---|---|---|---|
| Agoda Reviews Scraper ◄── you are here | Booking.com Occupancy Scraper | Airbnb Occupancy Scraper | Google Hotels Scraper |
VRBO calendars sit beside the Airbnb Actor: VRBO Occupancy Scraper.
When to use
- Export guest reviews for one hotel or a short list of hotel URLs and IDs
- Keep rating, stay dates, room type, traveler type, and country on the same row
- Schedule a run that saves only review IDs you have not stored yet
- Call an Agoda scraper from Python, Node.js, or an AI assistant and download JSON
When not to use
- Room rates and sold nights — use Booking.com Occupancy Scraper
- A cross-OTA price board — use Google Hotels Scraper
- Vacation-rental calendars — use Airbnb Occupancy Scraper or VRBO Occupancy Scraper
- Account, booking, or extranet data — public review pages only, no login
- A filter that keeps only one review provider — rows that appear on the hotel page are saved together
- A whole-catalog crawl — one run accepts at most 50 hotels and 1000 reviews per hotel
Key features
- Hotel page URL or numeric hotel ID
- Rating, title, text, positives, negatives, and helpful votes
- Booking.com rows that appear on the same public page, with liked and disliked text folded into
textwhen there is no single body - Check-in, check-out, length of stay, room type, and traveler type
- Reviewer display name and country when the page publishes them
- Hotel score and review count copied onto every review row
- Sort by newest, highest rating, lowest rating, or most helpful
- Optional minimum rating, cutoff date, and original language code
- Monitor mode for scheduled runs on a named Key-Value store
- HTTP fetch at 256 MB, no browser
Input
| Field | Required | Description |
|---|---|---|
hotelUrls | One of these | Hotel page URLs or numeric hotel IDs |
startUrls | One of these | The same hotel pages in the request-list editor |
maxReviewsPerHotel | No | Saved reviews per hotel. Default 20, maximum 1000 |
maxHotels | No | Hotels per run. Default 10, maximum 50 |
sort | No | recent, ratingHigh, ratingLow, or helpful |
minRating | No | Minimum score on a 10-point scale. 0 keeps every rating |
cutoffDate | No | Keep reviews on or after YYYY-MM-DD |
language | No | Original language code, such as en or ja |
monitorMode | No | Push only review IDs that are not already in the named store |
monitorStoreName | No | Named Key-Value store for scheduled runs. Default agoda-reviews-monitor |
proxyConfiguration | No | Leave off unless a run is blocked |
Input example
{"hotelUrls": ["https://www.agoda.com/marina-bay-sands/hotel/singapore-sg.html"],"maxReviewsPerHotel": 20,"sort": "recent","minRating": 8}
Output
Each dataset item is one guest review.
| Field | Description |
|---|---|
reviewId | Review id |
hotelId / hotelName | Hotel id and name |
hotelScore / hotelScoreText / hotelReviewCount | All-guest score, label, and count |
rating / ratingText | This review, on a 10-point scale |
title / text | Title and body |
positives / negatives | Split text when the page provides it |
reviewDate | Review date |
checkInDate / checkOutDate / lengthOfStay | Stay |
reviewerName / reviewerCountry / travelerType | Guest details published with the review |
roomType | Room name on the review |
provider | Source label on the page |
helpfulVotes | Helpful-vote count |
language | Original language code when present |
hotelUrl | Page used for the row |
scrapedAt | UTC time the row was built |
Output example
{"reviewId": "1169301862","hotelId": "185945","hotelName": "Marina Bay Sands","hotelUrl": "https://www.agoda.com/marina-bay-sands/hotel/singapore-sg.html","hotelScore": 8.8,"hotelScoreText": "Excellent","hotelReviewCount": 35624,"provider": "Agoda","rating": 10,"ratingText": "Exceptional","title": "The best hotel","text": "A clear stay with a city view.","positives": "Pool","negatives": null,"reviewDate": "2026-09-30","checkInDate": "2026-08-13","checkOutDate": "2026-08-16","lengthOfStay": 3,"reviewerName": "Guest","reviewerCountry": "Japan","travelerType": "Family with young children","roomType": "Premier Double","helpfulVotes": 2,"language": "ja","scrapedAt": "2026-10-06T00:00:00Z"}
Use cases
| Job | What you get |
|---|---|
| Reputation export | Newest reviews for one hotel URL, with rating and text |
| Comp set | The same cutoff date across a short list of hotel IDs |
| Scheduled watch | monitorMode on a named store so the next run keeps only new review IDs |
| Guest mix | Traveler type, room type, country, and language on each row |
| Rate context | hotelId for Booking.com Occupancy Scraper when you also need the calendar |
Integration examples
Replace APIFY_TOKEN with your Apify token. The Actor name is crawloop/agoda-reviews-scraper.
Node.js
import { ApifyClient } from "apify-client";const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor("crawloop/agoda-reviews-scraper").call({hotelUrls: ["https://www.agoda.com/marina-bay-sands/hotel/singapore-sg.html"],maxReviewsPerHotel: 20,sort: "recent",});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("crawloop/agoda-reviews-scraper").call(run_input={"hotelUrls": ["https://www.agoda.com/marina-bay-sands/hotel/singapore-sg.html"],"maxReviewsPerHotel": 20,"sort": "recent",})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
cURL
curl "https://api.apify.com/v2/acts/crawloop~agoda-reviews-scraper/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"hotelUrls":["https://www.agoda.com/marina-bay-sands/hotel/singapore-sg.html"],"maxReviewsPerHotel":20,"sort":"recent"}'
MCP and AI assistants
Use this Actor from AI tools via Apify MCP. Connect your Apify account, then call this Actor by its Store name.
Example prompts:
- "Run Agoda Reviews Scraper for Marina Bay Sands and return the newest 20 reviews as JSON"
- "Scrape Agoda hotel reviews with a minimum rating of 8 and summarize traveler type, room type, and country"
- "Chain Agoda Reviews Scraper, then Booking.com Occupancy Scraper, for the same hotel's reviews and sold nights"
Suite next step
After the review export, run Booking.com Occupancy Scraper for public room rates and the availability calendar. For a cross-OTA price board, use Google Hotels Scraper.
FAQ
Does this Agoda scraper log in?
No. It reads the public review list for a hotel URL or numeric hotel ID.
What does one dataset row mean?
One saved guest review. The hotel score is copied onto that row so you can filter without a second dataset.
Are Booking.com reviews included?
Yes, when they appear on the same public hotel page. If the body is empty, liked and disliked text is joined into text. There is no separate provider filter.
Why is a scheduled run empty?
monitorMode stores review IDs. The first run pushes the reviews it sees and stores those IDs. Later runs push a row only when the ID was not stored before. A cutoff date in the future also returns no rows.
Can I keep one language?
Set language to an original language code such as en or ja. Leave it empty to keep every language the page returns.