Mercari Japan Listings Scraper — Bulk Item Data avatar

Mercari Japan Listings Scraper — Bulk Item Data

Pricing

$1.50 / 1,000 listing returneds

Go to Apify Store
Mercari Japan Listings Scraper — Bulk Item Data

Mercari Japan Listings Scraper — Bulk Item Data

Export up to 2,000 Mercari Japan item rows per keyword: title, JPY price, status, condition, timestamps and URLs. Choose on_sale or sold_out explicitly; default both is unfiltered. $0.0015 per delivered item, no keyword fee. Sold-out labels do not verify payment. Unofficial.

Pricing

$1.50 / 1,000 listing returneds

Rating

0.0

(0)

Developer

h ichi

h ichi

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

What it does: Exports Mercari Japan live or sold-out search listings as item rows. Use this listings scraper for inventory research and recurring imports.

You enter: Keywords, e.g. Nikon Z6 ボディ; status; rows per keyword (100, up to 2,000); JPY price band.

You get: One row per item: ID, title, JPY price, source status, condition, category, shipping payer, shop flag, listing/update times, thumbnail, URL, seller ID and public profile URL. Seller names and ratings are not returned.

Price: $0.0015 per delivered listing, with no keyword fee. Duplicate IDs within a run are dropped across pages and keywords, and are not charged again. A later run can return and charge the same item again. No delivered listing means no listing fee.

Example: Use keywords: ["Nikon Z6 ボディ"], status: "on_sale" and maxListings: 100 for an inventory snapshot. Up to 100 delivered rows cost $0.15 in listing events; save the run ID with your export for the next comparison.

Unofficial — not affiliated with Mercari. Reads public pages only.

Choose the product for your job

Use this Actor for up to 2,000 raw search-result rows per keyword, with JPY price bounds and a source-status selector. $0.0015 per delivered listing; no keyword fee. Choose sold_out explicitly for sold-out results: default both sends no status filter and can return mostly live listings. The source's sold-out search can include trading rows; each row retains its actual status, so it is not proof that every transaction is completed.

For ready-made medians and a price range, use Mercari Japan Price Summary — Sold Out & Live. It samples up to 600 priced rows and offers summary-only (default), up to 10 representative evidence rows, or all sampled evidence. Summary is $0.02 per keyword/status; optional evidence is $0.002 per returned row. Use the bulk product for the 2,000-row export.

What you get

Measured on 2026-08-10 (real run)

{
"type": "listing",
"keyword": "Nikon Z6",
"id": "m81496913924",
"title": "Nikon Z6 ボディ ミラーレス一眼",
"priceJpy": 89000,
"hasPrice": true,
"status": "on_sale",
"conditionId": 3,
"condition": "no visible damage",
"categoryId": 4006,
"shippingPayerId": 2,
"shippingPayer": "seller",
"shippingMethodId": 14,
"isShopListing": false,
"listedAt": "2026-08-06T11:23:07+00:00",
"updatedAt": "2026-08-09T01:58:00+00:00",
"url": "https://jp.mercari.com/item/m81496913924",
"thumbnail": "https://static.mercdn.net/thumb/item/webp/m81496913924_1.jpg?1786015387",
"sellerId": "988826847",
"sellerUrl": "https://jp.mercari.com/user/profile/988826847"
}
fieldmeaning
priceJpy / hasPriceasking price in yen. Mercari encodes "no price" as ¥9,999,999; that becomes null with hasPrice: false, never a nine-million-yen listing
statuson_sale, sold_out or trading — as reported per listing
condition / conditionIdMercari's six condition grades, named
shippingPayerseller (送料込み) or buyer (着払い); null when Mercari reports neither
isShopListingwhether this is a Mercari Shops listing rather than an individual one
listedAtwhen the listing was created, in UTC
updatedAtthe last change to the listing — see the note below
urla link that resolves for both listing types
sellerId / sellerUrlthe seller's id and public profile page, as shown on Mercari's search result. No name or rating — Mercari's search layer does not publish them

When a search term returns nothing

A search term that delivers no listing leaves one free search_summary row instead, so a run over several terms shows you which one was empty rather than nothing at all. It is never charged — you pay per listing delivered, and this is not a listing.

{
"type": "search_summary",
"keyword": "zzzqqxnotarealproduct",
"totalFound": 0,
"pushed": 0,
"duplicatesDropped": 0,
"keywordStatus": "not_found",
"hint": "No listing matches this spelling. Try the Japanese name (camera -> カメラ) or another way of writing the model number (α7 IV / ILCE-7M4).",
"checkedAt": "2026-08-18T00:00:00+00:00"
}

Example values (shape only — the keyword and its 0 are measured 2026-08-18, the timestamp is illustrative)

