# Mercari Japan API scraper - keyword search and full item detail for jp.mercari.com, Japan's largest consumer-to-consumer resale marketplace. Live prices in JPY, sold-listing comparables, seller reputation, condition and category filters. No account, no browser.

> Search Mercari Japan by keyword and by any combination of category, brand, seller, price range, condition, colour, shipping terms and shipping prefecture, paginated. Every row carries the item id and url, the title, the price as a number in JPY, whether it is still on sale or already sold, the condition grade, the category id, the seller's id and profile url, the image, and when it was listed and last touched. Filter on `status: sold_out` to get the prices items actually sold at - the comparables a resale valuation is built from. Paginate by passing back the `next_page_token` from the previous response.
> ReefAPI engine `mercari` · 2 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/mercari/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed or blocked calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /mercari/v1/search — 1 credit
Search Mercari Japan by keyword and by any combination of category, brand, seller, price range, condition, colour, shipping terms and shipping prefecture, paginated. Every row carries the item id and url, the title, the price as a number in JPY, whether it is still on sale or already sold, the condition grade, the category id, the seller's id and profile url, the image, and when it was listed and last touched. Filter on `status: sold_out` to get the prices items actually sold at - the comparables a resale valuation is built from. Paginate by passing back the `next_page_token` from the previous response.

**Parameters:**
- `query` (string, optional) — Search keyword. Mercari's catalogue is Japanese, so Japanese terms return far more than English ones - though brand and model names in Latin script (iphone, nike, seiko) work well. Optional: a search with no keyword is valid as long as at least one of category_id, brand_id, seller_id or price_min is set, which is how you browse a category or a seller.
- `exclude` (string, optional) — Drop results matching this term. Mercari matches WORDS, not substrings: excluding 'Pro' removes 'iPhone 13 Pro' but keeps '(PRODUCT)RED'.
- `category_id` (string, optional) — Mercari category id, or several separated by commas. The id space is hierarchical and any LEVEL works: a leaf id (1731 = quartz wristwatches) returns just that leaf, while an ancestor id (39 = watches) returns everything beneath it. Every search row carries the leaf id of its own category under `category_id`, and `product/detail` returns the whole named path, which is how you discover ids - Mercari publishes no category directory endpoint.
- `brand_id` (string, optional) — Mercari brand id, or several separated by commas (3272 = Apple). Ids come from `product/detail`, which returns `brand{id, name}` for any listing the seller tagged with a brand.
- `seller_id` (string, optional) — Return only this seller's listings. The id is on every search row under `seller.id`. Works with no keyword, which makes it a seller-inventory feed.
- `price_min` (integer, optional) — Lowest price to include, in Japanese yen (whole yen, no decimals - Mercari prices are integers).
- `price_max` (integer, optional) — Highest price to include, in Japanese yen. A range with no listings in it returns an empty result, not an error.
- `condition` (enum, optional) — Item condition, Mercari's own six grades. Several may be given separated by commas. [one of: new, like_new, good, fair, worn, poor]
- `status` (enum, optional) — Listing state. `sold_out` is the useful one for pricing research: those rows carry the price the item ACTUALLY SOLD at, which is what a resale comparable is. Several may be given separated by commas; the default is Mercari's own mix of everything. [one of: on_sale, sold_out, trading]
- `shipping_payer` (enum, optional) — Who pays for shipping. `seller` means the listed price is the delivered price, which is the norm on Mercari. 🔴 Mercari Shops listings carry no shipping-payer value at all and are NOT removed by this filter - a `shipping_payer: buyer` page comes back part private listings that really do match and part Shops rows whose `shipping_payer` is null. Add `listing_type: c2c` for a strictly filtered set (measured 20/20 rather than 9/20). [one of: seller, buyer]
- `color` (enum, optional) — Colour family the seller tagged the item with. Several may be given separated by commas. Only listings the seller actually tagged are matched. [one of: black, white, grey, brown, red, pink, purple, blue, beige, green, yellow, orange]
- `shipping_from` (integer, optional) — Ship only from this Japanese prefecture, by its standard JIS number (1 Hokkaido, 13 Tokyo, 23 Aichi, 27 Osaka, 40 Fukuoka, 47 Okinawa). `product/detail` returns the prefecture name alongside its number.
- `listing_type` (enum, optional) — Restrict to private-individual listings (`c2c`) or to Mercari Shops business sellers (`shops`). The default mixes both, as Mercari does - measured 0-3 Shops rows in 60. [one of: c2c, shops]
- `sort` (enum, optional, default "relevance") — Result ordering. Only these five are published because only these five were measured to actually re-order Mercari's results - the site's remaining sort/direction combinations return the identical row order. [one of: relevance, newest, price_asc, price_desc, most_liked]
- `page_size` (integer, optional, default 20) — Rows per call, 1-120 (default 20). Mercari treats this as a hint and can return one or two either side of it, so read `count` rather than assuming. Above 120 its own answer stops making sense, which is why the ceiling is here.
- `page_token` (string, optional) — Continue a previous search: pass the `next_page_token` the last response returned. Tokens are Mercari's own and are not page numbers - do not construct one. A response with `next_page_token: null` is the end of the stream.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request that did not get through (1-8, default 3). Leave unchanged for typical use.

