# Rakuten - Products, Variants & Reviews (`abotapi/rakuten-ichiba-scraper`) Actor

Scrape Rakuten Ichiba (rakuten.co.jp): name, JPY price, reference price and discount, Rakuten points, shipping, stock, shop, genre, tags, images, size/colour variants with per-variant price, specs, and customer reviews with star breakdown and shop replies. Search or paste URLs; incremental mode.

- **URL**: https://apify.com/abotapi/rakuten-ichiba-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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?

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

## Rakuten Japan Scraper: Products, Variants & Reviews

Scrape **Rakuten Ichiba** (楽天市場, `rakuten.co.jp`), Japan's largest online marketplace, into clean
structured rows. Search by keyword, genre, tag or shop with Rakuten's own filters, or paste any Rakuten
URL you already have. Every product comes back with price, the reference ("was") price and discount,
Rakuten points, shipping and delivery, stock, shop, category, tags, images, size and colour variants,
full specifications, and individual customer reviews.

Built for price monitoring, catalogue tracking, assortment research and review mining. Fast, with a low
cost per record.

***

### What you get

**Around 95 fields per product.** Highlights:

| Group | Fields |
|---|---|
| Identity | `id` (shop-scoped, stable), `itemCode`, `manageNumber`, `url`, `name`, `subtitle`, `catchCopy`, `brand` |
| Price | `price`, `currency` (JPY), `originalPrice`, `originalPriceLabel`, `discountPercent`, `priceMin`, `priceMax`, `hasPriceRange`, `unitPriceDisplay`, `subscriptionPrice`, `subscriptionDiscountPercent`, `taxIncluded`, `taxRate` |
| Rakuten points | `pointCount`, `pointBaseMultiplier`, `pointItemMultiplier`, `pointShopMultiplier`, `pointDealMultiplier`, `isSuperDeal` |
| Availability | `isSoldOut`, `availability`, `inventoryType`, `isPreOrder` |
| Shipping | `shippingFee`, `isFreeShipping`, `deliveryEstimate`, `deliveryDays`, `isRakutenLogistics`, `isAsuraku`, `shippingCarriers` |
| Shop | `shopId`, `shopName`, `shopUrlCode`, `shopUrl`, `shopRating`, `shopReviewCount`, `shopIsExcellent`, `shopIs39` |
| Media | `thumbnail`, `images`, `imageCount`, `videos` |
| Taxonomy | `genreId`, `genreIdPath`, `genrePath`, `genres`, `breadcrumbs`, `tags` (id, name, group), `tagIds` |
| Variants | `variants` (per variant: id, options, price, `originalPrice`, points, shipping, images), `variantAxes`, `hasMultipleVariants`, `customizationOptions` |
| Specs | `description`, `salesDescription`, `attributes` (name/value spec table) |
| Reviews | `rating`, `reviewCount`, `ratingBreakdown` (1 to 5 star histogram), `reviews[]`, `reviewsReturned`, `aiReviewSummary`, `aiReviewTopics`, `reviewUrl` |
| Flags | `isUsed`, `usedCondition`, `isRental`, `isSubscription`, `isHometownTax`, `isSocialGift`, `isSponsored` |
| Ranking | `genreRank`, `genreRankGenre`, `genreRankUrl` |
| Change tracking | `changeType`, `changedFields`, `firstSeenAt`, `lastSeenAt` |
| Provenance | `searchQuery`, `sourceUrl`, `resultPage`, `resultPosition`, `scrapedAt`, `detailFetched`, `reviewsFetched` |

Each review row inside `reviews[]` carries: `reviewId`, `rating`, `title`, `body`, `author` (public
display nickname), `postedAt`, `orderedAt`, `verifiedPurchase`, `helpfulCount`, `informativeScore`, `authorAgeRange`,
`authorGender`, `variantInfo` (which variant was bought), `surveyAnswers`, `purchaseUse`,
`purchaseFrequency`, `purchasePurpose`, `shopReply`, `shopRepliedAt`, `images`, `imageThumbnails`.

***

### Modes

#### Search mode

Give it keywords, genres, shop codes, or any combination.

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

