# MUJI Scraper - Products, Prices, Stock & Reviews (`abotapi/muji-scraper`) Actor

Scrape MUJI products from the United States, Canada and Australia storefronts. Search by keyword or paste product, category and search links. Returns price, was-price and discount, per-variant stock, sizes, colours, media, materials and customer reviews, plus Incremental mode for change monitoring.

- **URL**: https://apify.com/abotapi/muji-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** E-commerce
- **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

## MUJI Product Scraper

Pull structured product data from MUJI's international storefronts: the United States (muji.us),
Canada (muji.ca) and Australia (muji.com.au). Search by keyword, or paste product, category and
search links and scrape them directly. Every product comes back as one flat record with its
identity, price and discount, per-variant stock, sizes and colours, images and videos, the full
description with materials, measurements and country of origin, and its customer rating and
reviews.

Built for catalogue monitoring, price and discount tracking, assortment comparison across
countries, and product research.

### What you can do

- Search MUJI by keyword, or paste any mix of product, category and search links.
- Pick a country storefront and get that country's own catalogue, prices, currency and stock.
- Mix links from different MUJI countries in one run; each link keeps its own country.
- Narrow by category, colour, size, price range and availability, using the storefront's own
  filter values.
- Order by relevance, price, name, newest or best selling.
- Capture the was-price, the discount amount and the discount percentage on sale items.
- Collect individual customer reviews with rating, title, text, author, date, verified-buyer
  flag, helpful votes, review photos and the per-star breakdown.
- Take every result page, or stop at a page or product cap you set.
- Re-run the same search on a schedule and get only what changed, with Incremental mode.

### Country coverage

| Storefront | Currency | Covered |
|---|---|---|
| United States (muji.us) | USD | yes |
| Canada (muji.ca) | CAD | yes |
| Australia (muji.com.au) | AUD | yes |
| Japan (muji.com) | JPY | no, see below |
| Europe and United Kingdom (muji.eu) | EUR, GBP | no, see below |

MUJI Japan and MUJI Europe are not country variants of the same storefront; they are separate
platforms with a different catalogue contract, so nothing in this actor applies to them. They
need their own actor rather than an option here. This is a documented limitation, not a gap
that a setting can open.

