# SUUMO Japan Rental Listings Scraper (`piquno/suumo-japan-rental-scraper`) Actor

Scrape rental listings from SUUMO, Japan's largest property portal. Rent, management fee, deposit and key money as plain yen numbers, plus layout, area, floor, building age and station walk times. One row per available room.

- **URL**: https://apify.com/piquno/suumo-japan-rental-scraper.md
- **Developed by:** [Piquno](https://apify.com/piquno) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 listings

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/platform/actors/running/actors-in-store#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

## SUUMO Japan Rental Listings Scraper

**Rental listings from [SUUMO](https://suumo.jp/), Japan's largest property portal — with every yen figure parsed into a real number.**

SUUMO writes prices the Japanese way: rent as `16.4万円`, fees as `15000円`, and an undisclosed cost as `-`. This actor returns `164000`, `15000` and `null`, so you can sort and filter without touching the data. It also adds the two numbers people actually compare on:

- **`monthlyTotalYen`** — rent plus management fee, what the tenant really pays each month
- **`rentPerSqmYen`** — yen per square metre, the honest way to compare a 1K against a 2LDK

One row per **available room**, with its building's details denormalised onto it — so a single CSV needs no joining.

HTTP-only. No browser, no login.

***

### Why it is cheap to run

SUUMO's listing pages are two-level: one card is a *building*, and inside it a table lists every available *room*. A single request in testing returned **30 buildings and 156 rooms**.

Most job and directory scrapers cost one request per row. This one costs about one request per 150 rows, so a 1,000-room extract is roughly 7 requests.

***

### What you get

| Field | What it is |
|---|---|
| `roomUrl`, `roomId` | The specific room's SUUMO page and its id |
| `buildingName`, `buildingType`, `address` | e.g. アーバネックス千代田淡路町 / 賃貸マンション / 東京都千代田区神田小川町１ |
| `rentYen`, `rentRaw` | `160000`, and the original `16万円` |
| `adminFeeYen`, `monthlyTotalYen` | Management fee, and rent + fee combined |
| `depositYen`, `gratuityYen` | Deposit (敷金) and key money (礼金) — `null` when not charged, never `0` |
| `layout`, `areaSqm`, `floor` | `1DK`, `25.13`, `4` |
| `rentPerSqmYen` | Derived — rent divided by area |
| `buildingAgeYears`, `buildingFloors` | `築5年` → `5`; 新築 (newly built) → `0` |
| `accessLine1..3`, `accessStation1..3`, `accessWalkMin1..3` | Up to three lines, split into line, station and walk minutes |
| `imageUrl`, `sourceUrl`, `scrapedAt`, `fieldsPopulated` | Provenance |

#### Measured fill rates

From a live 156-room page in Chiyoda, Tokyo. **Fee disclosure varies a lot by region** — a live Osaka run returned deposits on only 23% of rooms against Tokyo's 71%, because the two markets use 敷金 / 保証金 differently. Rent, layout, area and station walk are 100% everywhere tested:

| Field | Fill |
|---|---|
| `roomUrl`, `buildingName`, `address`, `rentYen`, `layout`, `areaSqm`, `floor` | 100% |
| `buildingAgeYears`, `accessStation1`, `accessWalkMin1` | 100% |
| `gratuityYen` | 84% |
| `adminFeeYen` | 79% |
| `depositYen` | 71% |
| `accessStation3` | 96% |

A fee the listing does not charge stays `null` rather than becoming `0` — a `0` deposit and an undisclosed deposit are very different things when you are budgeting.

***

### Input

```json
{
  "prefecture": "tokyo",
  "maxItems": 150,
  "maxRentYen": 150000,
  "maxWalkMinutes": 10
}
```

Or paste a SUUMO search URL with filters you already set on the site:

```json
{
  "startUrls": [{ "url": "https://suumo.jp/jj/chintai/ichiran/FR301FC001/?ar=030&bs=040&ta=13&sc=13101" }],
  "maxItems": 500
}
```

**Defaults:** `maxItems` is **100** — a single page that finishes in seconds. Raise it for a real extract; one ward of Tokyo alone advertises over 32,000 listings.

#### Filters

`maxRentYen`, `minAreaSqm`, `layoutContains`, `maxWalkMinutes` and `maxBuildingAgeYears` all run **before** a row is charged, so you are never billed for rows a filter excluded.

#### Monitoring

Set `incremental: true` with its own `stateKey` to emit only rooms not seen before, tagged `changeType: "new"` — a daily watch on a saved search bills for what actually appeared.

***

### Limitations — read before you buy

- **SUUMO rate-limits by IP.** It answers `503` with a short body when throttling. The actor detects that specifically, backs off and retries, and reports `throttleResponses` in the run summary. **Keep Apify Proxy enabled** — it is on by default and included on every Apify plan. A single unproxied address starts drawing 503s quickly.
- **A prefecture is not a search.** SUUMO addresses a ward by slug (`/chintai/osaka/sc_osakashikita/`), and a prefecture-wide URL returns HTTP 200, the right heading and **zero listings** — it is a search-refinement form, not results. Choosing a prefecture therefore runs its ward index and expands every ward (67 for Osaka), so a whole-prefecture run is many searches rather than one. Paste a search URL when you want exactly one area.
- **Bus routes have no station walk time.** An entry like `バス10分 停歩5分` means 10 minutes by bus then 5 on foot *from the bus stop*. Reporting that 5 as the station walk would make a far-out property look commutable, so `accessWalkMin` is `null` for bus access — and `maxWalkMinutes` therefore excludes those rooms.
- **Rentals only.** This actor covers 賃貸 (rental). Sale listings use different pages and are not included.
- **Japanese text is returned as-is.** Building names, addresses, layouts and station names come back in Japanese, because that is what the source publishes and transliterating would introduce errors.
- **Duplicate buildings.** SUUMO itself notes that the advertised total counts agency postings, and it merges listings it believes are the same property. Rows are deduplicated on room id within a run.

***

### Output

Three ready-made views on the Output tab: **Overview**, **Move-in costs** (every yen figure, for rent benchmarking) and **Stations & commute** (all three lines with walk times). A `RUN_SUMMARY` record reports rows pushed, rows billed, rows filtered out and how often SUUMO throttled.

# Actor input Schema

## `startUrls` (type: `array`):

Paste any SUUMO rental search URL, with whatever filters you already set on the site. This is the most precise way to run the actor and it overrides the prefecture below.

## `prefecture` (type: `string`):

Used when no search URL is given. SUUMO needs a city or ward to return listings, so a prefecture is expanded into its wards automatically.

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

Hard limit on rows. One request returns roughly 150 rooms across about 30 buildings, so this is cheap: 1,000 rooms is around 7 requests. The default of 100 is a single page.

## `requestDelaySecs` (type: `integer`):

SUUMO throttles hard and answers 503 when it does. The actor already backs off and retries; raise this if the run summary shows many throttle responses.

## `maxRentYen` (type: `integer`):

Keep only rooms at or below this monthly rent, e.g. 150000. Excludes the management fee — see monthlyTotalYen in the output for the all-in figure.

## `minAreaSqm` (type: `integer`):

Keep only rooms of at least this floor area, e.g. 25.

## `layoutContains` (type: `string`):

Keep only rooms whose layout contains this, e.g. "1K", "2LDK", "LDK".

## `maxWalkMinutes` (type: `integer`):

Keep only rooms within this walk of at least one of their listed stations. Bus-access entries have no station walk time and are excluded by this filter.

## `maxBuildingAgeYears` (type: `integer`):

Keep only buildings at or below this age. Newly built (新築) counts as 0.

## `incremental` (type: `boolean`):

Remember room ids between runs and emit only listings not seen before. Turns a scheduled watch into a cheap delta instead of re-billing the whole search.

## `stateKey` (type: `string`):

Namespace for incremental state. Use a different key per saved search so separate schedules do not share history.

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

Keep Apify Proxy enabled. SUUMO rate-limits by IP and starts returning 503 to a single address quickly; the datacenter pool is included on every Apify plan and spreads the load.

## Actor input object example

```json
{
  "prefecture": "tokyo",
  "maxItems": 100,
  "requestDelaySecs": 2,
  "incremental": false,
  "stateKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `rooms` (type: `string`):

One row per available room: rent, fees, layout, area, floor, building age and station walk times.

## `costs` (type: `string`):

Rent, management fee, deposit, key money and yen per square metre.

## `runSummary` (type: `string`):

Rows pushed, rows billed, rows filtered out, listings skipped as already seen, and how often SUUMO throttled.

# 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 = {
    "prefecture": "tokyo",
    "maxItems": 100,
    "requestDelaySecs": 2,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("piquno/suumo-japan-rental-scraper").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 = {
    "prefecture": "tokyo",
    "maxItems": 100,
    "requestDelaySecs": 2,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("piquno/suumo-japan-rental-scraper").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 '{
  "prefecture": "tokyo",
  "maxItems": 100,
  "requestDelaySecs": 2,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call piquno/suumo-japan-rental-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,piquno/suumo-japan-rental-scraper"
        }
    }
}

```

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/LR461ysF6mTsIsdAW/builds/sJ8E9QnBxF8odj2VL/openapi.json