Native filters, all applied by Rakuten itself so you only pay for rows you wanted:

| Input | What it does |
|---|---|
| `queries` | One paginated search per keyword. Japanese and English both work. |
| `genreIds` | Rakuten genre (category) IDs. Browse a whole genre with no keyword, or narrow a keyword to it. |
| `tagIds` | Brand and specification facets. Several tags in the same group behave as "any of". |
| `shopUrlCodes` | Walk a shop's entire catalogue by its code, for example `sawaicoffee-tea`. |
| `shopId` | Restrict a keyword or genre search to one numeric shop ID. |
| `minPrice` / `maxPrice` | Price band in yen. |
| `minRating` | `3.5`, `4` or `4.5` and up. These are the three steps Rakuten supports. |
| `condition` | New only, used only, or any. |
| `sortBy` | Standard (relevance), price low/high, price plus shipping low/high, newest, most reviewed, highest rated. |

One quirk worth knowing: **Rakuten's own search URLs cannot apply a genre and tag filters at the same
time.** If you set both, the genre is used and the tags are ignored, and the run log says so.
Tag filters also need a keyword or a genre alongside them; on their own Rakuten returns nothing, so the
actor refuses that combination up front instead of charging you for an empty run.

#### URL mode

Paste links you already have. Five kinds are recognised:

```json
{
  "mode": "url",
  "urls": [
    "https://search.rakuten.co.jp/search/mall/coffee/?s=2",
    "https://www.rakuten.co.jp/category/100316/",
    "https://search.rakuten.co.jp/search/inshop/sawaicoffee-tea/",
    "https://item.rakuten.co.jp/sawaicoffee-tea/ac-sale-1960/",
    "https://review.rakuten.co.jp/item/1/198667_10001136/1.1/"
  ],
  "maxItems": 100
}
```

Search, category and shop URLs are walked forward page by page. Product and review URLs return that one
product directly, with no wasted search. Reading the page you actually pasted is never charged the
enrichment surcharge, because that page **is** the request.

***

### Discounts and the "was" price

Rakuten does not put a strike-through price on search result cards. It publishes the reference price
only on the product page, per variant. So `originalPrice`, `originalPriceLabel` and `discountPercent`
are filled in when **`fetchDetails` is on**, and are `null` otherwise.

Verified live on 2026-08-27 against `item.rakuten.co.jp/miyoshi-ya/wa-02002/`:

```json
{
  "price": 880,
  "originalPrice": 1760,
  "originalPriceLabel": "当店通常価格",
  "discountPercent": 50,
  "variants": [{ "variantId": "16154", "options": ["抗菌ライトオーク"], "price": 880, "originalPrice": 1760 }]
}
```

***

### Reviews

Rakuten Ichiba exposes reviews publicly, and this actor reads them. Turn on `fetchReviews` and set
`maxReviewsPerItem` (`0` returns every review a product has).

You get the aggregate (`rating`, `reviewCount`), the full 1 to 5 star `ratingBreakdown`, Rakuten's own
AI review summary and topic sentiment, and the individual reviews with the shop's public replies and
any photos reviewers attached.

Verified live on 2026-08-27 against a product with 50,021 reviews: rating 4.7, breakdown
`[5★ 38274, 4★ 9587, 3★ 1494, 2★ 319, 1★ 348]`, 30 individual reviews per page across multiple pages,
each with rating, text, nickname, date, helpful count, the variant purchased and, where present, the
shop's reply.

A product with no reviews returns `reviews: []`, `reviewsReturned: 0`, and leaves `rating` and
`ratingBreakdown` empty rather than inventing zeros.

Only what Rakuten itself displays publicly is copied. Reviewer display nicknames are included because
they are shown on the page, together with the order date Rakuten itself prints on the review.

Two further reviewer-supplied attributes are copied when, and only when, Rakuten publishes them beside
the review: `authorAgeRange`, a coarse decade band such as `40代`, and `authorGender`. Both are
optional self-declared profile fields, both are printed publicly on the review page, and both come back
`null` when the reviewer did not publish them. If you do not want them, drop the two columns on export.