### Input

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` for keywords, `url` for pasted links. |
| `queries` | array | `["aroma diffuser"]` | Search keywords. Search mode only. |
| `urls` | array | two examples | Product, category or search links. URL mode only. |
| `country` | string | `us` | `us`, `ca` or `au`. In URL mode a link's own address wins. |
| `category` | string | empty | Keep only this catalogue category, for example `T-Shirts`. |
| `color` | string | empty | Keep only products offered in this colour. |
| `size` | string | empty | Keep only products offered in this size. |
| `minPrice` | integer | empty | Lowest current price to keep, in the storefront's currency. |
| `maxPrice` | integer | empty | Highest current price to keep, in the storefront's currency. |
| `inStockOnly` | boolean | `false` | Drop sold-out products. |
| `sortBy` | string | `relevance` | `relevance`, `price_asc`, `price_desc`, `title_asc`, `newest`, `best_selling`. |
| `fetchDetails` | boolean | `true` | Add description, breadcrumb, extra media, materials, measurements, care and origin. |
| `fetchReviews` | boolean | `false` | Add individual customer reviews and the per-star breakdown. |
| `maxReviewsPerProduct` | integer | `20` | Cap on reviews collected per product. |
| `maxItems` | integer | `20` | Products returned across the run. `0` for unlimited. |
| `maxPages` | integer | `0` | Result pages per keyword or link. `0` for unlimited. |
| `resumeFromRunId` | string | empty | Continue one interrupted run without repeating its products. |
| `incrementalMode` | boolean | `false` | Return only what changed since the last run of the same search. |
| `stateKey` | string | empty | Name a monitoring campaign, or share state deliberately. |
| `emitUnchanged` | boolean | `false` | Also return, and bill, unchanged products. |
| `emitExpired` | boolean | `false` | Also return, and bill, products that have disappeared. |
| `proxy` | object | Apify Proxy | Connection used for every request. |
| `mcpConnectors` | array | empty | Send results into your apps as well as the dataset. |
| `notionParentPageUrl` | string | empty | Parent page for the Notion connector. |
| `maxNotifyListings` | integer | `50` | Cap on products written to each connector. |

`maxItems` is the run's only cap by default. `maxPages` is unlimited unless you set it, so it never
caps the run below `maxItems`.

#### Examples

Keyword search on the Canadian storefront:

```json
{
  "mode": "search",
  "queries": ["aroma diffuser", "essential oil"],
  "country": "ca",
  "maxItems": 40
}
```

Discounted products with the was-price and discount, ordered cheapest first:

```json
{
  "mode": "url",
  "urls": ["https://www.muji.us/collections/sale"],
  "sortBy": "price_asc",
  "maxItems": 100,
  "maxPages": 0
}
```

Filtered search with reviews:

```json
{
  "mode": "search",
  "queries": ["shirt"],
  "country": "us",
  "category": "T-Shirts",
  "color": "Black",
  "minPrice": 20,
  "maxPrice": 60,
  "inStockOnly": true,
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviewsPerProduct": 25
}
```

Links from three countries in one run:

```json
{
  "mode": "url",
  "urls": [
    "https://www.muji.us/products/ultrasonic-aroma-diffuser",
    "https://muji.ca/collections/sale",
    "https://muji.com.au/search?q=oxford+shirt"
  ],
  "maxItems": 60
}
```

A category or search link that already carries `page=3` starts at page 3 rather than at page 1.

### Output

One record per product. Fields marked with a dot are filled when `fetchDetails` is on; fields
marked with a star are filled when `fetchReviews` is on.

| Field | Example |
|---|---|
| `productId` | `"0000000000001"` |
| `handle` | `"sample-product-handle"` |
| `title` | `"Sample Product Name"` |
| `url` | `"https://www.muji.us/products/sample-product-handle"` |
| `country` / `countryName` | `"us"` / `"United States"` |
| `currency` | `"USD"` |
| `brand` | `"MUJI"` |
| `category` | `"Aroma Diffusers"` |
| `productCategory` | `"Diffusers"` |
| `breadcrumb` . | `["Home", "Health & Beauty", "Aroma & Fragrances"]` |
| `collections` . | `[{"handle": "aroma-fragrances", "title": "Aroma & Fragrances"}]` |
| `tags` | `["Aroma Diffuser", "Best Seller Home"]` |
| `price` / `priceMax` | `74.99` / `74.99` |
| `originalPrice` | `89.90` |
| `discountAmount` / `discountPercent` | `14.91` / `16.6` |
| `onSale` | `true` |
| `inStock` / `availableForSale` | `true` |
| `variantCount` / `inStockVariantCount` | `4` / `3` |
| `sizes` / `colors` | `["S", "M", "L"]` / `["Black", "White"]` |
| `options` | `[{"name": "Size", "values": ["S", "M", "L"]}]` |
| `variants` | see below |
| `sku` | `"0000000000000"` |
| `featuredImage` / `images` / `thumbnails` | image URLs |
| `videos` . | `[{"url": "https://example.com/v/00000", "mimeType": null}]` |
| `requiresShipping` / `shippingWeight` / `shippingWeightUnit` | `true` / `650.0` / `"GRAMS"` |
| `rating` / `reviewCount` | `4.5` / `244` |
| `ratingBreakdown` \* | `{"1": 12, "2": 5, "3": 6, "4": 24, "5": 168}` |
| `reviews` \* | see below |
| `reviewsAvailable` \* | `true` |
| `description` . / `descriptionHtml` . | full product copy |
| `materials` . | `"Cotton"` |
| `measurements` . / `dimensions` . | `"Approx. dia. 8 cm x H14 cm"` |
| `careInstructions` . | `"Machine washable"` |
| `countryOfOrigin` . | `"Japan"` |
| `features` . / `scents` . / `productSeries` . | `["Long Sleeve"]` |
| `attributes` | every extra attribute the storefront carries, verbatim |
| `seoTitle` . / `seoDescription` . | page metadata |
| `createdAt` / `updatedAt` / `publishedAt` | ISO timestamps |
| `source` / `sourceRef` | `"search"` / `"aroma diffuser"` |
| `scrapedAt` | `"2026-01-01T00:00:00Z"` |
| `changeType` / `changedFields` / `firstSeenAt` / `lastSeenAt` | incremental mode only |

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

```json
{
  "productId": "0000000000001",
  "title": "Sample Product Name",
  "url": "https://www.muji.us/products/sample-product-handle",
  "country": "us",
  "countryName": "United States",
  "currency": "USD",
  "brand": "MUJI",
  "category": "Aroma Diffusers",
  "productCategory": "Diffusers",
  "breadcrumb": ["Home", "Health & Beauty", "Aroma & Fragrances"],
  "price": 74.99,
  "originalPrice": 89.9,
  "discountAmount": 14.91,
  "discountPercent": 16.6,
  "onSale": true,
  "inStock": true,
  "variantCount": 2,
  "inStockVariantCount": 1,
  "sizes": ["S", "L"],
  "colors": ["Black", "White"],
  "variants": [
    {
      "variantId": "0000000000002",
      "sku": "0000000000000",
      "title": "S / Black",
      "price": 74.99,
      "originalPrice": 89.9,
      "currency": "USD",
      "available": true,
      "backorder": false,
      "requiresShipping": true,
      "weight": 650.0,
      "weightUnit": "GRAMS",
      "options": { "Size": "S", "Colour": "Black" },
      "image": null
    }
  ],
  "featuredImage": "https://example.com/images/00000000.jpg",
  "images": ["https://example.com/images/00000000.jpg"],
  "thumbnails": ["https://example.com/images/00000000.jpg?width=300"],
  "videos": [],
  "rating": 4.5,
  "reviewCount": 244,
  "ratingBreakdown": { "1": 12, "2": 5, "3": 6, "4": 24, "5": 168 },
  "reviews": [
    {
      "reviewId": "000000001",
      "rating": 5.0,
      "title": "Sample review title",
      "body": "Sample review text appears here.",
      "author": "Reviewer Name",
      "date": "2026-01-01T00:00:00.000Z",
      "verifiedBuyer": true,
      "helpfulVotes": 0,
      "unhelpfulVotes": 0,
      "language": "en",
      "images": []
    }
  ],
  "reviewsAvailable": true,
  "description": "Full product description appears here when fetchDetails is on.",
  "materials": "Cotton",
  "measurements": "Approx. dia. 8 cm x H14 cm",
  "careInstructions": "Machine washable",
  "countryOfOrigin": "Japan",
  "attributes": { "custom.purposes": ["Long Sleeve"] },
  "source": "search",
  "sourceRef": "aroma diffuser",
  "scrapedAt": "2026-01-01T00:00:00Z"
}
```

### Reviews

The average rating and the review count come from the product record itself, so they are
returned on every storefront, with or without `fetchReviews`.

Individual reviews and the per-star breakdown are only returned where the storefront publishes
them. On the United States and Canada storefronts they are, and `fetchReviews` returns them.
The Australian storefront publishes no individual reviews, so a product there comes back with
`reviews: []` and `reviewsAvailable: false`, keeping its rating and review count. No review
rows are ever invented for a product that has none: an unreviewed product returns an empty list
with `rating` and `reviewCount` left as the storefront reports them.

### Resume and recurring updates

Two separate features, for two separate jobs.

**Resume from a previous run** continues ONE interrupted crawl. Paste that run's ID (or its
dataset ID) into `resumeFromRunId` and the new run skips every product the old one already
returned, so nothing is collected or billed twice.

**Incremental mode** is for running the same search again and again, for example on a daily
schedule. Turn on `incrementalMode` and the actor remembers the previous run of that same search
itself. The first run returns everything as `NEW`. After that it returns only what changed:

| `changeType` | Meaning |
|---|---|
| `NEW` | First time this product has been seen for this search. |
| `UPDATED` | Something changed. `changedFields` names exactly what. |
| `REAPPEARED` | Back after having disappeared. |
| `UNCHANGED` | Nothing changed. Suppressed unless `emitUnchanged` is on. |
| `EXPIRED` | No longer found. Only with `emitExpired` on. |

`emitUnchanged` and `emitExpired` are off by default because both return, and bill, extra rows.
`EXPIRED` is only produced when the run fully scanned the tracked search: a run stopped by
`maxItems`, a resumed run, or a run that could not read every page never marks anything expired.

State is kept per search: the storefront, the keywords or links and every filter go into the
key, so two different searches never mix. Set `stateKey` to name a campaign or to deliberately
share state between runs.

### Billing

Charged per product returned, plus one detail-enrichment event per product for which details or
reviews were collected. A run with `fetchDetails` and `fetchReviews` both off is charged per
result only. Suppressed rows in incremental mode are not charged, even though their details were
read to work out that nothing changed.

### Connection

Apify Proxy is used by default and the default setting works on every plan, so there is no reason
to change it for MUJI. If no Apify Proxy connection is available at all, the run continues on its
own address and says so in the log.

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

Optionally pipe results into the apps you already use. Authorize a connector under Apify,
Settings, API & Integrations, then select it in `mcpConnectors`. For Notion, also set
`notionParentPageUrl` and each product becomes a page under it. Other connectors get a
best-effort write or a digest.

Each connector receives a condensed, human-readable summary per product: a title plus the key
fields flattened to plain text, with nested objects collapsed to their main value and long lists
trimmed. The complete record always stays in the Apify dataset. `maxNotifyListings` caps how many
products are written per connector and never affects the dataset.

### Notes

- A run that could not read any results ends as a failure with a connection message, never as a
  silent empty result. A search that genuinely matches nothing succeeds with zero rows and says
  so instead.
- Colour, size and category values differ between country storefronts. The storefront's own
  filter values are read at run time, so capitalisation and spelling are matched for you, and a
  value a storefront does not offer simply returns nothing rather than everything.
- Name and newest ordering are applied by MUJI itself on a category or search link. On a keyword
  search MUJI offers only relevance and price ordering, so name and newest are applied over the
  products the run collects, and best selling falls back to relevance and says so in the log.

# Actor input Schema

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

Choose 'search' for keywords plus filters, or 'url' to scrape pasted MUJI links. Each mode reads only its own field below.

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

Only used when mode = search, ignored in URL mode. One or more keywords, for example 'aroma diffuser' or 'oxford shirt'.

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

Only used when mode = url, ignored in search mode. Product links under /products/, category links under /collections/ and search links under /search?q= are all accepted. A category or search link that already carries page=N starts at that page rather than at page 1.

## `country` (type: `string`):

Which MUJI storefront to read. Each one has its own catalogue, its own prices in its own currency and its own stock. In URL mode this is only the fallback: a pasted link's own address decides its country. MUJI Japan and MUJI Europe run on separate platforms and are not covered here.

## `category` (type: `string`):

Optional. Keep only products in this catalogue category, exactly as MUJI names it, for example 'Aroma Diffusers', 'Ballpoint Pens' or 'Shirts'. Category names differ between country storefronts.

## `color` (type: `string`):

Optional. Keep only products offered in this colour, for example 'Navy' or 'Off White'. The storefront's own colour list is read at run time, so spelling and capitalisation are matched for you.

## `size` (type: `string`):

Optional. Keep only products offered in this size, for example 'M', 'L' or 'A4'. The storefront's own size list is read at run time, so spelling and capitalisation are matched for you.

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

Optional. Only keep products whose current price is at or above this amount, in the storefront's own currency.

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

Optional. Only keep products whose current price is at or below this amount, in the storefront's own currency.

## `inStockOnly` (type: `boolean`):

Optional. Keep only products that can be bought right now. Sold-out products are returned by default so you can track them.

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

How to order results. Relevance and price are ordered by MUJI itself. A category or search link can also order by name, newest and best selling; a keyword search cannot, so for a keyword search name and newest are applied over the products the run collects, and best selling falls back to relevance.

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

Collect each product's full description, category breadcrumb, extra images and videos, materials, measurements, care notes and country of origin. Turn off for a lighter run that returns only the listing-level fields. A pasted product link always returns full detail, because there is no listing card behind it.

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

Also collect individual customer reviews for each product: rating, title, text, author, date, verified-buyer flag, helpful votes and review photos, plus the per-star breakdown. The average rating and review count are always returned without this. Not every MUJI country publishes individual reviews; where none are published, reviews come back as an empty list and reviewsAvailable is false.

## `maxReviewsPerProduct` (type: `integer`):

Cap on how many individual reviews are collected for each product when 'Fetch customer reviews' is on. Newest first.

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

Maximum number of products to return across the whole run. This is the run's cap. Use 0 for unlimited.

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

Maximum number of result pages to take per keyword or link. 0 = unlimited; the run then stops only at Max products, or when there are no more results.

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

Paste a previous run ID or dataset ID to continue a large catalogue pull without returning or charging for products already collected there. Use this after an interrupted run. For recurring monitoring of the same search, use Incremental mode below instead.

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

Turn this on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED products. Turn on 'Emit unchanged' or 'Emit expired' only when you also want those rows returned (and billed). State is kept separately for each storefront, 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 a previous run 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 derive a key automatically from the storefront, search and filter settings, so two different searches never mix state.

## `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 a 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, never when Max products capped it or Resume was used. This returns, and bills, extra rows, so leave it off unless you need expiry tracking.

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

