Rakuten Travel Purpose-Based Hotel Recommender avatar

Rakuten Travel Purpose-Based Hotel Recommender

Pricing

from $0.00005 / actor start

Go to Apify Store
Rakuten Travel Purpose-Based Hotel Recommender

Rakuten Travel Purpose-Based Hotel Recommender

Search Rakuten Travel hotels by area, budget, and purpose — get onsen, business, family, and solo-traveler picks with a score.

Pricing

from $0.00005 / actor start

Rating

0.0

(0)

Developer

coco zizi

coco zizi

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

12 hours ago

Last modified

Categories

Share

Searches hotels via the official Rakuten Travel API (楽天ウェブサービス / Rakuten Web Service) by area × budget band × purpose (onsen / business / family / solo-traveler) and returns each hotel with a transparent recommendation score — built for AI agents and travel apps to consume directly.

Features

  • Search hotels by area, budget, and travel purpose
  • Find onsen hotels via Rakuten's official filter
  • Detect business, family, and solo-traveler hotels
  • Score and rank hotels by review quality and price fit
  • Get hotel images, review data, and booking links

⚠️ Disclaimer (please read)

  • This Actor uses the official Rakuten Web Service API (commercial use allowed, free, instant application ID issuance, no review) — not scraping. You need your own applicationId and accessKey, issued together at https://webservice.rakuten.co.jp/app/create, to run it. Rakuten migrated its API infrastructure in 2026: both credentials (UUID-format applicationId, pk_-prefixed accessKey) are required — a pre-migration, applicationId-only key will not work.
  • recommendationScore and purposeTags (business/family/solo) are generated by this Actor's own logic on top of Rakuten's data. They are a convenience estimate, not an official Rakuten classification. Always verify details on the official hotel page before booking.
  • Rakuten enforces 1 request/second per applicationId; exceeding it returns HTTP 429. This Actor enforces a minimum 1100ms delay between paginated calls for safety (see "Rate limit" below).
  • Area codes: middleClassCode, smallClassCode, and detailClassCode are all required — Rakuten's own API docs suggest middleClassCode alone should be enough, but in practice the search rejects anything short of the full 4-level chain. Look codes up via Rakuten's Area Class API (GetAreaClass); well-known values like tokyo/tokyo/A (central Tokyo) work out of the box.
  • Security note: this Actor's Rakuten app has its IP allowlist set to 0.0.0.0/0 (open to any IP — needed since Apify's cloud runs from dynamic, shared outbound IPs), so applicationId/accessKey are the only access control left on that Rakuten app. Both are marked isSecret: true in the input schema and never logged or included in output.

Purpose classification: official vs. estimated

This is the core design point of this Actor's output:

PurposesourceconfidenceHow it's determined
onsen (温泉)officialalways 1.0Rakuten's own squeezeCondition=onsen filter on the Vacant Hotel Search API — the hotel is only included in the search results because Rakuten itself tagged it as an onsen property.
business (ビジネス)heuristic00.95Keyword-dictionary match (src/purposeClassifier.js) against the hotel's own hotelSpecial free-text description, name, and facility fields.
family (ファミリー)heuristic00.95Same keyword-dictionary approach, different dictionary.
solo (一人旅)heuristic00.95Same keyword-dictionary approach, plus a small contextual boost when the search itself specifies 1 adult (adultNum: 1).

Each hotel's purposeTags array can contain multiple tags at once (e.g. an onsen ryokan can also match the family dictionary). There is no official Rakuten API parameter for business/family/solo — that gap is exactly what this Actor's keyword dictionary fills (tunable in src/purposeClassifier.js, same pattern as classify.js in our PR TIMES Actor).

What does this Actor do?

  1. Calls Rakuten's Vacant Hotel Search API (VacantHotelSearch, 2017-04-26) — the only Rakuten Travel endpoint with a real price-band filter (minCharge/maxCharge) — filtered by area (middleClassCode etc.), budget band, stay dates, and occupancy. When purpose is onsen, this call also passes Rakuten's own squeezeCondition=onsen.
  2. Tags each hotel with purposeTags as described above.
  3. When purpose is business/family/solo, keeps only hotels where that tag was detected (confidence > 0).
  4. Scores every remaining hotel with recommendationScore (0–100, src/scoring.js) combining review quality, price fit within the requested budget band, and purpose-match confidence — with a scoreBreakdown so the weighting is inspectable, not a black box.
  5. Sorts by recommendationScore descending and outputs the top maxItems.

Who is this for?

Existing similar Actors (piquno/rakuten-travel-scraper, shiokoshi356/rakuten-travel-scraper) stop at dumping raw hotel list/detail data. This Actor's differentiation (same stack as our BOOTH, SUUMO, and PR TIMES Actors: JavaScript ESM, Apify SDK, Pay-per-event pricing) is structuring the result as a curated, scored recommendation instead — and clearly labeling which part of that recommendation is official Rakuten data vs. this Actor's own estimate (see "Purpose classification" above).