**Returns:** items[]{item_id, title, url, price (number, JPY), price_display (null - Mercari publishes no formatted price), currency, status, condition, condition_id, listing_type, category_id, category (null on a search row - use product/detail for the named path), brand{id, name}, size, seller{id, name (null on a search row), url, rating (null), rating_count (null), rating_scale (null)}, shop{id, name}, shipping_payer, rating (null - Mercari does not rate individual listings), review_count (null), rating_scale (null), image, thumbnail, listed_at, updated_at}, count, next_page_token, total_results, total_results_is_estimate (always true), total_results_capped_at, filters{}

**Example request body:**
```json
{
  "query": "ポケモンカード"
}
```

### POST /mercari/v1/product/detail — 1 credit
One Mercari Japan listing in full, by id or url: title, description, the price as a number in JPY, sale status, the condition grade with Mercari's own wording for it, the named category path, brand, colours, hashtags, the full photo gallery, the shipping terms (who pays, the method, the prefecture it ships from and the seller's stated handling days), the like and comment counts, and the SELLER - name, profile url, how many items they have listed, and their rating with the good/normal/bad breakdown behind it. Mercari Shops products are accepted too and return the smaller set of fields Mercari publishes for them, with everything else null.

**Parameters:**
- `item_id` (string, required) — Mercari item id, or the full listing url. Two kinds exist and both are accepted: a private listing (`m` followed by 11 digits, jp.mercari.com/item/m48713153498) and a Mercari Shops product (22 letters and digits, jp.mercari.com/shops/product/<id>). Every search row carries its own id and url.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a request that did not get through (1-8, default 3). Leave unchanged for typical use.

**Returns:** item{item_id, title, url, price (number, JPY), price_display (null), currency, status, condition, condition_id, condition_label, condition_description, listing_type, description, category_id, category{id, name, path[]}, brand{id, name}, colors[]{id, name}, hashtags[], seller{id, name, url, rating (number - Mercari's star score), rating_count, rating_scale (null - Mercari publishes no scale), rating_breakdown{good, normal, bad}, listings_count, is_official, quick_shipper, photo, member_since}, shop{}, shipping{payer, payer_label, method, from_area_id, from_area, handling_days_min, handling_days_max, anonymous}, rating (null - Mercari does not rate individual listings), review_count (null), rating_scale (null), like_count, comment_count, is_offerable, images[], image, thumbnail, listed_at, updated_at}

**Example request body:**
```json
{
  "item_id": "m36530816878"
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=mercari
- Human docs page: https://reefapi.com/docs/mercari
- Overview page: https://reefapi.com/mercari-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