keywordStatus is not_found when Mercari has nothing under that spelling, duplicates_only when every listing had already been delivered for an earlier search term in the same run, and unknown when Mercari reports listings but returned none of them.

Input

{
"keywords": ["Nikon Z6", "Nikon Z6 ボディ"],
"status": "both",
"maxListings": 60
}
inputnotes
keywordsone search per term; results are merged and de-duplicated across all of them
statuson_sale, sold_out, or both. both sends no filter, which is what Mercari's own search bar does — in practice that returns an almost entirely live book (measured 2026-08-18: Nikon Z6 with both gave 100 live listings out of 100), so ask for sold_out explicitly if you want sold listings
maxListingsper search term, 10–2000
priceMinJpy / priceMaxJpypushed to Mercari, so your page budget is spent on listings you want

Listings are returned in Mercari's own relevance order — the order the site's search bar gives you.

Repeat a search without duplicating your database

A repeat run is a fresh search, with the same per-delivered-row charge even when you received an item before. This is useful for price observations and inventory watchlists; it is not an incremental feed.

  • Use id as the item key in your database and save each observation with its run ID. Duplicate IDs are removed across pages and keywords within one run; the first matching keyword labels the delivered row, so that label is not a complete list of matching keywords. A later run can return and charge the same ID again. Relisting with a new ID is a separate record.
  • Each term returns a bounded slice of Mercari's relevance order, up to maxListings; overlapping terms can deliver fewer unique rows after deduplication. There is no "changed since" cursor or guarantee of full-market coverage. both is an unfiltered search, not an equal allocation between live and sold items. Use a separate saved Task with sold_out for sold observations and inspect each row's actual status; trading must not be relabelled sold_out.
  • Compare only observations from the same search settings. A new ID means newly observed in your results, not necessarily newly listed. An absent ID can have moved beyond your page budget, outside a price band, out of the keyword match, or into an unavailable search. Do not turn absence into "sold", deletion, or a zero price.
  • listedAt and updatedAt are source timestamps; updatedAt is not a sale time. Listing rows have no checkedAt; store the run's startedAt and finishedAt as the collection interval. Only a free search_summary row has its own checkedAt.
  • A multi-keyword run can succeed when one keyword fails. Read the run log for failed searches; SUCCEEDED alone is not proof of complete coverage. Free search_summary rows describe searches, not items: filter type == "listing" for your item table and inspect notices separately. duplicates_only means an earlier keyword in that run already delivered the IDs; it does not mean the market is empty.

Save the search and collect the next snapshot

  1. Save a Task in Apify Console with your keywords, status, price band and maxListings. Use the same Task for each comparison; create a separate Task when the search scope changes. Set a run cost cap and a schedule that matches your business needs.
  2. Run that Task again manually, from a schedule, or through the Task API. This request uses the saved input and starts one billable run; read its data.id as the run ID:
# Set APIFY_TOKEN in your environment and replace YOUR_TASK_ID.
curl --fail --silent --show-error --request POST \
"https://api.apify.com/v2/actor-tasks/YOUR_TASK_ID/runs" \
--header "Authorization: Bearer $APIFY_TOKEN" \
--header 'Content-Type: application/json' --data '{}'
  1. After it finishes, import the completed run. Save the Python example below as ingest_run.py; it uses only the standard library.
python3 ingest_run.py FIRST_RUN_ID snapshots.sqlite
python3 ingest_run.py NEXT_RUN_ID snapshots.sqlite

The example only reads an existing run and its dataset pages; it never starts a run. It accepts this Actor's SUCCEEDED runs, groups observations by listing id, and keeps both a run history (observations) and the most recently completed run that saw each ID (latest). Importing the same run twice adds no duplicate observations, and importing an older run cannot overwrite a newer one. A missing ID leaves the previous observation intact. The local database stores IDs, market prices/status/times and run metadata; it omits seller data and search text.

For example, query changes to IDs present in both runs (replace the two run IDs):

SELECT b.id, a.values_json AS previous, b.values_json AS current
FROM observations AS a JOIN observations AS b
ON a.actor_id = b.actor_id AND a.id = b.id
WHERE a.run_id = 'FIRST_RUN_ID' AND b.run_id = 'NEXT_RUN_ID'
AND a.values_json <> b.values_json;

Use a separate database for each saved Task/search scope. latest means last observed in a completed run, so check its run_id and finished_at before using an old price. This example is customer-side storage; the Actor itself keeps no state between runs.

Three things this Actor is honest about

Who is selling is emitted — but only what the search page shows. Each row has sellerId and sellerUrl (the public profile page), straight from Mercari's search response. Mercari's search layer publishes no seller name or rating, so those fields are absent rather than guessed at — filling them would take one extra request per listing, which this price cannot fund.