No account identifier, email address, phone number, postal address or any other contact detail is ever
collected.

***

### Country scope: Japan only, and why

This actor covers **`rakuten.co.jp` (Rakuten Ichiba, Japan) only**. That is a deliberate decision, not
an omission. Every other Rakuten country property was re-checked live on 2026-08-27, each one fetched
with the same real-browser client this actor uses:

| Property | What it actually serves | Verdict |
|---|---|---|
| `www.rakuten.com` (US) | 200. The Rakuten cash-back and coupon portal ("Coupons, Promo Codes & Cash Back"). No marketplace catalogue, nothing resembling Ichiba's data shape. | Different product, out of scope |
| `global.rakuten.com` | 200, redirecting to `/corp/`, where it serves Rakuten Group corporate and investor pages. The **storefront** paths are the part that is gone: `/en/` and `/en/store/` both return 404 "Page not found". Rakuten Global Market is retired; the hostname is not. | Storefront retired, host alive |
| `fr.shopping.rakuten.com` (France) | 200, ~450 KB of a live marketplace (formerly PriceMinister) with its own URL grammar, its own catalogue, EUR prices and a different page structure. | Separate site, own actor |
| `www.rakuten.com.tw` (Taiwan) | 200, ~950 KB of a live, actively maintained Chinese-language storefront. It has its own URL grammar (`/search/<keyword>/`, `/shop/<code>/`), its own catalogue and TWD prices - none of which match Ichiba's `search.rakuten.co.jp/search/mall/...` pages or their structure. | Separate site, own actor |

**On how these were checked.** Rakuten's edge refuses requests that do not look like they came from a
real browser, and it refuses them *before* answering - so a naive check can make a perfectly healthy
storefront look like a dead host. Every row above was fetched exactly the way this actor fetches
`rakuten.co.jp`, so "live" and "404" mean what a real browser sees. In particular
`www.rakuten.com.tw` resolves and serves a full storefront: any claim that it is gone is an artefact
of the probe, not a fact about the site.

The scope decision does not rest on any of these being dead. It rests on them being **different
platforms**: separate catalogues, separate currencies, separate URL grammars and separate page
payloads, with no shared or trivially parameterisable backend behind them. A `country` input on this
actor would have been a label with nothing behind it, so it is not offered. Rakuten France and Rakuten
Taiwan are each a reasonable candidate for a separate actor with its own extraction logic.

***

### Incremental mode and resume

Two different things, both included.

**`incrementalMode`** is for recurring monitoring. Schedule the same search daily and later runs return
only what actually changed:

- `changeType` is `NEW`, `UPDATED`, `REAPPEARED` or `EXPIRED`
- `changedFields` names exactly what moved, for example `["price"]` or `["isSoldOut", "pointCount"]`
- `firstSeenAt` and `lastSeenAt` track each product's lifetime

Unchanged products are suppressed by default, so you are not billed for rows you already have. Turn on
`emitUnchanged` for a full snapshot every run, or `emitExpired` to be told when a product disappears.
Both return, and bill, extra rows.

Fields that change on their own every day without the product changing are deliberately excluded from
change detection: the delivery-date estimate, the daily genre ranking position, the site-wide Rakuten
sale window, and the AI-generated review summary. Price, discount, stock, points, rating and review
count all count as real changes.

`EXPIRED` is only produced after a run has fully scanned the tracked search with nothing capped, nothing
resumed, nothing unreadable and something actually found. A partial run never tombstones live products.

**`resumeFromRunId`** continues one specific interrupted run. Paste the previous run ID (or dataset ID)
and rows already collected there are skipped. Runs also survive a platform migration or a Resurrect on
their own, without re-collecting or re-charging anything.

***

### Pricing

Billing has three components, each with volume tiers:

| Event | What triggers it |
|---|---|
| Actor start | Once per run. |
| Product result | Each product row returned in the dataset. |
| Product detail and reviews | Once per product when `fetchDetails` and/or `fetchReviews` is on. A product enriched with **both** is charged once, not twice. |

A suppressed row in incremental mode is never charged, even though its pages were still read to work out
whether anything changed. A failed enrichment is never charged either.

