# Mercari Japan Scraper – Listings & Sold Prices (メルカリ) (`tokyo-select-jp/mercari-search-scraper`) Actor

Scrape Mercari Japan (jp.mercari.com, メルカリ): search by keyword, category, brand, seller, price, condition and status — including SOLD items for price history. Normalized JSON (price JPY, size, condition rank, images), optional item details. No browser, no login. JP Data Works series.

- **URL**: https://apify.com/tokyo-select-jp/mercari-search-scraper.md
- **Developed by:** [JP Data Works](https://apify.com/tokyo-select-jp) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Mercari Japan Scraper – Listings & Sold Prices (メルカリ)

Scrape **Mercari Japan ([jp.mercari.com](https://jp.mercari.com/), メルカリ)** — Japan's largest C2C marketplace — by **keyword, category, brand, seller, price range, condition and status**, and get clean JSON / CSV: price in JPY, normalized size, condition rank, images, timestamps and, with `status: "sold"`, **sold listings for price history**. Optionally fetch each item's detail (description, shipping, seller ratings, attributes). **No browser, no login, no proxy needed** under normal use — the Actor talks to the same API the Mercari web app uses. Part of the **JP Data Works** series of Japanese marketplace scrapers (Trefac, KOMEHYO, Yahoo! Auctions …).

**Keywords:** Mercari scraper · メルカリ スクレイピング · Mercari Japan API · Mercari sold items / sold prices · Japanese secondhand market data · vintage clothing, sneakers, Pokémon cards, figures, cameras, watches · resale sourcing (eBay, Grailed, Depop, StockX) · price monitoring · new-listing alerts.

### What you get

One row per listing:

- `itemId`, `url`, `title`, `brand`, `brandId`, `categoryId`
- `priceJpy` (integer), `status` (`on_sale` | `trading` | `sold`), `soldAt` (sold / trading items: last update time)
- `sizeRaw` as written and `sizeNorm` / `size` normalized (`W32`, `L`, `JP3`, `26.5cm`, `FREE`)
- `conditionRank` 6 (新品、未使用) … 1 (全体的に状態が悪い), `conditionLabel`, Mercari's `conditionId`
- `itemType` (`mercari` C2C listing | `shops` Mercari Shops product), `shopName`, `sellerId`, `shippingPayerId`
- `imageUrl` (full size) and `imageUrls`, `createdAt`, `updatedAt`, `fetchedAt`, `keyword`, `search` (the resolved search parameters)

With **Enrich with item details** (C2C items):

- `description`, `categoryPath` (メンズ > パンツ > デニム/ジーンズ), `color`, `hashTags`, `attributes` (素材, 季節感 …)
- `shippingPayer`, `shippingMethod`, `shippingFromArea`, `shippingDuration`
- `likes`, `comments`, `seller` `{ id, name, numSellItems, ratingGood, ratingNormal, ratingBad }`, all photos, `detailFetchedAt`

#### Example item

```json
{
  "source": "mercari",
  "itemId": "m11111111111",
  "url": "https://jp.mercari.com/item/m11111111111",
  "title": "KAPITAL キャピタル センチュリーデニム 5P モンキーシスコ W32",
  "brand": "KAPITAL",
  "brandId": 9174,
  "priceJpy": 28000,
  "status": "sold",
  "sizeRaw": "W32",
  "sizeNorm": { "kind": "waist", "value": 32 },
  "size": "W32",
  "conditionRank": 4,
  "conditionLabel": "目立った傷や汚れなし",
  "conditionId": 3,
  "categoryId": 1191,
  "itemType": "mercari",
  "sellerId": "222",
  "shippingPayerId": 2,
  "imageUrl": "https://static.mercdn.net/item/detail/orig/photos/m11111111111_1.jpg",
  "imageUrls": ["https://static.mercdn.net/item/detail/orig/photos/m11111111111_1.jpg", "https://static.mercdn.net/item/detail/orig/photos/m11111111111_2.jpg"],
  "createdAt": "2026-09-21T13:33:20.000Z",
  "updatedAt": "2026-10-14T17:46:40.000Z",
  "soldAt": "2026-10-14T17:46:40.000Z",
  "fetchedAt": "2026-11-02T00:00:00.000Z",
  "keyword": "KAPITAL デニム",
  "search": { "label": "KAPITAL デニム sold newest", "keyword": "KAPITAL デニム", "status": "sold", "sort": "newest", "priceMinJpy": 5000, "priceMaxJpy": null, "conditionIds": [], "createdAfter": null, "clientSideFilters": [] }
}
```

Without enrichment the detail fields are `null` / `{}` / `[]`, so the dataset always has the same columns.

### Output modes — listings or a market summary

`outputMode` chooses what the dataset contains:

- **`items`** (default) — one row per listing, as above.
- **`summary`** — one **market-summary row per search** instead of the listings. The Actor still walks the search pages (up to `maxItemsPerSearch` listings, with `enrichDetail` if set), but stores only the aggregate — so a run that answers "what does X go for on Mercari?" costs one `summary` event per search rather than hundreds of result events.
- **`both`** — the listings plus the summary row.

A summary row (`recordType: "summary"`) has the same shape in every JP Data Works Actor, so you can put several sites side by side:

```json
{
  "recordType": "summary",
  "source": "mercari",
  "search": { "label": "…", "url": "…", "…": "the resolved search parameters" },
  "fetchedAt": "2026-11-02T03:00:00.000Z",
  "sampleSize": 180, "totalOnSite": 1243, "scanned": 190, "filteredOut": 10, "withDetail": 0,
  "status": { "on_sale": 180, "sold": 0, "unknown": 0 },
  "price": { "count": 180, "min": 3300, "p25": 9800, "median": 16500, "mean": 19840, "p75": 25300, "max": 128000, "stddev": 15210 },
  "priceOnSale": { "…": "same statistics for on-sale listings" }, "priceSold": { "…": "and for sold ones (sites that list them)" },
  "priceHistogram": { "bucketJpy": 10000, "buckets": [ { "fromJpy": 0, "toJpy": 10000, "count": 46 }, "…" ] },
  "conditionRank": { "6": 12, "5": 40, "4": 71, "3": 30, "unknown": 27 }, "conditionLabels": { "…": "the site's own labels" },
  "sizes": { "M": 48, "L": 41, "W32": 12, "…": 0 }, "sizeKinds": { "alpha": 120, "waist": 30, "numeric": 20, "unknown": 10 },
  "brands": { "KAPITAL": 180 }, "categories": { "メンズ > ジャケット/アウター": 95, "…": 0 }, "gender": { "mens": 170, "unknown": 10 },
  "listed": { "last24h": 9, "last7d": 41, "last30d": 120 }, "sold": null,
  "cheapest": [ { "itemId": "…", "title": "…", "url": "…", "priceJpy": 3300, "conditionRank": 4, "size": "M", "status": "on_sale" }, "…" ],
  "cheapestGoodCondition": [ "… cheapest with condition rank ≥ 4 …" ],
  "newest": [ "… most recently listed (sites that expose listing times) …" ]
}
```

Mercari exposes listing and sold times and lists sold items (`status: sold` / `all`), so the summary gives `priceOnSale` vs `priceSold`, `listed` (new listings in the last 24 h / 7 d / 30 d), `sold` (sales in the last 7 d / 30 d) and `newest` — the closest thing to a sell-through signal on a single run.

### Input

Two ways to describe what to search, which can be combined in one run:

- **`keywords`** — one search per keyword (`KAPITAL デニム`, `visvim`, `ポケモンカード リザードン` …).
- **`searches`** — structured: objects with any of `keyword`, `excludeKeyword`, `status`, `categoryId`, `brandId`, `sizeId`, `sellerId`, `priceMinJpy`, `priceMaxJpy`, `conditionMin` / `conditionIds`, `shippingPayer`, `sort`, `createdAfter`, `createdBefore`, `excludeWords`, `itemType`.

Top-level `status`, `sort`, `priceMinJpy`, `priceMaxJpy`, `conditionMin`, `createdAfter`, `excludeWords`, `itemType` are defaults for every keyword and search; a value inside a search wins.

| Field | Type | Default | Notes |
|---|---|---|---|
| `keywords` | string\[] | — | One search per keyword. Optional when `searches` is given. |
| `outputMode` | `items` | `summary` | `both` | `items` | Listings, one market-summary row per search, or both (see "Output modes"). |
| `searches` | object\[] | — | Structured searches (table below). Each needs a keyword, categoryId, brandId or sellerId. |
| `status` | `on_sale` | `sold` | `trading` | `all` | `on_sale` | `sold` = sold out + in trading → price history. |
| `sort` | `relevance` | `newest` | `priceAsc` | `priceDesc` | `likes` | `relevance` | |
| `priceMinJpy` / `priceMaxJpy` | integer | none | |
| `conditionMin` | 1–6 | none | 6 新品、未使用, 5 未使用に近い, 4 目立った傷や汚れなし, 3 やや傷や汚れあり, 2 傷や汚れあり. |
| `createdAfter` | ISO date / epoch | none | Only items listed after this. Schedule + `createdAfter` = incremental collection. |
| `excludeWords` | string\[] | `[]` | Client-side title filter (レプリカ, 偽物, ジャンク …). |
| `itemType` | `any` | `mercari` | `shops` | `any` | C2C listings only / Mercari Shops only. |
| `maxItemsPerSearch` | integer | 120 | Per keyword / search. 120 hits per API page. |
| `maxTotalItems` | integer | none | Hard cap per run. |
| `dedupeAcrossSearches` | boolean | true | |
| `enrichDetail` | boolean | false | One extra request + one `detail-page` event per C2C item. |
| `maxDetailPages` | integer | 100 | Cap on detail requests per run. |
| `requestDelayMs` | integer | 2000 | Minimum pause between requests (≥ 500). |
| `pageSize` | integer | 120 | Hits per API page (max 120). |
| `proxyConfiguration` | object | none | Optional Apify Proxy / own proxies. |
| `outputFields` | string\[] | all | Keep only these fields (`itemId`, `url` always kept). |

Fields of one `searches` entry (all optional):

| Field | Example | How it is applied |
|---|---|---|
| `keyword` / `excludeKeyword` | `"KAPITAL デニム"` / `"レプリカ"` | Site search / site exclude. |
| `status` | `"sold"` | `on_sale`, `sold` (sold out + trading), `trading`, `all`. |
| `categoryId` | `[1191]` | Mercari category id(s). Find them in the site URL after filtering (`category_id=`). |
| `brandId` | `[9174]` | Mercari brand id(s) (`brand_id=`). 9174 = KAPITAL. |
| `sizeId` | `[55]` | Mercari size id(s). |
| `sellerId` | `[123456]` | List one seller's items (user id from the profile URL). |
| `priceMinJpy` / `priceMaxJpy` | `5000` / `30000` | Site price filter, re-checked on the client. |
| `conditionMin` / `conditionIds` | `4` / `[1, 2, 3]` | Site condition filter; `conditionIds` are Mercari's ids 1 (new) … 6 (poor). |
| `shippingPayer` | `"seller"` | `seller` 送料込み, `buyer` 着払い, `any`. |
| `sort` | `"newest"` | `relevance` おすすめ順, `newest` 新しい順, `priceAsc`, `priceDesc`, `likes` いいね順. |
| `createdAfter` / `createdBefore` | `"2026-11-01"` | ISO date/time or epoch seconds. |
| `excludeWords` | `["レプリカ", "偽物"]` | **Client-side**: drop items whose title contains any of these. |
| `itemType` | `"mercari"` | **Client-side**: `mercari` C2C only, `shops` Mercari Shops only, `any`. |

#### Examples

Sold prices for one brand, last 30 days (price history / comps):

```json
{
  "searches": [{ "keyword": "KAPITAL デニム", "status": "sold", "priceMinJpy": 5000, "sort": "newest", "createdAfter": "2026-10-01" }],
  "maxItemsPerSearch": 240
}
```

New listings for a category under ¥20,000, run on a schedule (diff `itemId` against the previous run, or set `createdAfter` to the previous run time):

```json
{
  "searches": [{ "categoryId": [1191], "priceMaxJpy": 20000, "conditionMin": 4, "sort": "newest", "excludeWords": ["レプリカ", "偽物"] }],
  "maxItemsPerSearch": 120
}
```

Several keywords with details:

```json
{ "keywords": ["visvim FBT", "visvim Christo"], "status": "on_sale", "enrichDetail": true, "maxDetailPages": 50 }
```

Requests are sequential: one API call per 120 hits plus, with `enrichDetail`, one per item. 240 sold items without detail ≈ 2 requests ≈ 5 seconds; with detail ≈ 242 requests ≈ 8 minutes at the default delay.

### FAQ

**Can I get sold prices / price history?**
Yes — set `status: "sold"`. Mercari keeps sold listings searchable; each row has `priceJpy` and `soldAt` (the listing's last update, which is the sale or completion time). Use `createdAfter` and a schedule to collect new sales incrementally.

**Do I need a proxy or a browser?**
No. The Actor calls Mercari's public search API with the same request signature the web app generates (a per-session DPoP key), so it runs on Apify's datacenter IPs at the default 2-second delay. `proxyConfiguration` (e.g. Apify residential proxy, country JP) is there in case you see 403 / 429 at higher volumes.

**How are sizes and conditions normalized?**
`sizeRaw` keeps the tag text; `sizeNorm` interprets it (`waist` inches for `W32`, `alpha` for `S/M/L/LL→XL`, `numeric` for JP sizes, `cm` for shoes, `free`). `conditionRank` uses 6 = best … 1 = worst, the same scale as our Trefac and KOMEHYO scrapers, so results from several Actors can be merged; `conditionId` is Mercari's own 1 (new) … 6 (poor).

**Where do I find category / brand / size ids?**
Filter on jp.mercari.com and copy them from the URL: `category_id=1191`, `brand_id=9174`, `size_id=55`. A seller id is the number in a profile URL (`/user/profile/123456`).

**What about Mercari Shops?**
Products from Mercari Shops (business sellers) are returned with `itemType: "shops"`, `shopName` and the product URL. Item detail enrichment is only available for C2C listings (`itemType: "mercari"`); set `itemType: "mercari"` to exclude Shops products.

**Is this legal?**
The Actor collects publicly visible listing data only — no login, no personal data beyond the public seller name / ratings on the listing, no purchases or messages — at a polite rate and with a browser-like signature only so the public API accepts the request. How you use the data is your responsibility; respect Mercari's terms of use, keep runs small and scheduled, and do not republish photos or descriptions as your own.

**How do I call it from code or from an AI agent?**
Any Apify client works. With the JavaScript client:

```js
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor("tokyo-select-jp/mercari-search-scraper").call({
  searches: [{ keyword: "KAPITAL デニム", status: "sold", sort: "newest", priceMinJpy: 5000 }],
  maxItemsPerSearch: 120,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

or with plain HTTP (`run-sync-get-dataset-items` returns the results directly):

```
POST https://api.apify.com/v2/acts/tokyo-select-jp~mercari-search-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN
Content-Type: application/json

{ "keywords": ["visvim"], "status": "sold", "maxItemsPerSearch": 60 }
```

The Actor is also exposed through Apify's MCP server (`https://mcp.apify.com`), so Claude, ChatGPT, Cursor and other MCP-capable assistants can search Mercari by calling this Actor as a tool.

### Pricing (pay per event)

| Event | Charged when | Price |
|---|---|---|
| Result (`apify-default-dataset-item`, charged automatically by Apify) | one listing is saved to the dataset | $0.002 |
| Item detail (`detail-page`) | that listing was enriched with its detail | $0.005 (in addition to the result) |
| Market summary (`summary`) | one summary row is saved (outputMode `summary` / `both`) | $0.03 per search |
| Actor start (`apify-actor-start`) | each run starts | $0.00005 |

Example: 240 sold listings without detail = **$0.48**; 100 listings with detail = **$0.70**. A `summary`-only run over 3 searches ≈ 3 × $0.03 = **$0.09**, whatever the number of listings sampled.
Set **Max total charge** on the run to cap spending — the Actor stops cleanly at the limit and you keep everything collected so far.

### Roadmap — JP Data Works

Scrapers for Japanese secondhand and auction marketplaces with one normalized shape (`priceJpy`, `sizeNorm`, `conditionRank`, `imageUrls`) so results can be merged:

- **Trefac (トレファク)** — [published](https://apify.com/tokyo-select-jp/trefac-search-scraper)
- **Mercari (メルカリ)** — this Actor
- **KOMEHYO (コメ兵)**, **Yahoo! Auctions (ヤフオク!)** incl. sold listings, **2nd STREET**, **RAGTAG** — coming
- A cross-site aggregator (one query → all stores)

Requests and bug reports: the Issues tab of this Actor.

***

### 日本語

**メルカリ（jp.mercari.com）をキーワード・カテゴリ・ブランド・出品者・価格帯・コンディション・ステータス（販売中 / 売り切れ）で検索し、構造化された商品データを返す Actor です。** `status: "sold"` で **売り切れ商品（相場・価格履歴）** も取れます。ブラウザ不要・ログイン不要・通常はプロキシ不要（Web 版メルカリと同じ API を同じ署名方式で呼びます）。オプションで商品詳細（説明文・配送・出品者評価・属性）を付加します。

用途: 古着・スニーカー・トレカ・フィギュア・カメラ・時計の相場調査、eBay / Grailed 等への転売の仕入れリサーチ、新着監視、ブランド別の価格モニタリング。

#### 出力（1 商品 = 1 行）

- `itemId` / `url` / `title` / `brand` / `brandId` / `categoryId`
- `priceJpy`、`status`（`on_sale` 販売中 / `trading` 取引中 / `sold` 売り切れ）、`soldAt`（売り切れ・取引中のとき: 最終更新時刻 = 売れた時刻の近似）
- `sizeRaw`（表記そのまま）と `sizeNorm` / `size`（`W32`、`L`、`JP3`、`26.5cm`、`FREE`）
- `conditionRank`（6 新品、未使用 … 1 全体的に状態が悪い。他の JP Data Works Actor と同じ尺度）、`conditionLabel`、`conditionId`（メルカリの 1〜6）
- `itemType`（`mercari` 個人出品 / `shops` メルカリ Shops）、`shopName`、`sellerId`、`shippingPayerId`（2 送料込み / 1 着払い）
- `imageUrl` / `imageUrls`（フルサイズ）、`createdAt` / `updatedAt` / `fetchedAt`、`keyword`、`search`

**「商品詳細を付加」(enrichDetail) を ON にすると追加で**（個人出品のみ）: `description`、`categoryPath`、`color`、`hashTags`、`attributes`、`shippingPayer` / `shippingMethod` / `shippingFromArea` / `shippingDuration`、`likes`、`comments`、`seller`（名前・出品数・評価）、全写真。

#### 入力

`keywords`（キーワードだけ）と `searches`（構造化検索）を併用できます。トップレベルの `status` / `sort` / `priceMinJpy` / `priceMaxJpy` / `conditionMin` / `createdAfter` / `excludeWords` / `itemType` は全検索の既定値で、各検索内の指定が優先されます。

| 項目 | 既定 | 説明 |
|---|---|---|
| `keywords` | — | 検索キーワード（1 行 1 件）。`searches` があれば省略可 |
| `searches` | — | 構造化検索の配列（下表）。各要素にキーワード・categoryId・brandId・sellerId のいずれかが必要 |
| `status` | `on_sale` | `on_sale` 販売中 / `sold` 売り切れ + 取引中 / `trading` / `all` |
| `sort` | `relevance` | `relevance` おすすめ順 / `newest` 新しい順 / `priceAsc` / `priceDesc` / `likes` いいね順 |
| `priceMinJpy` / `priceMaxJpy` | なし | 価格帯 |
| `conditionMin` | なし | コンディション下限 1〜6（6 新品、未使用 … 2 傷や汚れあり） |
| `createdAfter` | なし | この日時以降に出品されたものだけ（ISO 日付 or epoch 秒）。スケジュール実行と組み合わせて差分取得 |
| `excludeWords` | `[]` | タイトルにこの語を含む商品を除外（クライアント側） |
| `itemType` | `any` | `mercari` 個人出品のみ / `shops` メルカリ Shops のみ |
| `maxItemsPerSearch` | 120 | 検索ごとの最大件数（API 1 ページ 120 件） |
| `maxTotalItems` | なし | 1 実行の上限 |
| `enrichDetail` | false | 商品詳細を取得（1 商品 +1 リクエスト） |
| `maxDetailPages` | 100 | 詳細取得の上限 |
| `requestDelayMs` | 2000 | リクエスト間隔（ms） |
| `proxyConfiguration` | なし | 403 / 429 が出る場合のみ Apify Proxy（Residential, JP）等を指定 |

`searches` の各要素: `keyword` / `excludeKeyword` / `status` / `categoryId` / `brandId` / `sizeId` / `sellerId`（配列）/ `priceMinJpy` / `priceMaxJpy` / `conditionMin` または `conditionIds`（メルカリの 1〜6）/ `shippingPayer`（`seller` 送料込み / `buyer` 着払い）/ `sort` / `createdAfter` / `createdBefore` / `excludeWords` / `itemType`。ID はサイトで絞り込んだときの URL（`category_id=1191`、`brand_id=9174`、`size_id=55`）から拾えます。

##### 入力例

ブランドの売り切れ相場（直近 1 か月）:

```json
{
  "searches": [{ "keyword": "KAPITAL デニム", "status": "sold", "priceMinJpy": 5000, "sort": "newest", "createdAfter": "2026-10-01" }],
  "maxItemsPerSearch": 240
}
```

カテゴリの新着監視（¥20,000 以下・状態良好・偽物語除外）:

```json
{
  "searches": [{ "categoryId": [1191], "priceMaxJpy": 20000, "conditionMin": 4, "sort": "newest", "excludeWords": ["レプリカ", "偽物"] }],
  "maxItemsPerSearch": 120
}
```

#### 料金（Pay per event）

| イベント | 課金タイミング | 価格 |
|---|---|---|
| 結果（`apify-default-dataset-item`、Apify が自動課金） | 商品 1 件をデータセットに保存したとき | $0.002 |
| 商品詳細（`detail-page`） | その商品の詳細を取得したとき（結果に加算） | $0.005 |
| 相場サマリー（`summary`） | `outputMode` が `summary` / `both` のとき、検索 1 件につきサマリー行 1 行 | $0.03 |
| Actor 起動（`apify-actor-start`） | 実行ごと | $0.00005 |

例: 売り切れ 240 件（詳細なし）≈ $0.48、100 件（詳細あり）≈ $0.70。「Max total charge」で上限を設定すると安全に停止し、それまでの結果は残ります。

#### 利用上の注意

- 取得するのは公開されている商品情報のみです（ログイン・購入・メッセージ等は一切行いません）。1 リクエストずつ、既定 2 秒間隔でアクセスします。
- データの利用はご自身の責任で、メルカリの利用規約を守り、過度なアクセスや画像・文章の無断転載はお控えください。

# Changelog

This Actor's version history is a separate document: https://apify.com/tokyo-select-jp/mercari-search-scraper/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

Simple keyword searches, one per line — brand names, item types, model numbers, Japanese or English (e.g. `KAPITAL デニム`, `visvim`, `ポケモンカード リザードン`). Each keyword is one search and inherits the defaults below. Optional when `searches` is set.

## `searches` (type: `array`):

Advanced searches as JSON objects. Every field is optional, but each search needs at least one of `keyword`, `categoryId`, `brandId`, `sellerId`.

- `keyword`, `excludeKeyword` — free text (the site's search box / exclude box).
- `status` — `on_sale` (default), `sold` (sold out + in trading = price history), `trading`, `all`.
- `categoryId`, `brandId`, `sizeId`, `sellerId` — lists of Mercari ids. Find them in the site's URL after filtering, e.g. `category_id=1191`, `brand_id=9174`.
- `priceMinJpy` / `priceMaxJpy` — price bounds in JPY.
- `conditionMin` — minimum condition rank 1–6 (6 = 新品、未使用 … 1 = 全体的に状態が悪い), or `conditionIds` — Mercari condition ids 1 (new) … 6 (poor).
- `shippingPayer` — `seller` (送料込み), `buyer` (着払い), `any`.
- `sort` — `relevance` (default), `newest`, `priceAsc`, `priceDesc`, `likes`.
- `createdAfter` / `createdBefore` — ISO date or epoch seconds; only items listed in that window.
- `excludeWords` — drop items whose title contains any of these (client-side).
- `itemType` — `any` (default), `mercari` (C2C listings only), `shops` (Mercari Shops products only).

Values set here override the defaults below.

## `outputMode` (type: `string`):

`items` (default): one dataset row per listing. `summary`: one market-summary row per search instead of the listings — sample size, price min / p25 / median / mean / p75 / max, price histogram, status / condition-rank / size / brand / category breakdowns, cheapest listings — billed once per search as the `summary` event (the sampled listings are not billed). `both`: listings plus the summary row.

## `status` (type: `string`):

Applied to every keyword / search without its own `status`. `sold` returns sold-out and in-trading items — use it for sold price history.

## `sort` (type: `string`):

Applied to every keyword / search without its own `sort`.

## `priceMinJpy` (type: `integer`):

Lower price bound for every search without its own `priceMinJpy`.

## `priceMaxJpy` (type: `integer`):

Upper price bound for every search without its own `priceMaxJpy`.

## `conditionMin` (type: `integer`):

Only listings with this condition rank or better: 6 新品、未使用, 5 未使用に近い, 4 目立った傷や汚れなし, 3 やや傷や汚れあり, 2 傷や汚れあり, 1 全体的に状態が悪い. Leave empty for all.

## `createdAfter` (type: `string`):

Only items listed after this date/time (ISO, e.g. 2026-11-01, or epoch seconds). Combine with a schedule to collect new listings or new sales incrementally.

## `excludeWords` (type: `array`):

Drop items whose title contains any of these words (case-insensitive), e.g. レプリカ, 偽物, ジャンク.

## `itemType` (type: `string`):

`mercari` = individual (C2C) listings only, `shops` = Mercari Shops products only, `any` = both.

## `maxItemsPerSearch` (type: `integer`):

Stop after this many listings for each keyword / search (up to 120 per API page).

## `maxTotalItems` (type: `integer`):

Hard cap on listings saved in this run across all searches. Leave empty for no cap (Max total charge still applies).

## `dedupeAcrossSearches` (type: `boolean`):

Save a listing only once when several searches return it.

## `enrichDetail` (type: `boolean`):

Fetch each C2C item's detail (description, category path, colour, shipping method / payer / origin / duration, likes, comments, seller ratings, attributes, all photos). One extra request and one `detail-page` event per item. Mercari Shops products are returned without detail.

## `maxDetailPages` (type: `integer`):

Cap on item detail requests per run. Items beyond the cap are returned without detail fields.

## `requestDelayMs` (type: `integer`):

Minimum pause between API requests. Keep ≥ 2000 to stay polite; raise it if you see rate limiting.

## `pageSize` (type: `integer`):

Hits per API page (max 120). Smaller pages = more requests.

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

Optional. Direct connections work under normal use; switch to Apify Proxy (residential, country JP) or your own proxy URLs if the API starts returning 403 / 429.

## `outputFields` (type: `array`):

Keep only these top-level fields in the output (`itemId` and `url` are always kept). Leave empty for all fields.

## Actor input object example

```json
{
  "keywords": [
    "KAPITAL デニム"
  ],
  "searches": [
    {
      "keyword": "KAPITAL デニム",
      "status": "sold",
      "priceMinJpy": 5000,
      "sort": "newest"
    }
  ],
  "outputMode": "items",
  "status": "on_sale",
  "sort": "relevance",
  "excludeWords": [],
  "itemType": "any",
  "maxItemsPerSearch": 120,
  "dedupeAcrossSearches": true,
  "enrichDetail": false,
  "maxDetailPages": 100,
  "requestDelayMs": 2000,
  "pageSize": 120,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "outputFields": []
}
```

# Actor output Schema

## `listings` (type: `string`):

All scraped items (default dataset)

# 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 = {
    "keywords": [
        "KAPITAL デニム"
    ],
    "searches": [
        {
            "keyword": "KAPITAL デニム",
            "status": "sold",
            "priceMinJpy": 5000,
            "sort": "newest"
        }
    ],
    "status": "on_sale",
    "sort": "relevance",
    "maxItemsPerSearch": 120,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tokyo-select-jp/mercari-search-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 = {
    "keywords": ["KAPITAL デニム"],
    "searches": [{
            "keyword": "KAPITAL デニム",
            "status": "sold",
            "priceMinJpy": 5000,
            "sort": "newest",
        }],
    "status": "on_sale",
    "sort": "relevance",
    "maxItemsPerSearch": 120,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("tokyo-select-jp/mercari-search-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 '{
  "keywords": [
    "KAPITAL デニム"
  ],
  "searches": [
    {
      "keyword": "KAPITAL デニム",
      "status": "sold",
      "priceMinJpy": 5000,
      "sort": "newest"
    }
  ],
  "status": "on_sale",
  "sort": "relevance",
  "maxItemsPerSearch": 120,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call tokyo-select-jp/mercari-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tokyo-select-jp/mercari-search-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/IU1XaTnXjKaAar1wn/builds/WAV3p31IMZTMhQCXs/openapi.json
