# Rakuten Ichiba Scraper - Products, Prices, Points & Reviews (`abotapi/rakuten-ichiba-scraper`) Actor

Scrape Rakuten Ichiba (rakuten.co.jp) by keyword or URL. Extract JPY prices, discounts, Rakuten points, shipping, stock, shops, categories, images, size/colour variants, specifications and customer reviews with star breakdowns and shop replies. Supports incremental tracking.

- **URL**: https://apify.com/abotapi/rakuten-ichiba-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Features:** Limited permissions
- **Stats:** 13 total users, 4 monthly users, 92.6% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 product results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Rakuten Japan Scraper: Products, Variants & Reviews

Rakuten Japan Scraper turns Rakuten Ichiba (楽天市場, rakuten.co.jp), Japan's largest online marketplace of independent shops, into clean structured rows. Search by keyword (optionally narrowed with a tag), genre or shop code the same way Rakuten's own filters do, or paste any product, review, category, shop or search link you already have. Every product comes back with price, the reference ("was") price and discount, Rakuten points, shipping and delivery, stock, the selling shop's own details, category, tags, images, size and colour variants, full specifications and, on request, individual customer reviews with the star breakdown and shop replies. Export to JSON, CSV or Excel, or pull results straight into your app through the API.

### Why This Scraper?

- **Three ways to find products, plus a keyword refinement.** Keyword (optionally narrowed further with a tag), genre or shop code searches built with Rakuten's own filters, or paste any Rakuten Ichiba link you already have: search, category, shop, product or review.
- **One flat record per product, about 95 named fields.** Price, points, shipping, stock, shop, taxonomy, media, specs and reviews all in a single row, plus the pieces that only exist per size/colour variant.
- **Marketplace aware.** Every product carries the id, name, rating and review count of the independent shop that actually sells it, not just Rakuten's own catalogue metadata.
- **The reference ("was") price and discount, where Rakuten actually publishes them.** Only the product page carries the strike-through price, never invented from a search result card.
- **Rakuten's own signals carried through untouched.** Point multipliers, the Super DEAL flag and the 39-shop free-shipping marker travel with the price, not just a generic "on sale" flag.
- **Reviews on demand.** The star histogram, individual review text, shop replies and Rakuten's own AI review summary, only fetched (and charged) when you turn them on.
- **Built for monitoring.** Incremental mode returns only new and changed products on a recurring run, and a refused run fails loudly instead of quietly returning an empty dataset.

### Use Cases

- **Price and stock monitoring:** track a keyword search, or a keyword search restricted to one shop ID, daily and get only the products that actually changed.
- **Assortment and catalogue research:** map genres, tags and per-shop search results with price tiers, size and colour variants.
- **Review mining:** collect ratings, review text and shop replies to analyse customer sentiment per product or per shop.
- **Marketplace and competitor tracking:** compare price, points and shipping terms across different shops selling similar products.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live record.

| Field | Example |
| --- | --- |
| `id` | `"412233_10000482"` |
| `itemCode` | `"10000482"` |
| `url` | `"https://item.rakuten.co.jp/paletuft-zakka/mug-classic-01/"` |
| `name` | `"パレタフト ハンドメイド陶器マグカップ 300ml 北欧デザイン"` |
| `brand` | `"PALETUFT"` |
| `shopId` | `"412233"` |
| `shopName` | `"パレタフト雑貨店"` |
| `shopUrlCode` | `"paletuft-zakka"` |
| `price` | `2160` |
| `currency` | `"JPY"` |
| `originalPrice` | `2880` |
| `discountPercent` | `25.0` |
| `pointCount` | `21` |
| `shippingFee` | `0` |
| `isFreeShipping` | `true` |
| `availability` | `"InStock"` |
| `genrePath` | `["生活雑貨・キッチン用品", "食器", "マグカップ"]` |
| `tags` | `[{"id": "9001234", "name": "北欧雑貨", "groupName": "スタイル"}]` |
| `variants` | `[{"variantId": "77021", "options": ["ネイビー"], "price": 2160, "originalPrice": 2880}]` |
| `rating` | `4.39` |
| `reviewCount` | `96` |
| `isSponsored` | `false` |
| `sourceUrl` | `"https://search.rakuten.co.jp/search/mall/mug/?s=2"` |