***

### Connection

The Apify Proxy default group is enough, and it works on every plan. Switch to a different proxy group
only if a run reports pages it could not read.

If every page of a run is refused, the run **fails** with a clear message rather than quietly reporting
an empty search. "We found nothing" and "we could not read anything" are never confused.

***

### Limits worth knowing

- 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.
- A shop walk (`shopUrlCodes`, or a pasted `/search/inshop/<code>/` URL) is Rakuten's own in-shop
  search, and Rakuten mixes a few rows from **other** shops into it - measured at 2 of 48 on a live
  walk. Rakuten does not flag those rows, and this actor returns them as Rakuten served them rather
  than silently dropping rows it cannot prove are foreign. Every row carries `shopUrlCode` and
  `shopId`, so filter on the code you asked for if you need a strictly single-shop catalogue.
- Rakuten mixes paid placements into every result page, including sorted ones, so a price-sorted run is
  not perfectly monotonic. Those rows are marked `isSponsored: true` so you can filter or keep them
  deliberately. Measured on a price-sorted, price-banded run of 60 products: 2 sponsored rows.
- Prices are in Japanese yen, tax included as displayed by the shop.

***

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

Optionally pipe results into Notion, Linear, Airtable or Apify through MCP connectors. Authorize a
connector once under Apify, Settings, Integrations, then select it here. The connector receives a
condensed summary per product; the complete record always stays in the dataset.

# 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.

## `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 shop's full catalogue is walked page by page. 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).

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

Rakuten Ichiba URLs (URL mode only). Search results (search.rakuten.co.jp/search/mall/...), category pages (www.rakuten.co.jp/category/<id>/), whole-shop pages (search.rakuten.co.jp/search/inshop/<shop>/), product pages (item.rakuten.co.jp/<shop>/<item>/) and review pages (review.rakuten.co.jp/item/1/...) are all accepted. Listing URLs are walked forward page by page; the filters above are ignored because the URL already carries its own.

## `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, and the reference ('was') price plus discount percent, which Rakuten publishes only on the product page. Charges the per-product enrichment surcharge.

## `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, so 30 is the cheapest setting. Set 0 to return every review a product has, which can be thousands of reviews.

## `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, with changedFields naming exactly what moved (price, stock, points, discount). 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.

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

The Apify Proxy default group is enough, and it works on every plan. Switch to a different proxy group only if a run reports pages it could not read.

## `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",
  "queries": [
    "コーヒー"
  ],
  "genreIds": [],
  "tagIds": [],
  "shopUrlCodes": [],
  "sortBy": "standard",
  "minRating": "",
  "condition": "any",
  "urls": [
    "https://search.rakuten.co.jp/search/mall/coffee/?s=2"
  ],
  "maxItems": 50,
  "fetchDetails": false,
  "fetchReviews": false,
  "maxReviewsPerItem": 30,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

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

No description

## `reviews` (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",
    "queries": [
        "コーヒー"
    ],
    "genreIds": [],
    "tagIds": [],
    "shopUrlCodes": [],
    "urls": [
        "https://search.rakuten.co.jp/search/mall/coffee/?s=2"
    ],
    "maxItems": 50,
    "maxPages": 0,
    "maxReviewsPerItem": 30,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxy": {
        "useApifyProxy": true
    }
};

// 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",
    "queries": ["コーヒー"],
    "genreIds": [],
    "tagIds": [],
    "shopUrlCodes": [],
    "urls": ["https://search.rakuten.co.jp/search/mall/coffee/?s=2"],
    "maxItems": 50,
    "maxPages": 0,
    "maxReviewsPerItem": 30,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxy": { "useApifyProxy": True },
}

# 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",
  "queries": [
    "コーヒー"
  ],
  "genreIds": [],
  "tagIds": [],
  "shopUrlCodes": [],
  "urls": [
    "https://search.rakuten.co.jp/search/mall/coffee/?s=2"
  ],
  "maxItems": 50,
  "maxPages": 0,
  "maxReviewsPerItem": 30,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  }
}' |
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/0AdQtYeZJrk5th80J/openapi.json
