# Japan Hotel Rates and Date Watchlist (`jpmarketdata/japan-hotel-refundable-total-comparison`) Actor

Monitor dated room-and-plan stay prices for Japan hotels on Jalan and Rakuten across multiple properties and dates. Preserve exact source IDs and unknown fees; optionally compare verified Haneda same-room totals.

- **URL**: https://apify.com/jpmarketdata/japan-hotel-refundable-total-comparison.md
- **Developed by:** [h ichi](https://apify.com/jpmarketdata) (community)
- **Categories:** Travel, Automation, Developer tools
- **Stats:** 1 total users, 1 monthly users, 90.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$20.00 / 1,000 hotel rate screen delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Japan Hotel Rates and Date Watchlist

Collect dated **room and plan stay prices from Jalan and Rakuten** for a hotel watchlist. Compare properties and dates, inspect cheaper room categories, and repeat the same input to track rate changes. Refund deadlines and payment preferences are optional conditions in the separate verified same-room comparison.

### Main use: property and date rate shopping

Supply `targets` containing 1–10 `{provider, hotelId}` objects and `stays` containing 1–7 `{checkIn, checkOut}` pairs. A run accepts at most 20 target/stay combinations. Each provider/property/stay produces one dataset row with exact source room/plan IDs, original room labels, advertised stay amounts, meal facts when disclosed, source-order positions, a dated source link, occupancy, acquisition time, and a stable `observationKey`.

```json
{
  "targets": [
    {"provider": "jalan", "hotelId": "344614"},
    {"provider": "rakuten", "hotelId": "147116"},
    {"provider": "jalan", "hotelId": "372448"},
    {"provider": "rakuten", "hotelId": "388"}
  ],
  "stays": [
    {"checkIn": "2026-11-10", "checkOut": "2026-11-11"},
    {"checkIn": "2026-11-17", "checkOut": "2026-11-18"}
  ],
  "adults": 2,
  "maxOffersPerProvider": 50
}
```

Find Jalan's six-digit property ID in its `/yadNNNNNN/` URL and Rakuten's numeric ID in `/hotelinfo/plan/ID`. IDs are provider-specific; the Actor never converts them or assumes two supplied IDs describe the same property. The dated source must echo the exact hotel ID, stay dates, adults, one room and no children. Live examples verified on 2026-10-03 include Royal Park Tokyo Haneda (Jalan 344614 / Rakuten 147116), Ryokan Nakanaka (Jalan 372448), and Hotel Metropolitan Tokyo (Rakuten 388), each with 1, 2 and 4 adults. Other valid property IDs use the same guarded listing contract and may fail explicitly if their source layout is unsupported, unavailable or exceeds the response bound.

`adults` accepts 1–4, default 2; one room and no children. Each stay is 1–7 nights; check-in is a future date within 365 days in Asia/Tokyo. `maxOffersPerProvider` is 1–50, default 50. Return entries in original source order. `loadedOfferCount` describes the inspected page before the output bound; `scopeTruncated` identifies further pages or omitted room/plan entries. No pagination or detail request is needed for ordinary price observations.

`cheapestObservedAdvertisedStayJpy` is the minimum among **returned advertised room/plan stay amounts**. Different room categories and meal packages remain separate observations. It is not a same-room provider comparison, a whole-hotel/global minimum, or a total including undisclosed mandatory fees. `consumptionTaxIncluded` is affirmative only when disclosed for the joined price. Service inclusion, extra required fees, final payable total, cancellation deadline and payment options remain null when this listing does not establish them. An unavailable Rakuten room must have zero source amounts and matching explicit no-vacancy evidence; zero is never a free rate. Missing structures or prices cannot establish a negative. No whole-hotel sold-out claim is inferred.

Repeat a watchlist on an Apify schedule and compare `observationKey`, room/plan IDs and `observedAt` between datasets to monitor changes. The Actor produces current snapshots; it does not persist a price history or send notifications itself.

### Optional verified same-room total comparison

Legacy input remains available as a separate mode: supply `hotel`, `checkIn`, and `checkOut`, without `targets`/`stays`. Only the corroborated Royal Park Tokyo Haneda standard-floor Superior Twin, one room/two adults/room only, is supported for strict cross-provider matching. No fuzzy room matching is used.

```json
{"hotel":"royal-park-tokyo-haneda","checkIn":"2026-11-10","checkOut":"2026-11-11"}
```

`freeCancellationBy` optionally requires both compared offers to advertise free cancellation through that date. `requireLocalPayment` optionally requires an affirmative pay-at-hotel option; default false. Ordinary supported-room totals are not withheld solely because pay-at-hotel is unavailable or unknown. When that filter is true, denials, unknowns, conditional statements and contradictions suppress ranking while retaining all payment evidence. The cancellation cutoff is today or later and no later than check-in.

Strict mode retains original room/area/bed evidence, meal fields, stay windows, cancellation tiers, payment facts, consumption-tax/service inclusion, local-tax evidence and missing reasons. Rank only supported 15:00–11:00 room-only offers with complete mandatory-fee evidence and any requested optional conditions. Preserve Jalan 25 m² / Rakuten 24.5 m² / official 24.8 m² evidence. Unknown fees or missing nightly lodging bases prevent all-in ranking. Exclude other rooms/floors, meals, day use, transit rooms, children/extra beds and reduced stay windows. Stays are 1–7 nights with checkout no later than 2027-04-01; longer-date watchlist observations do not use this older Tokyo tax rule. Strict detail limit is 1–8 per provider, default 8. Divergent unkeyed Rakuten cancellation policies fail strict acquisition; ordinary watchlist prices never join those arrays.

### Charging and limits

The `hotel-compared` event is **$0.02 per delivered screen**. In watchlist mode, one screen means one provider/property/stay, up to 20 events/run ($0.40). In curated comparison mode, one screen contains both completed provider acquisitions and uses one event. No per-offer event or double manual charge. Event budget must cover every requested screen before network work. All requested acquisitions and validation complete before any delivery; an upstream failure produces no rows or events. An explicitly evidenced no-price screen can be useful negative information within its stated source scope.

HTTP only, 256 MB, no proxy, browser or paid API. Maximum 22 GETs including robots, 20 seconds/request and 120 seconds overall; no retries. Watchlist listings are limited to 4 MiB decoded response bytes and 500 source room/plan entries per page. Curated comparison keeps the 2,000,000-byte response cap. Robots policies, crawl delays and request rates are respected before each host/redirect; same-host starts are spaced at least 0.2 seconds or the larger robots interval. Redirects remain on the fixed allowed source routes. Date/occupancy/property echoes, plan/room membership and DOM/numeric amount joins are mandatory. Challenges, access failures, rate limits, timeouts, malformed data and changed structures fail explicitly.

Prices and policies can change before reservation; no booking is performed.

### Privacy and source terms

Output public property/room/date/price facts and short policy evidence only. No reviews, images, contacts, guests, personal booking data, cookies, tokens or raw HTML. Use generated dated listing URLs, excluding tracking or reservation endpoints. Provider terms and exact source excerpts are recorded in the dated scouts under DR-0007; robots/access/PII guards remain mandatory.

# Actor input Schema

## `hotel` (type: `string`):

Optional legacy comparison mode only. Supply hotel,checkIn,checkOut; do not combine with targets/stays. Exact same-room all-in comparison is verified for Royal Park Haneda Superior Twin only.

## `checkIn` (type: `string`):

Explicit future YYYY-MM-DD in Asia/Tokyo. No date default. Stay is 1–7 nights and must finish before the tax amendment affects any charged night.

## `checkOut` (type: `string`):

Explicit YYYY-MM-DD, 1–7 nights after check-in and no later than 2027-04-01. Missing nightly lodging bases prevent multi-night all-in ranking; stay averages cannot determine nightly tax brackets.

## `freeCancellationBy` (type: `string`):

Optional YYYY-MM-DD cutoff for the curated comparison. Omit to compare ordinary supported-room rates without a required refund deadline. Refund facts still remain visible.

## `maxOffersPerProvider` (type: `integer`):

Rate watchlist: default 50,range1–50 room/plan entries per provider/property/stay. Curated comparison: default 8,maximum8 detail requests. Source order is preserved; truncation cannot establish a global minimum.

## `requireLocalPayment` (type: `boolean`):

Optional curated-comparison filter, default false. Local payment uncertainty or denial prevents ranking only when this is true; ordinary rate observations retain payment facts without this gate.

## `targets` (type: `array`):

Main rate-shopping mode:1–10 provider/property-ID objects. Jalan IDs are six digits from /yadNNNNNN/ URLs; Rakuten IDs are numeric from /hotelinfo/plan/ID. IDs are independent and never converted or assumed equivalent. Live source identity is checked. Do not supply legacy hotel/checkIn/checkOut fields.

## `stays` (type: `array`):

1–7 unique checkIn/checkOut pairs,1–7 nights each; future check-in within365 days in Asia/Tokyo. At most20 target/stay combinations in one run. The provider echoes exact dates and occupancy.

## `adults` (type: `integer`):

Rate watchlist only: 1–4 adults,default 2,one room and no children. Curated comparison remains exactlytwo adults.

## Actor input object example

```json
{
  "targets": [
    {
      "provider": "jalan",
      "hotelId": "344614"
    },
    {
      "provider": "rakuten",
      "hotelId": "147116"
    }
  ],
  "stays": [
    {
      "checkIn": "2026-11-10",
      "checkOut": "2026-11-11"
    }
  ]
}
```

# Actor output Schema

## `results` (type: `string`):

Dated advertised stay prices and source room/plan identifiers; required extras and cross-provider room equivalence remain qualified.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "targets": [
        {
            "provider": "jalan",
            "hotelId": "344614"
        },
        {
            "provider": "rakuten",
            "hotelId": "147116"
        }
    ],
    "stays": [
        {
            "checkIn": "2026-11-10",
            "checkOut": "2026-11-11"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpmarketdata/japan-hotel-refundable-total-comparison").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "targets": [
        {
            "provider": "jalan",
            "hotelId": "344614",
        },
        {
            "provider": "rakuten",
            "hotelId": "147116",
        },
    ],
    "stays": [{
            "checkIn": "2026-11-10",
            "checkOut": "2026-11-11",
        }],
}

# Run the Actor and wait for it to finish
run = client.actor("jpmarketdata/japan-hotel-refundable-total-comparison").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "targets": [
    {
      "provider": "jalan",
      "hotelId": "344614"
    },
    {
      "provider": "rakuten",
      "hotelId": "147116"
    }
  ],
  "stays": [
    {
      "checkIn": "2026-11-10",
      "checkOut": "2026-11-11"
    }
  ]
}' |
apify call jpmarketdata/japan-hotel-refundable-total-comparison --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jpmarketdata/japan-hotel-refundable-total-comparison"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/PPnulT4wu7MEcGgvt/builds/8VBBzGOvrsfjn4y7y/openapi.json
