Traveloka Hotel Scraper at a glance
Traveloka Hotel Scraper is a ready-to-run Apify actor from abotapi for collecting web data. Its documented output includes hotelid, name, url, locationname and area, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.80 per 1,000 results on the Apify Free plan and from $1.80 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Web data
- Pricing
- $2.80 per 1,000 results (Free plan), from $1.80 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 28 options
Scrape Traveloka hotels across Singapore, Malaysia, Indonesia, Thailand, Vietnam and the Philippines: nightly prices, star ratings, guest scores, coordinates and photos by city. Paste search or hotel links, and monitor price changes with recurring updates.
What Traveloka Hotel Scraper can do
- 30+ fields per hotel: nightly price, star rating, guest score out of 10, review count, region, coordinates, photos and facilities.
- Seven storefronts (Singapore, Malaysia, Indonesia, Thailand, Vietnam, Philippines, Australia) with per-market currency handling.
- Two ways to find hotels: keyword search by city or area, or paste Traveloka search links (with spec=) and hotel detail links.
- Optional enrichment, priced per hotel: facility codes and labels, feature highlights, extra photos and a backfilled guest rating merged straight from the site's own data feed, no extra page loads for search results. A separate guest-review pull is also available.
- Recurring updates: incremental mode classifies every hotel NEW, UPDATED, UNCHANGED or EXPIRED between scheduled runs, so you only pay for what changed.
- Client-side filters and sorting: price range, minimum star rating and minimum guest score, plus popularity or price-based sort order.
Choose what to collect
These inputs let you configure Traveloka Hotel Scraper - SEA Hotel Prices & Ratings. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | Search walks hotel results for the locations below. URL mode pastes Traveloka hotel-search links (with spec=) or hotel detail links; search filters are ignored in URL mode. |
marketstring | Which Traveloka storefront to read. Sets the language and the currency prices are returned in. |
locationsarray | City or area names as you would type them into Traveloka's hotel search box (e.g. Singapore, Bangkok, Kuta). Each location is resolved to Traveloka's internal region id, then its results are walked. Multiple locations are split evenly across your result budget. |
checkInDatestring | Check-in date (YYYY-MM-DD). Leave empty to default to tomorrow (site time). |
checkOutDatestring | Check-out date (YYYY-MM-DD). Leave empty to default to the day after check-in. |
adultsinteger | Number of adult guests per search. |
roomsinteger | Number of rooms per search. |
Show 21 more inputs
| Input | What it controls |
|---|---|
sortBystring | Search-mode sort order requested from the site. Popularity is Traveloka's own default order. |
minPriceinteger | Drop hotels whose nightly price is below this. Applied to returned results (client side), in the market's currency. |
maxPriceinteger | Drop hotels whose nightly price is above this. Applied to returned results (client side), in the market's currency. |
minStarRatinginteger | Drop hotels below this star rating (0 = keep all). Applied to returned results (client side). |
minGuestRatingnumber | Drop hotels whose guest review score is below this (Traveloka scores out of 10). Applied to returned results (client side); hotels without a score are kept. |
urlsarray | Multi-URL supported. Paste hotel-search links that contain spec= (from a browser search) and/or hotel detail links. Filter-mode fields are ignored; a search link walks forward from its own dates and occupancy. |
fetchDetailsboolean | Merges the static-content feed into each row: facility codes + labels, feature highlights, extra images and UGC ratings. Each enriched row bills the detail-enrichment surcharge event once; unenriched rows push the base listing and bill nothing extra. A pasted hotel detail link is read as a page only when this is on; a link whose page cannot be read is skipped and not billed. With only Read guest reviews on, a link whose reviews cannot be read is skipped and not billed too. |
fetchReviewsboolean | Adds a reviews array (author, rating, date, text) from the review JSON lane, up to maxReviews per hotel. Rows with fetched reviews bill the detail-enrichment surcharge like other enrichment (search results: started blocks of 10 reviews, minimum 1; hotel detail links: 1 unit per row). Works with fetchDetails on or off. |
reviewSortBystring | Order of the reviews array when fetchReviews is on. The order is applied to the reviews read for each hotel (up to maxReviews); it does not search the site's whole review list for the best or newest ones. |
reviewCutoffDatestring | When fetchReviews is on, keep only reviews dated after this day (YYYY-MM-DD). Leave empty for no date filter. |
aggregateRatingsboolean | When fetchReviews is on, adds an aggregatedReview object (count, overallRating) to each hotel row. The data this actor reads carries no per-score breakdown. |
maxItemsinteger | The one real cap: maximum hotel records to return per run, across all locations. 0 means unlimited. |
maxPagesinteger | Safety cap on result pages walked per location. 0 (default) means no page cap: the walk follows Max results and the site's own result count. |
resumeFromRunIdstring | ID of an interrupted run of this Actor to continue, skipping hotels already saved by that run. Leave empty for a fresh run. Conflicts with Incremental mode (pick one). |
incrementalModeboolean | Recurring monitoring: the Actor remembers hotels it saw on the previous run of the same scope and only emits new or changed ones. Rows carry changeType/changedFields. Unchanged rows are suppressed (set emitUnchanged to also emit and bill them). Conflicts with Resume from run ID. |
stateKeystring | Name for the storage the incremental baseline is kept under. Leave empty to derive it from your scope (mode, market, locations, dates, occupancy and filters), so different setups never share a baseline. |
emitExpiredboolean | With Incremental mode: also emit (and bill) rows that were tracked before but no longer appeared in a complete walk, marked changeType EXPIRED. Never fires when the walk was capped, truncated or refused part-way. |
ignoreFieldsForChangesarray | Incremental mode only: field names that never make a hotel count as updated, for example price or guestRating. Use dots for nested fields. The fields are still kept in the output. The cover image link is always ignored because its address rotates between runs; hotel facilities are compared regardless of list order. Changing this list never re-bills the saved baseline. |
mcpConnectorsarray | Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify → Settings → API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write/digest. Leave empty to skip (never changes the dataset output). Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
notionParentPageUrlstring | URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on items written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
hotelIdhotelIdnameName (text)urlurllocationNamelocationNameregionArea (text)priceNightly price (number)currencyCurrency (text)starRatingStars (number)guestRatingGuest score (number)guestRatingLabelguestRatingLabelnumReviewsnumReviewslatitudelatitudeShow 33 more fields
longitudelongitudeimageUrlimageUrlmarketmarketcheckInDatecheckInDatecheckOutDatecheckOutDatechangeTypechangeTypechangedFieldschangedFieldsfirstSeenAtfirstSeenAtlastSeenAtlastSeenAtreviews.productTypereviews.productTypereviews.reviewerNameReviewerreviews.reviewTimestampTimestampreviews.reviewScoreScorereviews.reviewMaxScorereviews.reviewMaxScorereviews.reviewContentTextReviewreviews.reviewOriginalTextreviews.reviewOriginalTextreviews.reviewAdditionalInformationreviews.reviewAdditionalInformationreviews.reactionCountreviews.reactionCountreviews.hasReactedreviews.hasReactedreviews.reviewProviderreviews.reviewProviderreviews.replierNamereviews.replierNamereviews.reviewReplyTextreviews.reviewReplyTextreviews.reviewReplyOriginalTextreviews.reviewReplyOriginalTextreviews.reviewReplySubmissionTimereviews.reviewReplySubmissionTimereviews.reviewReplyTranslationStatusreviews.reviewReplyTranslationStatusreviews.reviewIdreviews.reviewIdaddressAddress (text)descriptionDescription (text)amenitiesAmenities (array)featuresFeatures (array)facilitiesfacilitiesimageUrlsimageUrlsdetailFetchedDetails fetched (boolean)Example output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"hotelId": "9034521",
"name": "Sample City Hotel",
"url": "https://www.traveloka.com/en-sg/hotel/singapore/sample-city-hotel-9034521?checkIn=2026-11-01&checkOut=2026-11-02",
"locationName": "Singapore",
"region": "Sample District, Singapore",
"address": null,
"price": 185,
"priceMinor": 18500,
"currency": "SGD",
"starRating": 4,
"guestRating": 8.2,
"guestRatingMax": 10,
"guestRatingLabel": "Very Good",
"numReviews": 1240,
"latitude": 1.301,
"longitude": 103.855,
"facilities": [
"Wi-Fi in public areas"
],
"facilityCodes": [
"WIFI_PUBLIC_AREA"
],
"imageUrl": "https://ik.imagekit.io/tvlk/sample/asset/sample-hotel-0000000.jpeg",
"imageUrls": [
"https://ik.imagekit.io/tvlk/sample/asset/sample-hotel-0000000.jpeg"
],
"market": "en-sg",
"checkInDate": "2026-11-01",
"checkOutDate": "2026-11-02",
"changeType": "NEW",
"changedFields": [],
"firstSeenAt": "2026-11-01T00:00:00Z",
"lastSeenAt": "2026-11-01T00:00:00Z"
}Ways to use this data
- Travel meta-search and price-comparison sites: pull nightly Traveloka rates across cities to power search widgets or price-alert tools.
- Hotel revenue teams and market researchers: track competitor pricing, star ratings and guest scores across Traveloka's storefronts.
- OTA and travel-tech platforms: feed structured hotel inventory (facilities, photos, coordinates) into an internal booking or aggregation product.
- Travel content and city-guide sites: build listing pages from ratings, facilities and photos without manual data entry.
- Recurring rate monitoring: schedule the actor against a fixed set of cities or hotels to catch price and rating changes over time.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Traveloka Hotel Scraper return?
The documented output for Traveloka Hotel Scraper includes hotelid, name, url, locationname, area, nightly price, currency and stars. Availability of each field depends on the source page and the selected mode.
How much does Traveloka Hotel Scraper cost?
It costs $2.80 per 1,000 results on the Apify Free plan and from $1.80 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new or changed hotels on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated records, and unchanged ones are not billed unless you turn on Emit unchanged rows. Use fixed check-in and check-out dates (or a State key) for the scope you are watching: with empty dates the scope changes every day and every hotel comes back as new.
Does Resume from run ID actually skip hotels from the earlier run?
Yes. Pass the interrupted run's ID in resumeFromRunId and hotels that run already saved are skipped, so they are not fetched or billed again. It cannot be combined with Incremental mode.
Can I use it with AI agents or MCP?
Yes. Any MCP client or AI agent that can call Apify actors can run it and read the dataset. The built-in connector field (mcpConnectors) is meant to push results into Notion, Linear or Airtable, but in the current build that export sends nothing (see the MCP connectors section), so read the dataset directly for now.