Input

ParameterTypeDefaultDescription
applicationIdstring (secret)Required. Your Rakuten Web Service application ID (UUID format).
accessKeystring (secret)Required. Your Rakuten Web Service access key, issued alongside applicationId.
middleClassCodestringRequired. Prefecture-level area code (e.g. "tokyo").
smallClassCodestringRequired. City/ward-level area code (e.g. "tokyo" for central Tokyo's 23 wards).
detailClassCodestringRequired. Station/neighborhood-level area code (e.g. "A").
largeClassCodestring"japan"Top-level area code. Rarely needs to change.
minCharge / maxChargeintegernoneBudget band, JPY per room per night.
checkinDate / checkoutDatestringtomorrow / day afterFormat YYYY-MM-DD.
adultNuminteger2Number of adults. Also a contextual signal for the solo tag.
purposestring"any"any / onsen (official) / business / family / solo (estimated).
maxItemsinteger20Cap on hotels output/charged (max 100).
requestDelayMsinteger1100Delay between paginated Rakuten API calls. Cannot go below 1100ms (Rakuten's 1 req/sec limit).

Look up middleClassCode/smallClassCode/detailClassCode via Rakuten's Area Class API (GetAreaClass) — see "FAQ & known limitations" for a note on making this step easier in a future version.

Output

Actual output from a real run against a live applicationId/accessKey (2026-08-06, Tokyo/Ginza area, purpose: "onsen"):

{
"hotelNo": 182801,
"hotelName": "天然温泉 七宝の湯 ドーミーインPREMIUM銀座",
"hotelKanaName": "どーみーいんぷれみあむぎんざ",
"hotelSpecial": "銀座エリア唯一の”黒湯”天然温泉・高温サウナ完備! 最上階には和風プレミアムフロアを御用意しております",
"area": {
"middleClassCode": "tokyo",
"smallClassCode": "tokyo",
"areaName": null,
"address1": "東京都",
"address2": "中央区銀座6-16-8",
"nearestStation": "東銀座",
"latitude": 35.6676788,
"longitude": 139.7657912
},
"priceBand": { "minCharge": null, "maxCharge": null },
"hotelMinCharge": 12210,
"reviewAverage": 4.62,
"reviewCount": 203,
"stayCondition": { "checkinDate": "2026-08-07", "checkoutDate": "2026-08-08", "adultNum": 2 },
"purposeTags": [
{ "type": "onsen", "label": "温泉", "source": "official", "confidence": 1, "matchedTerms": [] }
],
"recommendationScore": 86.2,
"scoreBreakdown": { "reviewScore": 46.2, "priceScore": 10, "purposeScore": 30 },
"hotelInformationUrl": "https://img.travel.rakuten.co.jp/image/tr/api/re/pvonD/?f_no=182801",
"hotelImageUrl": "https://img.travel.rakuten.co.jp/share/HOTEL/182801/182801.jpg",
"reviewUrl": "https://img.travel.rakuten.co.jp/image/tr/api/re/gJNfM/?f_hotel_no=182801",
"disclaimer": "Reference information generated from data retrieved via the official Rakuten Travel API. The onsen tag is confirmed data reflecting Rakuten's own official filter (squeezeCondition=onsen); the business/family/solo tags are estimates based on simple keyword matching against each property's own description text (see purposeTagConfidence for the confidence level) and are not guaranteed to be accurate. Always check the official listing page for the latest details before booking.",
"retrievedAt": "2026-08-06T06:28:16.361Z"
}

Note: hotelName/hotelSpecial/addresses are Rakuten's own Japanese-language data — Rakuten's API has no English fields to translate from, so only this Actor's own disclaimer text is in English (see "FAQ" below). Also note that area.areaName returns null in practice despite Rakuten's own documentation listing it as present on this endpoint — a discrepancy in Rakuten's API/docs, not a bug in this Actor.

Pricing

EventPriceTrigger
Actor Start (apify-actor-start)$0.00005Once per run (Apify's standard synthetic event)
Hotel recommended (hotel-recommended)$0.035Per hotel output, with review data and a scored recommendation
Purpose match detected (purpose-match-detected)$0.01Charged in addition to hotel-recommended when at least one purpose tag (official or estimated) matched

A tagged hotel costs $0.045 total; an untagged one costs $0.035.

How the price was set (measured on Apify, 2026-08-06)

Two production-like runs, both Tokyo/Ginza area (middleClassCode=tokyo/smallClassCode=tokyo/ detailClassCode=A), maxCharge: 30000:

RunpurposeItems outputAPI pages fetchedDurationReal infra cost (usageTotalUsd)Cost per item
1any (25 requested)2538.0s$0.0006275855$0.0000251034
2business (20 requested, only 1 hotel matched the dictionary)124.4s$0.0003041074$0.0003041074
Blended26$0.0009316928$0.0000358343

~85–95% of the cost in both runs is ACTOR_COMPUTE_UNITS; dataset/key-value-store writes are a small fixed add-on with no meaningful per-item scaling. Two things stand out:

  1. Per-item cost is dominated by fixed per-run overhead (container boot + the Rakuten API calls themselves), not by item count. Run 2 fetched 2 pages (60 candidates) but only 1 survived the business heuristic filter, so that page-fetch cost landed entirely on a single output item — $0.0003/item, ~12x worse than Run 1's $0.000025/item. A purpose-filtered run that matches few or zero hotels is the worst case for per-item cost, and a zero-match run earns no hotel-recommended revenue at all (only the flat $0.00005 apify-actor-start charge) despite making the same Rakuten API calls — a structural gap worth being aware of, though the absolute amounts are small enough (a fraction of a cent per zero-match run) that it isn't worth added pricing complexity to close.
  2. Purpose tagging itself adds no measurable infrastructure cost — official (onsen) tagging is a literal object construction and heuristic tagging is a regex scan over hotelSpecial text already fetched for the base search, with zero additional HTTP calls (same finding as the PR TIMES Actor's salesTimingSignals). purpose-match-detected's price is therefore a value-based decision, not something a cost measurement can inform — see below.

Following the same methodology as the PR TIMES Actor's README (price against the higher of the measured per-item costs, not the optimistic blended average): hotel-recommended was set at $0.035 — a placeholder $0.02 would only be 65.8x the worst-case $0.0003041/item figure (short of a 100x target), while $0.035 clears it at 115x (and ~1150x against the typical/blended figure).

Why official and estimated purpose tags are priced the same

A case could be made for pricing business/family/solo higher than onsen: they're exactly the categories Rakuten's own API can't filter by at all, so they're where this Actor's differentiation actually lives, while onsen is close to a pass-through of a filter Rakuten already provides for free. (The PR TIMES Actor prices its own analogous estimated signal, sales-timing-signal-detected, 4x higher than its base event on this logic.)

This Actor instead uses one flat purpose-match-detected price regardless of source, because purpose is the core promise of the product itself here, not a bonus layered on top of an already-complete result the way PR TIMES's signal is — a caller asking for purpose: "family" and one asking for

purpose: "onsen"
are getting the same feature answering the same question, just via a different internal mechanism they don't choose and mostly don't see. purposeTagConfidence already communicates reliability directly, rather than folding it into a price split. A confidence-tiered price schedule is a reasonable direction for a future version if usage data justifies the added billing complexity, but isn't implemented here.

Rate limit

Rakuten enforces 1 request/second per applicationId (exceeding it returns HTTP 429). This Actor:

  • Never sets requestDelayMs below 1100ms (1000ms + safety margin) between paginated calls.
  • Auto-retries once, after a 3-second wait, if a 429 is received (src/rakutenClient.js).

FAQ

How accurate are the business/family/solo purpose tags? They're keyword-dictionary estimates only (src/purposeClassifier.js), not an official Rakuten classification. Wording not covered by the dictionary won't be detected, and matches can be spurious (e.g. a hotel merely mentioning "family restaurant nearby" could false-positive on family). PURPOSE_DEFINITIONS can be tuned as real output is reviewed.

Do I need to know Rakuten's area codes myself? Yes, for now — all 4 levels (largeClassCode/middleClassCode/smallClassCode/detailClassCode) are required, so you need to look them up via Rakuten's Area Class API (GetAreaClass). A natural future addition would be accepting a free-text area name and resolving it to the full code chain automatically, or offering latitude/longitude + searchRadius as a simpler alternative input mode.

Does the recommendation score include per-aspect review ratings (cleanliness, service, etc.)? Not currently. VacantHotelSearch only returns reviewAverage/reviewCount/userReview — the per-aspect breakdown (service/location/room/equipment/bath/breakfast/dinner/cleanliness) would require an additional call to SimpleHotelSearch or HotelDetailSearch per hotelNo, which this v0.1 skips to keep the request count (and rate-limit exposure) minimal. Relatedly, hotelClassCode's exact value meanings (hotel/ryokan/pension/etc.) aren't documented by Rakuten and haven't been fully confirmed against real data yet.

Can I search for premium/luxury hotels specifically? Not as a dedicated option — HotelRanking's genre=premium is a separate, area-less ranking endpoint that isn't wired into this Actor, since the current purpose list (onsen/business/family/solo) didn't call for it.

Is the hotel description translated to English? No — hotelName/hotelSpecial/addresses etc. are Rakuten's raw Japanese text, since Rakuten's API has no English fields to fall back to. Only this Actor's own boilerplate disclaimer text is in English. Generating English summaries of the actual property descriptions would need an additional translation/LLM step on top of hotelSpecial, not implemented here.