Connection used for every request. The default setting is recommended and works on every plan.

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

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a page per product; other connectors get a best-effort write or digest. Each connector receives a condensed summary per product, not the full record; the complete record always stays in the dataset. Leave empty to skip; this never changes the dataset output. 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": [
    "aroma diffuser"
  ],
  "urls": [
    "https://www.muji.us/collections/aroma-fragrances",
    "https://www.muji.us/products/ultrasonic-aroma-diffuser"
  ],
  "country": "us",
  "inStockOnly": false,
  "sortBy": "relevance",
  "fetchDetails": true,
  "fetchReviews": false,
  "maxReviewsPerProduct": 20,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (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": [
        "aroma diffuser"
    ],
    "urls": [
        "https://www.muji.us/collections/aroma-fragrances",
        "https://www.muji.us/products/ultrasonic-aroma-diffuser"
    ],
    "country": "us",
    "inStockOnly": false,
    "fetchDetails": true,
    "fetchReviews": false,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/muji-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": ["aroma diffuser"],
    "urls": [
        "https://www.muji.us/collections/aroma-fragrances",
        "https://www.muji.us/products/ultrasonic-aroma-diffuser",
    ],
    "country": "us",
    "inStockOnly": False,
    "fetchDetails": True,
    "fetchReviews": False,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/muji-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": [
    "aroma diffuser"
  ],
  "urls": [
    "https://www.muji.us/collections/aroma-fragrances",
    "https://www.muji.us/products/ultrasonic-aroma-diffuser"
  ],
  "country": "us",
  "inStockOnly": false,
  "fetchDetails": true,
  "fetchReviews": false,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/muji-scraper --silent --output-dataset

```

## MCP server setup

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