Turning on **Fetch product details** adds `description`, `salesDescription`, `catchCopy`, the full `attributes` specification table, `shippingCarriers`, `customizationOptions`, shop `breadcrumbs` and the shipping fee for your chosen prefecture (`shippingFee`, `shippingFeeCurrency`, `shippingIncluded`, `shippingPrefecture`, `freeShippingThreshold`, `shippingFeeStatus`). A pasted product link returns the same shipping fields without Fetch product details. `shippingFee` is the amount in yen, and `0` when shipping is included in the price or the shop ships free. For a destination the shop cannot price (some remote areas, `shippingFeeStatus` is `REMOTE_AREA`) it is empty. If Rakuten's calculator could not be reached (`UNAVAILABLE`) the shipping fields are empty and any fee already read from the search result is left as it was. `freeShippingThreshold` is the order total at which Rakuten's calculator returns no fee; a product page may round the same figure up by one yen. The shipping fields are not compared in incremental mode, so a fee change alone does not mark a product UPDATED. Turning on **Fetch reviews** adds the individual `reviews[]` array (each row carrying `reviewId`, `rating`, `title`, `body`, a public display `author` nickname, `postedAt`, `verifiedPurchase`, `helpfulCount`, the `variantInfo` purchased and the shop's public `shopReply`), the 1 to 5 star `ratingBreakdown` and Rakuten's own `aiReviewSummary` and `aiReviewTopics`. Turning on **Incremental mode** adds `changeType` (`NEW`, `UPDATED`, `UNCHANGED`, `REAPPEARED` or `EXPIRED`), `changedFields`, `firstSeenAt` and `lastSeenAt` to every row; these four fields are absent entirely when incremental mode is off.

For drop-in compatibility with other Rakuten scrapers, every row also carries six alias fields that repeat existing values: `imageUrl` (= `thumbnail`), `productName` (= `name`), `reviewScore` (= `rating`), `shippingPrice` (= `shippingFee`), `categories` (= `genrePath`) and `rankingPosition` (= `genreRank`). They never count as a change in incremental mode.

### How to Use

1. Pick a **mode**: `search` (build a search from keywords, genres, tags or shop codes) or `url` (paste Rakuten links you already have).
2. Fill in the fields for that mode, and switch on **Fetch product details** and/or **Fetch reviews** if you want the reference price, specs, variants or individual reviews.
3. Set **Max products** to control run size and cost, then click **Start**.
4. Download the dataset as JSON, CSV or Excel, or read it through the API.

**Search by keyword with Rakuten's own filters:**

```json
{
  "mode": "search",
  "queries": ["コーヒー豆"],
  "genreIds": ["100316"],
  "minPrice": 1000,
  "maxPrice": 5000,
  "minRating": "4",
  "condition": "new",
  "sortBy": "price-asc",
  "maxItems": 200
}
```

**Paste links you already have (a search page and a category page):**

```json
{
  "mode": "url",
  "urls": [
    "https://search.rakuten.co.jp/search/mall/coffee/?s=2",
    "https://www.rakuten.co.jp/category/100316/"
  ],
  "maxItems": 100
}
```

**Search one shop by its numeric shop ID, with details and reviews:**

```json
{
  "mode": "search",
  "queries": ["coffee"],
  "shopId": 193811,
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviewsPerItem": 20,
  "maxItems": 50
}
```

**Daily monitoring of the same search:**

```json
{
  "mode": "search",
  "queries": ["コーヒー豆"],
  "incrementalMode": true,
  "stateKey": "coffee-daily-watch",
  "maxItems": 0
}
```

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/rakuten-ichiba-scraper").call(
    run_input={"mode": "search", "queries": ["コーヒー豆"], "maxItems": 50}
)
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(product["name"], product["price"], product["shopName"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/rakuten-ichiba-scraper').call({
  mode: 'search', queries: ['コーヒー豆'], maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### How far a search reaches

Rakuten caps how deep any single search can be walked: the result pages report the reachable slice themselves (often a few hundred products for a broad keyword, even when millions match), and the walk stops there. To go wider, split the search: add genres, tags, price bands or shop codes. Result pages carry about 45 products each. Result pages can also include a handful of paid placements even on a sorted run, so a price-sorted page is not perfectly monotonic; those rows are marked `isSponsored: true` so you can filter or keep them deliberately.

#### URL mode: supported link shapes

The **URLs** field is pre-filled with one example of each shape below; running url mode with the field untouched scrapes all of them (capped by Max products). Clear it to run only your own links.

| Shape | Example | Result |
| --- | --- | --- |
| Keyword search | `search.rakuten.co.jp/search/mall/coffee/?s=2` | Product rows, walked page by page |
| Keyword in a genre | `.../search/mall/coffee/100316/` | Product rows |
| Genre only, paged | `.../search/mall/-/100316/?p=2` | Product rows |
| Tag (facet) | `.../search/mall/<keyword>/-/tg1011693/` | Product rows |
| Shop-restricted / filtered | `...?sid=193811`, `?min=500&max=2000&review=4&used=0&s=5` | Product rows |
| Genre page | `www.rakuten.co.jp/category/100316/` | Product rows |
| Legacy shop search | `.../search/inshop/ajinomoto/` | Rakuten redirects this to a keyword search for the shop code, not a full catalogue |
| Product page | `item.rakuten.co.jp/ajinomoto/nb38/` | One product row |
| Review page | `review.rakuten.co.jp/item/1/193811_10001806/2.1/` | Reviews for that product |
| Shop storefront | `www.rakuten.co.jp/ajinomoto/` | Skipped with a warning (not a listing) |

Shop codes in `shopUrlCodes` behave the same way as the legacy shop search: each code runs as a keyword search, so results are products that mention the code, not a guaranteed whole-shop catalogue. The field is still accepted; use `shopId` for a strict per-shop walk.

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) continues one specific interrupted run: paste its run or dataset ID and this run walks the same search or URLs again from the start, skipping every product id that run already collected as it re-encounters it, so you don't pay twice. A page that turns out to be entirely already-collected does not stop the walk early; it keeps going to the same natural end (or cap) a fresh run would reach. The run also saves its own progress as it goes, so a platform migration or a Resurrect of that same run continues on its own, without re-collecting or re-charging anything already pushed.
- **Incremental mode** (`incrementalMode`) is for recurring monitoring: schedule the same search or URLs daily and later runs return only what changed. Each product is classified `NEW`, `UPDATED` (with `changedFields` naming exactly what moved, for example `price` or `pointCount`), `UNCHANGED` (suppressed and not billed unless `emitUnchanged` is on), `REAPPEARED`, or `EXPIRED`. `REAPPEARED` only fires for a product whose stored state was previously marked gone, which itself only happens once a prior run was allowed to mark it `EXPIRED`. `EXPIRED` itself is produced only when **Emit expired** is on and this run's scan of the tracked search was complete: nothing capped by Max products, nothing cut short of its natural end by Max pages, Resume not used, at least one product actually scanned, and no page refused. A partial or capped run never tombstones a product that simply wasn't reached yet. With incremental mode off, every row is the plain base record, with no `changeType`, `changedFields`, `firstSeenAt` or `lastSeenAt` at all.

#### What incremental mode compares

Compared (a change makes the row `UPDATED`): price, original price, discount, points, stock and sale flags, title, shop, images, variants (including per-variant price and stock), shipping, tags, and the rating and review counts. Never compared (they never trigger `UPDATED`, but stay in the output): scrape time, search query, source URL, result position and page, delivery estimate, genre ranking, the site-wide Super Sale window, the AI review summary and topics, and the review texts themselves. Whole numbers compare equal whether stored as `25` or `25.0`.

#### Changes view

The dataset has a **Changes (incremental)** view listing the change type, the changed fields and the first and last seen times next to the product name, price and link, so recurring runs are easy to scan.

#### Ignore fields when detecting changes (incremental mode only)

`ignoreFieldsForChanges` is a list of extra field names (for example `pointCount`) that must never count as a change. They stay in the output but do not trigger `UPDATED` and are not listed in `changedFields`. Names match at any depth, including inside `variants`. The saved state is re-compared with the current list, so changing it never causes a one-time wave of `UPDATED` rows.

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each product, not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The
**complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify, Settings, Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where products should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` builds a search from keywords, genres, tags or shop codes; `url` takes Rakuten links you already have. |
| `queries` | array | (none) | Search keywords (search mode only). Japanese and English both work; each keyword runs its own paginated search. Prefill: `["コーヒー"]`. |
| `genreIds` | array | (none) | Rakuten genre (category) IDs to browse, or to narrow a keyword search to. Prefill: empty. |
| `tagIds` | array | (none) | Brand and specification facet tag IDs. Needs at least one keyword; ignored if a genre is also set, since Rakuten can't apply both at once. Prefill: empty. |
| `shopUrlCodes` | array | (none) | Shop codes, each run as a keyword search for that code (matches products mentioning it; not a guaranteed whole-shop catalogue, use `shopId` for a strict per-shop walk). Prefill: empty. |
| `shopId` | integer | (none) | Restrict a keyword or genre search to one numeric shop ID. |
| `sortBy` | string | `standard` | Search mode only, and has no effect on a shop-code walk. Result ordering applied by Rakuten itself: standard (relevance), price, price plus shipping, newest, most reviewed, or highest rated. |
| `minPrice` | integer | (none) | Minimum price in yen (search mode only). |
| `maxPrice` | integer | (none) | Maximum price in yen (search mode only). |
| `minRating` | string | (empty; any rating) | Search mode only, and has no effect on a shop-code walk. Only return products rated at least this highly: `3.5`, `4` or `4.5`. |
| `condition` | string | `any` | New only, used only, or any (search mode only). |
| `urls` | array | (none) | Rakuten URLs to walk or fetch directly (url mode only). Default and prefill: one example per supported URL shape (search, genre, tag, paged, shop-restricted, filtered, legacy shop search, category, product, review, plus a storefront page that is skipped with a warning); clear it to run your own. Legacy `/search/inshop/<shop>/` URLs are redirected by Rakuten to a keyword search for the shop code, not a full catalogue; storefront pages are not listings. |
| `maxItems` | integer | `50` | Cap on products returned across every keyword, genre, shop and URL combined. `0` = unlimited. |
| `maxPages` | integer | (none) | Optional bound on result pages per scope. Prefill: `0` (no page limit). |
| `fetchDetails` | boolean | `false` | Adds description, specs, images, every size/colour variant, the shipping fee amount and the reference ("was") price and discount percent. Charges the enrichment surcharge. |
| `shippingPrefecture` | string | empty | Prefecture the shipping fee is calculated for (Japanese or English name, or a number from 1 to 47). Empty means Tokyo. Applies with Fetch product details or a pasted product link. |
| `fetchReviews` | boolean | `false` | Adds individual reviews, the star breakdown and Rakuten's own AI review summary. Charges the same surcharge, once per product, whether or not Fetch product details is also on. |
| `maxReviewsPerItem` | integer | `20` | Reviews to return per product when Fetch reviews is on. Default lowered from 30 to 20. `0` or any value above 1000 is capped at 1000 reviews per product. |
| `resumeFromRunId` | string | (none) | Continue one specific interrupted run; products it already collected are skipped. |
| `incrementalMode` | boolean | `false` | Return only new and changed products by default on a recurring run over the same search or URLs (reappeared and expired products need Emit expired too, plus a complete scan). |
| `ignoreFieldsForChanges` | array | `[]` | Field names that never count as a change in incremental mode (they stay in the output but never trigger `UPDATED` or appear in `changedFields`). |
| `stateKey` | string | (none) | Name or deliberately share an incremental-mode monitoring campaign. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) products that have not changed since the last run. |
| `emitExpired` | boolean | `false` | Also return (and bill) products no longer found, once a run has fully scanned the tracked search. |
| `proxy` | object | `{"useApifyProxy": true}` | Connection settings. The default group serves paid plans; on a free plan the run continues on a backup connection. |
| `mcpConnectors` | array | (none) | Optional: send a summary of each product to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which product pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on products written to each connector per run. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live record.

```json
{
  "id": "412233_10000482",
  "itemCode": "10000482",
  "manageNumber": "mug-classic-01",
  "url": "https://item.rakuten.co.jp/paletuft-zakka/mug-classic-01/",
  "itemUrl": "https://item.rakuten.co.jp/paletuft-zakka/mug-classic-01/",
  "name": "パレタフト ハンドメイド陶器マグカップ 300ml 北欧デザイン",
  "subtitle": "ギフト箱入り 2色展開",
  "catchCopy": "手になじむシンプルなマグカップ",
  "brand": "PALETUFT",
  "shopId": "412233",
  "shopName": "パレタフト雑貨店",
  "shopUrlCode": "paletuft-zakka",
  "shopUrl": "https://www.rakuten.co.jp/paletuft-zakka/",
  "shopRating": 4.6,
  "shopReviewCount": 3820,
  "shopIsExcellent": true,
  "shopIs39": true,
  "price": 2160,
  "currency": "JPY",
  "priceMin": 2160,
  "priceMax": 2160,
  "hasPriceRange": false,
  "originalPrice": 2880,
  "originalPriceLabel": "メーカー希望価格",
  "discountPercent": 25.0,
  "pointCount": 21,
  "isSponsored": false,
  "isSoldOut": false,
  "availability": "InStock",
  "shippingFee": 0,
  "isFreeShipping": true,
  "genreId": "300258",
  "genrePath": ["生活雑貨・キッチン用品", "食器", "マグカップ"],
  "tags": [{ "id": "9001234", "name": "北欧雑貨", "groupId": "1000900", "groupName": "スタイル" }],
  "variants": [
    { "variantId": "77021", "options": ["ネイビー"], "price": 2160, "originalPrice": 2880, "pointCount": 21 },
    { "variantId": "77022", "options": ["アイボリー"], "price": 2160, "originalPrice": 2880, "pointCount": 21 }
  ],
  "hasMultipleVariants": true,
  "description": "手になじむ丸みのあるフォルムのマグカップです。ギフト箱にお入れしてお届けします。",
  "attributes": [{ "name": "素材", "value": "陶器" }, { "name": "容量", "value": "300 ml" }],
  "images": ["https://tshop.r10s.jp/paletuft-zakka/cabinet/mug-classic-01/main.jpg"],
  "imageCount": 1,
  "rating": 4.39,
  "reviewCount": 96,
  "ratingBreakdown": [
    { "stars": 5, "count": 58 }, { "stars": 4, "count": 24 }, { "stars": 3, "count": 9 },
    { "stars": 2, "count": 3 }, { "stars": 1, "count": 2 }
  ],
  "aiReviewSummary": "使いやすいサイズ感とデザインが好評です。",
  "reviews": [
    {
      "reviewId": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
      "rating": 5,
      "title": "とても気に入りました",
      "body": "軽くて持ちやすく、毎日のコーヒーに使っています。",
      "author": "コーヒー好きさん",
      "postedAt": "2026/06/14",
      "verifiedPurchase": true,
      "helpfulCount": 4,
      "variantInfo": "ネイビー",
      "shopReply": "ご購入ありがとうございます。",
      "images": []
    }
  ],
  "reviewsReturned": 1,
  "detailFetched": true,
  "reviewsFetched": true,
  "scrapedAt": "2026-09-15T03:00:00+00:00",
  "sourceUrl": "https://search.rakuten.co.jp/search/mall/mug/?s=2",
  "resultPage": 1,
  "resultPosition": 3
}
```

### Plan Requirement

A datacenter connection is enough for Rakuten; no residential proxy is needed. On paid plans the default Apify proxy group serves it. The free plan has no Apify proxy, so on a free plan the run says so and continues on a backup connection:

- Notice: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable."
- Notice: "Served over the backup connection (the default connection was unavailable)."
- Failure, account has no proxy access: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required." If you entered your own proxy URLs, check their credentials.
- Failure, backup also failed: "No results: residential proxies are unavailable on this run ... and the backup connection could not load the requested Rakuten pages." Upgrade your plan or supply your own proxy URLs.
- Failure, pages failed to load: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."

Each page gets a 25 second budget (retries included); a page that cannot be read in that time is counted as failed. The run moves to a backup connection only when a connection is refused for your account. For large or frequent runs, the residential proxy group gives more headroom; pick it under Proxy & connection.

### FAQ

#### How much does it cost?

You pay per product returned, plus a once-per-product surcharge when Fetch product details and/or Fetch reviews are on (a product enriched with both is still charged only once, not twice). A pasted product or review link's own page is read and included at no surcharge either way; only the other half (detail or reviews) is charged if its toggle is on. The **Pricing** tab shows the current rates. Use **Max products** to cap the cost of any run.

#### Is it legal to scrape Rakuten Ichiba?

This actor collects only publicly available product and review data. You are responsible for how you use it: follow Rakuten's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product names, prices and specifications are generally facts, but images, descriptions and shop-authored text may be subject to third-party rights.

#### Can I get only new or changed products on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental mode**. Each run then returns only new and updated products by default, and unchanged ones are not billed. Turn on **Emit expired** too, once a run scans the whole scope end to end, to also get expired products and, on a later run, reappeared ones.

#### Does this cover Rakuten in other countries?

No. This actor covers rakuten.co.jp (Rakuten Ichiba, Japan) only. Rakuten's other country sites, including the cash-back and coupon portal at rakuten.com and the separate marketplaces in France and Taiwan, are different platforms with their own catalogues, currencies and URL grammar, not a mode of this actor.

#### Why did my run fail instead of returning an empty dataset?

If a run returns nothing and some pages could not be read, the run stops with a clear message so "nothing matched" is never confused with "nothing could be read". Run it again in a few minutes, or select a different proxy group (see Plan Requirement for the exact messages). A genuinely empty search where every page was actually read still finishes successfully with zero rows.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 Want more Rakuten data?

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🏨 <a href="https://apify.com/abotapi/rakuten-travel-scraper"><b>Rakuten Travel Scraper</b></a><br>Scrape Rakuten Travel, Japan's largest domestic hotel-booking site, by prefecture...</td><td>👗 <a href="https://apify.com/abotapi/zozotown-scraper"><b>ZOZOTOWN</b></a><br>Scrape ZOZOTOWN (zozo.jp), Japan's largest fashion marketplace: name, brand, JPY price...</td></tr>
<tr><td>🧩 <a href="https://apify.com/abotapi/mistore-jp-scraper"><b>Isetan Mitsukoshi</b></a><br>Scrape the Isetan Mitsukoshi department store online shop (mistore.jp). Search by keyword...</td><td>🛒 <a href="https://apify.com/abotapi/nitori-net-jp-scraper"><b>Nitori Japan Furniture &amp; Home Goods Scraper</b></a><br>Scrape Nitori Japan (nitori-net.jp) furniture and home goods by keyword, category or...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/mercari-jp-scraper"><b>Mercari Japan Scraper</b></a><br>Scrape Mercari Japan listings, sellers and reviews at scale. Extract names, prices...</td><td>🧩 <a href="https://apify.com/abotapi/suumo-jp-scraper"><b>Suumo.jp Scraper</b></a><br>Scrape Suumo, Japan's largest property portal: rental rooms with rent, management fees...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/rakuten-ichiba-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `mode` (type: `string`):

How to find products. 'search' builds Rakuten Ichiba searches from keywords, genres and shops. 'url' takes Rakuten URLs you already have: search results, category pages, whole-shop pages, product pages and review pages.

## `urls` (type: `array`):

Rakuten Ichiba URLs (URL mode only). Accepted: keyword/genre/tag/shop-restricted/filtered search results (search.rakuten.co.jp/search/mall/...), category pages (www.rakuten.co.jp/category/<id>/), legacy search.rakuten.co.jp/search/inshop/<shop>/ (Rakuten redirects it to a keyword search for the shop code, not a full catalogue), product pages (item.rakuten.co.jp/<shop>/<item>/) and review pages (review.rakuten.co.jp/item/1/...). Shop storefront pages (www.rakuten.co.jp/<shop>/) are not listings: they are skipped with a warning; use a search URL with ?sid=<shop ID> instead. Listing URLs are walked forward page by page; the filters above are ignored because the URL already carries its own. The default holds one example per URL shape; clear it to run your own.

## `queries` (type: `array`):

Keywords to search on Rakuten Ichiba (Search mode only). Japanese and English both work. Each keyword runs its own paginated search and the results are combined.

## `genreIds` (type: `array`):

Rakuten genre IDs, for example 100316 for Water & Soft Drinks. With keywords, each keyword is searched inside each genre. Without keywords, each genre is browsed on its own. Find an ID in any rakuten.co.jp/category/<id>/ URL.

## `tagIds` (type: `array`):

Rakuten tag IDs, used for brand and specification facets (for example 1011693 for UCC). Several tags in the same group are combined as 'any of'. Note: Rakuten's own search URLs cannot apply a genre and tags at the same time, so if you also set a genre the tags are ignored.

## `shopUrlCodes` (type: `array`):

Shop codes, for example 'sawaicoffee-tea' from item.rakuten.co.jp/sawaicoffee-tea/... Each code runs Rakuten's keyword search for that code, which surfaces products that mention it; it is not a guaranteed whole-shop catalogue (for a strict per-shop walk use the shop ID input). Works with or without keywords.

## `shopId` (type: `integer`):

Numeric Rakuten shop ID. When set, keyword and genre searches only return products from that shop.

## `sortBy` (type: `string`):

Result ordering applied by Rakuten itself (Search mode only).

## `minPrice` (type: `integer`):

Minimum price in yen (Search mode only). Leave empty for no minimum.

## `maxPrice` (type: `integer`):

Maximum price in yen (Search mode only). Leave empty for no maximum.

## `minRating` (type: `string`):

Only return products rated at least this highly (Search mode only). Rakuten supports these three steps.

## `condition` (type: `string`):

Filter by new or used (Search mode only).

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

Cap on products returned across every keyword, genre, shop and URL combined. Set 0 for unlimited, bounded only by Max pages and by how many results Rakuten makes reachable for a query.

## `maxPages` (type: `integer`):

Optional bound on result pages per keyword, genre, shop or URL. Rakuten returns about 45 products per page. Leave empty or 0 for no page limit.

## `fetchDetails` (type: `boolean`):

Adds the full description, the specification table, all images, every size and colour variant with its own price and points, the shipping carriers, the shipping fee amount and free-shipping threshold for your chosen prefecture, and the reference ('was') price plus discount percent, which Rakuten publishes only on the product page. Charges the per-product enrichment surcharge.

## `shippingPrefecture` (type: `string`):

The prefecture the shipping fee is calculated for when Fetch product details is on (or for a pasted product link). Enter a Japanese or English name such as 東京都, Hokkaido or Okinawa, or a number from 1 to 47. Fees differ by region, and some remote areas have no calculable fee. Leave empty for Tokyo, the product page's own default.

## `fetchReviews` (type: `boolean`):

Adds individual reviews (rating, title, text, reviewer nickname, date, helpful count, purchased variant, shop reply and review photos), the 1-to-5 star rating breakdown, and Rakuten's own AI review summary. Charges the same per-product enrichment surcharge, once per product, whether or not you also turn on Fetch product details.

## `maxReviewsPerItem` (type: `integer`):

How many reviews to return per product when Fetch reviews is on. Rakuten publishes 30 per review page. Values above 1000, and 0, are capped at 1000 reviews per product.

## `proxy` (type: `object`):

A datacenter connection is enough for Rakuten. The Apify Proxy default group serves it on paid plans; the free plan has no Apify proxy, so a free-plan run says so and continues on a backup connection. Switch to a different proxy group only if a run reports pages it could not read.

## `resumeFromRunId` (type: `string`):

Optional: paste a previous run ID (or dataset ID) from this actor. Products already collected there are skipped, so this run only returns new ones. Leave empty for a normal run. For recurring monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring of the same search or URLs. The first run returns every matching product as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED products. Compared: price, original price, discount, points, stock and sale flags, title, shop, images, variants (including per-variant price and stock), shipping, tags and rating/review counts, with changedFields naming exactly what moved. Never compared (they never trigger UPDATED): scrape time, search query, source URL, result position/page, delivery estimate, genre ranking, Super Sale window, AI review summary/topics and the review texts themselves. Turn on Emit unchanged or Emit expired only when you also want those rows returned, and billed. State is kept separately per search and filter setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from run ID above.

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

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search and filter settings, so different searches never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have, so leave it off unless you want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search with no unreadable pages, never when Max items or Max pages capped it and never when Resume was used. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.

## `ignoreFieldsForChanges` (type: `array`):

Incremental mode only. Field names that must never count as a change, for example pointCount or reviewCount. They stay in the output but do not trigger UPDATED or appear in changedFields. Applies at any depth, including inside variants. Takes effect immediately against the saved state, with no one-time wave of UPDATED rows.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it here. The connector receives a condensed, human-readable summary per product (title plus key fields), not the full JSON: the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which product pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on products written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "urls": [
    "https://search.rakuten.co.jp/search/mall/coffee/?s=2",
    "https://search.rakuten.co.jp/search/mall/coffee/100316/",
    "https://search.rakuten.co.jp/search/mall/-/100316/?p=2",
    "https://www.rakuten.co.jp/category/100316/",
    "https://search.rakuten.co.jp/search/mall/%E3%82%B3%E3%83%BC%E3%83%92%E3%83%BC/-/tg1011693/",
    "https://search.rakuten.co.jp/search/mall/coffee/?p=3",
    "https://search.rakuten.co.jp/search/mall/coffee/?sid=193811",
    "https://search.rakuten.co.jp/search/mall/coffee/?min=500&max=2000&review=4&used=0&s=5",
    "https://search.rakuten.co.jp/search/inshop/ajinomoto/",
    "https://www.rakuten.co.jp/ajinomoto/",
    "https://item.rakuten.co.jp/ajinomoto/nb38/",
    "https://review.rakuten.co.jp/item/1/193811_10001806/2.1/"
  ],
  "queries": [
    "コーヒー"
  ],
  "genreIds": [],
  "tagIds": [],
  "shopUrlCodes": [],
  "sortBy": "standard",
  "minRating": "",
  "condition": "any",
  "maxItems": 50,
  "maxPages": 0,
  "fetchDetails": false,
  "fetchReviews": false,
  "maxReviewsPerItem": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `detail` (type: `string`):

No description

## `reviews` (type: `string`):

No description

## `changes` (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 = {
    "mode": "search",
    "urls": [
        "https://search.rakuten.co.jp/search/mall/coffee/?s=2",
        "https://search.rakuten.co.jp/search/mall/coffee/100316/",
        "https://search.rakuten.co.jp/search/mall/-/100316/?p=2",
        "https://www.rakuten.co.jp/category/100316/",
        "https://search.rakuten.co.jp/search/mall/%E3%82%B3%E3%83%BC%E3%83%92%E3%83%BC/-/tg1011693/",
        "https://search.rakuten.co.jp/search/mall/coffee/?p=3",
        "https://search.rakuten.co.jp/search/mall/coffee/?sid=193811",
        "https://search.rakuten.co.jp/search/mall/coffee/?min=500&max=2000&review=4&used=0&s=5",
        "https://search.rakuten.co.jp/search/inshop/ajinomoto/",
        "https://www.rakuten.co.jp/ajinomoto/",
        "https://item.rakuten.co.jp/ajinomoto/nb38/",
        "https://review.rakuten.co.jp/item/1/193811_10001806/2.1/"
    ],
    "queries": [
        "コーヒー"
    ],
    "genreIds": [],
    "tagIds": [],
    "shopUrlCodes": [],
    "maxItems": 50,
    "maxPages": 0,
    "maxReviewsPerItem": 20,
    "proxy": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/rakuten-ichiba-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 = {
    "mode": "search",
    "urls": [
        "https://search.rakuten.co.jp/search/mall/coffee/?s=2",
        "https://search.rakuten.co.jp/search/mall/coffee/100316/",
        "https://search.rakuten.co.jp/search/mall/-/100316/?p=2",
        "https://www.rakuten.co.jp/category/100316/",
        "https://search.rakuten.co.jp/search/mall/%E3%82%B3%E3%83%BC%E3%83%92%E3%83%BC/-/tg1011693/",
        "https://search.rakuten.co.jp/search/mall/coffee/?p=3",
        "https://search.rakuten.co.jp/search/mall/coffee/?sid=193811",
        "https://search.rakuten.co.jp/search/mall/coffee/?min=500&max=2000&review=4&used=0&s=5",
        "https://search.rakuten.co.jp/search/inshop/ajinomoto/",
        "https://www.rakuten.co.jp/ajinomoto/",
        "https://item.rakuten.co.jp/ajinomoto/nb38/",
        "https://review.rakuten.co.jp/item/1/193811_10001806/2.1/",
    ],
    "queries": ["コーヒー"],
    "genreIds": [],
    "tagIds": [],
    "shopUrlCodes": [],
    "maxItems": 50,
    "maxPages": 0,
    "maxReviewsPerItem": 20,
    "proxy": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/rakuten-ichiba-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 '{
  "mode": "search",
  "urls": [
    "https://search.rakuten.co.jp/search/mall/coffee/?s=2",
    "https://search.rakuten.co.jp/search/mall/coffee/100316/",
    "https://search.rakuten.co.jp/search/mall/-/100316/?p=2",
    "https://www.rakuten.co.jp/category/100316/",
    "https://search.rakuten.co.jp/search/mall/%E3%82%B3%E3%83%BC%E3%83%92%E3%83%BC/-/tg1011693/",
    "https://search.rakuten.co.jp/search/mall/coffee/?p=3",
    "https://search.rakuten.co.jp/search/mall/coffee/?sid=193811",
    "https://search.rakuten.co.jp/search/mall/coffee/?min=500&max=2000&review=4&used=0&s=5",
    "https://search.rakuten.co.jp/search/inshop/ajinomoto/",
    "https://www.rakuten.co.jp/ajinomoto/",
    "https://item.rakuten.co.jp/ajinomoto/nb38/",
    "https://review.rakuten.co.jp/item/1/193811_10001806/2.1/"
  ],
  "queries": [
    "コーヒー"
  ],
  "genreIds": [],
  "tagIds": [],
  "shopUrlCodes": [],
  "maxItems": 50,
  "maxPages": 0,
  "maxReviewsPerItem": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/rakuten-ichiba-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/rakuten-ichiba-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/qjGr1atNl322SDj2X/builds/e8FUYppwHw7pTi4Ih/openapi.json