updatedAt is not a sale time. Mercari's search API offers no sold-date sort and returns no sale timestamp. updated is simply the last time the listing changed — a price edit, a re-list, or the sale. Any Actor presenting it as "when it sold" is guessing. We name it updatedAt and leave it at that.

Mercari Shops links. Mercari Shops (ITEM_TYPE_BEYOND) results can appear alongside ordinary items, and their pages use a different URL path from jp.mercari.com/item/{id} — they live at jp.mercari.com/shops/product/{id}. This Actor picks the right one per listing, so url uses the appropriate ordinary-item or Shops path; availability can change after collection.

Two fields you may expect and will not find: brand and favourite count. Mercari's search response carries neither (itemBrand came back null on every one of 352 results across three keywords, including two brand searches). They exist only on the per-listing detail endpoint, which costs one extra request per row — a trade that does not fit a $0.0015 listing, and we would rather omit a column than ship one full of nulls.

Pricing

$0.0015 per listing delivered, flat.

  • You pay per listing returned; there is no per-keyword fee and no monthly fee.
  • The same rate on every plan.
  • Within each run, repeated listings are dropped by listing id across pages and across your search terms, and you are charged only for the rows you actually get. Overlapping search terms cost you nothing extra in that run; a later run can deliver and charge the same listing again.

Read-only public data, no login, throttled requests (1.5s between pages), no browser, 256 MB. Nothing is stored between runs.

A whole list in one run

keywords takes as many search terms as you like; rows are de-duplicated across terms and you pay only for the rows you get.

Measured on 2026-08-21 (real run): 5 camera terms at 200 rows each → 868 listings in 29 seconds, $1.302.

Two limits for big pulls: the run's default time limit is 300 seconds (the run above used a tenth of it), and the platform stops a run when it reaches its Maximum cost per run setting (default $3.00 = 2,000 rows). Both can be raised in the run options — or split the terms across runs.

Use with AI agents

Connect to the Apify MCP server and identify this tool as jpmarketdata/mercari-japan-listings. Use an explicit status and row budget:

Use jpmarketdata/mercari-japan-listings to export Mercari Japan live listings for Nikon Z6 camera bodies. Run with keywords: ["Nikon Z6 ボディ"], status: "on_sale", maxListings: 100, priceMinJpy: 50000 and priceMaxJpy: 150000. Return item IDs, titles, JPY prices, source status, condition, update times and URLs. Keep only type: "listing" in the item table and show any search_summary notices separately. Explain that results are a bounded search snapshot; do not infer sales from missing items. Do not repeat the run unless I ask.

At $0.0015 per delivered listing, this example costs at most $0.15 in listing events, before trial credits and any applicable Apify platform charges. Choose status: "sold_out" for sold-out-labelled search results; the source labels do not verify payment.

FAQ

How do I scrape Mercari Japan sold listings?

Use status: "sold_out" explicitly with your keyword and maxListings limit. The default both sends no status filter and can return mostly live listings. Returned status values preserve the source label, including trading; sold-out search results do not independently verify payment or completed transactions.

Can I export Mercari Japan listings to CSV or JSON?

Yes. Start a run in Apify Console or with Apify API, then export the run's dataset as JSON or CSV. This Actor returns up to 2,000 search rows per keyword and charges $0.0015 per delivered item. It returns item rows rather than calculated medians; use Mercari Japan Price Summary — Sold Out & Live for the price statistics.

Does Mercari provide sale dates, brand names or seller ratings here?

This Actor preserves the public fields exposed by search results. updatedAt is the last listing update, not a sale date. Brand, favourite count, seller name and seller rating are not included. sellerId and sellerUrl identify the public seller profile; no additional profile requests are made.

Does an item disappearing from a repeat search mean it sold?

No. Each run reads a bounded relevance-ordered search sample. A missing ID may have moved outside your page budget, keyword or price band. Save observations by item id and run ID; retain the last observed row without relabelling an absent item as sold. Repeated runs can deliver and charge previously seen items again.

If something goes wrong

  • Wrong number or a failed run? Open a ticket on the Issues tab. I read every one and reply within 2 business days (Japan time).
  • Source failures are reported. Read run logs and partial-result warnings; a successful run can contain fewer completed searches than requested. An acquisition failure is not proof of zero market matches.
  • No results = no charge. You only pay for results you actually get.
  • Checked every week. An automatic test runs this tool weekly; if the site changes, I fix it.
  • Public pages only. No login. Only seller IDs and public profile attributes exposed by search are included; no extra seller-profile requests.

More tools by the same author

All tools (Japan marketplaces, real estate, jobs, racing, prediction markets): https://apify.com/jpmarketdata

Disclaimer

Unofficial, independent tool — not affiliated with, endorsed by, or sponsored by Mercari. Product names and logos belong to their owners and only say where the data comes from. Data is read from public pages, for market research; check before you act on it.