# Jalan Japanese Hotel & Ryokan Availability (`superslowsloth/jalan-hotels`) Actor

Live prices and availability from Jalan (jalan.net), Japan largest domestic accommodation site.

- **URL**: https://apify.com/superslowsloth/jalan-hotels.md
- **Developed by:** [Superslow Sloth](https://apify.com/superslowsloth) (community)
- **Categories:** Travel, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.14 / 1,000 hotel scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Jalan Japanese Hotel & Ryokan Availability

Live prices from [Jalan](https://www.jalan.net), Recruit's domestic
accommodation site and the largest hotel and ryokan inventory in Japan. Ask one
question - where, which night, how many people - and get back a small flat list
of facilities with the cheapest bookable price for that stay, the plan behind
it, the guest rating and the review count.

Built to be an agent's tool rather than a crawler: two requests for a typical
run, a flat JSON record per hotel, and a default budget of twenty rows.

### Prices are real quotes for the dates you asked for

This is the part worth reading before you compare this actor with another one.

Jalan has an obvious keyword search that returns thirty hotels with prices on
them. **Its prices do not change with the date.** Measured on 2026-08-24, the
same Shinjuku query for 15 September, 19 September and 31 December returned
byte-identical prices for all thirty facilities - New Year's Eve at the same
rate as a Tuesday. Jalan labels that column 目安, "a guide", and means it.

This actor does not use that endpoint. It resolves your destination through
Jalan's own suggest service and then reads the **area availability listing**,
which reprices properly: the same Hakone ryokan quoted ¥26,400 for a September
midweek and ¥41,800 for New Year's Eve. A live test in the repo fails the build
if that ever stops being true, because a stale price is worse than no price.

### Input

| Field | Notes |
|---|---|
| `destination` | Free text. Japanese works best - `箱根`, `新宿駅`, `沖縄`, or a facility name. Romaji such as `hakone` resolves to the same region. |
| `checkIn` | `YYYY-MM-DD`. Must be today or later and within a year. Only ISO is accepted, deliberately: an ambiguous date would be searched as the wrong night without telling you. |
| `nights` | Default 1, up to 30. |
| `adults` | Default 2. Changes the quoted prices, so it is not cosmetic. |
| `rooms` | Default 1. |
| `maxItems` | Default 20. Also the cap on how many `hotel-scraped` events you can be charged. |
| `includeUnpriced` | Default off - see below. |

`destination` is resolved to the **tightest bookable area** that matches, so
`箱根` searches Hakone rather than the whole of Kanagawa. Where it landed is
reported on every row (`resolved_area`) and in the run log, so a surprising
result set is always explainable.

Children are not supported. Jalan prices them by age band, and picking a band
for you would invent a price.

### Output

One flat record per hotel.

| Field | Notes |
|---|---|
| `hotel_id` | Jalan's facility number, the `NNNNNN` in `/yadNNNNNN/`. |
| `url`, `plan_url` | The facility page and its plan list. |
| `name` | As Jalan prints it, e.g. `箱根湯本温泉　ホテル南風荘`. |
| `area`, `prefecture` | Jalan's own breadcrumb, e.g. `神奈川県 > 箱根`. |
| `rating` | Guest review average out of 5. `null` when the facility has no reviews. |
| `review_count` | Reviews behind that average. `null`, never `0`, when there are none. |
| `lowest_total_price_jpy` | Cheapest bookable total for **the whole party and the whole stay**, tax included. |
| `lowest_price_per_person_jpy` | The same quote per person, as Jalan prints it. |
| `price_basis` | Jalan's own words for what the two figures assume, e.g. `1泊 大人2名 合計(税込)`. Read this before comparing rows. |
| `plan_name` | The cheapest plan listed under the facility. |
| `plan_per_person_jpy`, `plan_total_jpy` | That plan's prices. Not always equal to `lowest_total_price_jpy`, which is the facility-wide minimum. |
| `plan_labels` | Room type and meal plan as printed, e.g. `["和洋室", "朝・夕"]`. |
| `plan_rooms_left` | Rooms Jalan says remain on that plan. `null` when it does not say. |
| `description`, `catch_phrase` | The facility's paragraph and its promotional line. |
| `access` | Directions as printed. |
| `thumbnail_url` | First listing photo. |
| `query`, `resolved_area`, `area_url` | What you asked for, where it resolved, and the exact page the row came from. |
| `check_in`, `check_out`, `nights`, `adults`, `rooms` | Echo of the stay, so a dataset merged across several runs stays readable. |

#### Japanese is returned exactly as Jalan prints it

Nothing is translated, transliterated or romanised. `箱根湯本温泉　ホテル南風荘`
comes back as `箱根湯本温泉　ホテル南風荘`. The romanisation would be ours, not
Jalan's, and it would be wrong often enough to matter.

#### Fields Jalan does not give, and are therefore not here

- **No street address.** The availability listing prints directions (`access`)
  but not a postal address. It is not nulled into every row; it simply is not a
  field. The facility page has one, and fetching one extra page per hotel would
  multiply the cost of every run.
- **No room-level inventory, no cancellation policy, no photos beyond the first.**
- **No English name.** Jalan does not publish one for most facilities.
- Anything Jalan omits for a particular hotel is `null`, never `0` or `""`. A
  zero rating would read as a measured score of zero, which is a different claim
  from "not rated yet".

#### Sold-out facilities

Off by default. A facility Jalan lists with no price has nothing bookable on
your dates, so it is dropped rather than delivered with a null price - you are
not charged for a row whose answer is empty. Set `includeUnpriced` to `true` to
get the full listing; those rows are then charged like any other.

### Paid placements are excluded

Jalan puts sponsored `[PR]` cassettes above its organic results. They are never
emitted and never charged for. You get the ranking Jalan's own sort produced.

### Limits worth knowing

- **30 facilities per page.** Asking for more than 30 fetches more pages, which
  is slower and costs more. Past the end of an area Jalan re-serves the last
  page rather than returning nothing, so the actor de-duplicates by facility id
  and stops - you are never charged twice for the same hotel.
- **A year ahead at most.** Past Jalan's booking window the listing degrades to
  undated guide prices, so the actor refuses the date instead of quoting one.
- **Japan only.** Jalan is domestic inventory.

### Pricing

Pay per event: a small charge to start the run, then one `hotel-scraped` event
per hotel actually delivered. A run that finds nothing bookable costs only the
start fee.

# Actor input Schema

## `destination` (type: `string`):

Where to search, as free text. Japanese works best - an area ("箱根"), a station ("新宿駅"), a prefecture ("沖縄") or a facility name - and romaji ("hakone") resolves to the same region. The term is resolved through Jalan's own suggest service and the search runs over the tightest bookable area it matches, so the run report tells you exactly where it landed.

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

Check-in date as YYYY-MM-DD. Must be today or later and within a year, because Jalan stops quoting real availability past its booking window. Only ISO format is accepted: an ambiguous date would be silently searched as the wrong night.

## `nights` (type: `integer`):

How many nights to stay. Prices are quoted for the whole stay, not per night.

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

Adults in the party. This changes the prices Jalan quotes, so it is not cosmetic. Children are not supported: Jalan prices them by age band and guessing a band would invent a price.

## `rooms` (type: `integer`):

Rooms to spread the party across.

## `maxItems` (type: `integer`):

Budget for the run, and the number of hotel-scraped events you can be charged for. Jalan lists 30 facilities per page; asking for more pages more deeply and costs more, so keep this at what you will actually read.

## `includeUnpriced` (type: `boolean`):

Off by default. A facility Jalan lists without a price has nothing bookable on these dates, so it is dropped rather than delivered with a null price. Turn this on if you want the full listing including sold-out facilities - they are charged for like any other row.

## `proxyConfiguration` (type: `object`):

Optional. Jalan answered every request from Apify's own addresses when this actor was built - no bot check, no rate limit - so datacenter proxy is enough. A proxy still gives the scraper a fresh exit address to retry on if that changes.

## Actor input object example

```json
{
  "destination": "箱根",
  "checkIn": "2026-09-15",
  "nights": 1,
  "adults": 2,
  "rooms": 1,
  "maxItems": 20,
  "includeUnpriced": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `hotels` (type: `string`):

No description

# 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 = {
    "destination": "箱根",
    "checkIn": "2026-09-15",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("superslowsloth/jalan-hotels").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 = {
    "destination": "箱根",
    "checkIn": "2026-09-15",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("superslowsloth/jalan-hotels").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 '{
  "destination": "箱根",
  "checkIn": "2026-09-15",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call superslowsloth/jalan-hotels --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,superslowsloth/jalan-hotels"
        }
    }
}

```

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/RGpkPotv7YFHNjNTB/builds/T5NzpHxLBdlygG5Jj/openapi.json
