# Japan Sell-Through Rate — Sold vs Listed on Mercari & Yahoo (`jpmarketdata/japan-sell-through-rate`) Actor

Will it actually sell in Japan? The Mercari sell-through rate (sold vs listed), median days to sell, sell-through by price band, Yahoo! Auctions sales per day and the sold-vs-asking gap. Demand, not just price — for cross-border resellers, proxy buying and sourcing. From $0.02. 日本の中古の消化率を1コールで。

- **URL**: https://apify.com/jpmarketdata/japan-sell-through-rate.md
- **Developed by:** [h ichi](https://apify.com/jpmarketdata) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 sell-through summaries

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## Japan Sell-Through Rate — Sold vs Listed on Mercari & Yahoo

**Before "what is it worth", the question is "does it sell".** One call per keyword measures Japanese resale **demand**: what share of the listings have sold, how fast they sold, and what separates the prices that sold from the prices still sitting there.

| Market | What it can measure | Basis |
|---|---|---|
| [Mercari Japan](https://jp.mercari.com/) (メルカリ) | **Sell-through rate** — sold-out vs on-sale listings, days to sell, listing age, sell-through per price band | `stock_ratio` |
| [Yahoo! Auctions Japan](https://auctions.yahoo.co.jp/) (ヤフオク) | **Sales per day**, days since the last sale, realized prices, bid competition, instant-buy take rate | `sold_flow` |
| [PayPay Flea Market](https://paypayfleamarket.yahoo.co.jp/) (PayPayフリマ) | **Competing supply** — live listings and what they ask | `supply_only` |

### The one thing to read first: `demandBasis`

The three markets do **not** publish the same kind of evidence, so their headline numbers are **not interchangeable**:

- **`stock_ratio`** (Mercari) — a share of the current listing stock. Unit: a fraction.
- **`sold_flow`** (Yahoo! Auctions) — sales per day. Unit: 1/day.
- **`supply_only`** (PayPay) — no demand measurement at all.

A share and a rate-per-day cannot be averaged, so no field ever blends them. Every key in `demand` names the market it came from.

**Yahoo! Auctions cannot produce a sell-through rate, and this Actor does not pretend it can.** Yahoo's closed-auction index (`closedsearch`, 落札相場) serves auctions that **sold** — measured 2026-08-07 over 200 auctions across four unrelated keywords, the minimum bid count served was **1**. Ended-without-a-bid auctions are simply not indexed, so any "Yahoo sell-through rate" is 1.0 by construction. `sellThroughRate` is therefore `null` there, with the reason attached, and `soldPerDay` is used instead.

### What you get

```
demand.mercariSellThroughRate      0.5515      sold / (sold + on sale), from Mercari's own hit counts
demand.mercariRateBound            "exact"     exact | lower_bound | upper_bound | unknown
demand.mercariMedianDaysToSell     6           how fast the sold half moved
demand.mercariMedianListingAgeDays 6           how long the unsold half has been sitting
demand.mercariSoldMedianJpy        14250       the price that actually sells
demand.mercariOnSaleMedianJpy      8350        what live sellers are asking
demand.mercariAskPremiumPct        -41.4       ask vs realized
demand.yahooSoldPerDay             5.52        completed auctions per day
demand.yahooDaysSinceLastSale      0.76        staleness: nothing sold for N days = no demand
demand.yahooSoldAuctionsIndexed    1102        how many completed sales Yahoo has on file
demand.paypayLiveListings          589         supply you would compete with on a second platform
```

Plus, per market, the full distributions (`min / p25 / median / p75 / max / average`) for sold prices, asking prices, days to sell, listing age, bid counts and likes — and the price-band table below.

#### Sell-through by price band

Does the cheap end clear faster, or is it clogged with parts nobody wants? Measured for `象印 圧力IH炊飯器` on 2026-08-07:

| Band | Sold (sampled) | On sale (sampled) | Sell-through |
|---|---|---|---|
| ≤ ¥6,000 | 23 | 32 | **46.9%** |
| ¥6,000–¥11,000 | 18 | 30 | **42.5%** |
| ¥11,000–¥19,000 | 31 | 22 | **63.4%** |
| > ¥19,000 | 28 | 16 | **68.3%** |

Here the *expensive* bands clear better. Below ¥6,000 the keyword catches spare parts (内ブタ, 内鍋, 雑穀フィルター), damaged units ("内釜剥がれあり") and older non-pressure models — not the machine most buyers came for. That is also why `askPremiumPct` came out **negative**: the sold pool and the on-sale pool hold different products. The band table is the fix for that composition effect, and it is why this Actor has no price filter (see *Notes & limits*).

### Pricing — from $0.02 per keyword, no subscription

| Event | Price | When |
|---|---|---|
| Keyword analyzed | **$0.02** | Per keyword, whatever the number of markets |
| Individual listing | **$0.002** | Only if you enable **Include individual listings** |

A default run (1 keyword, 3 markets, summary only) costs **$0.02** and took **8.8 seconds** measured. Apify's **$5 monthly free credit covers about 250 keywords** at that rate. No subscription.

**A keyword is only charged when at least one market actually measured demand** — a sell-through rate, a sales-per-day figure, or a sold-vs-listed price gap. A run that could only count live listings measured *supply*, not demand, and is free.

### Input

| Field | Example | Notes |
|---|---|---|
| `keywords` | `["象印 圧力IH炊飯器"]` | Japanese matches far more listings. Narrow keywords give sharper rates. $0.02 each |
| `markets` | `["mercari","yahoo_auction","paypay_flea"]` | All three by default. The price per keyword does not change |
| `maxItemsPerMarket` | `100` | 30–300 sampled **per side**. Does not affect the headline rate or the listing counts |
| `includeIndividualItems` | `false` | Enable to also get every sampled listing, +$0.002 each |
| `convertToUsd` | `true` | Adds USD stats at the current rate (one FX lookup per run) |

### Output example (`type: "sell_through_summary"`, abridged, measured 2026-08-07)

```json
{
  "type": "sell_through_summary",
  "keyword": "象印 圧力IH炊飯器",
  "demand": {
    "mercariSellThroughRate": 0.5515, "mercariSellThroughPct": 55.1,
    "mercariRateBound": "exact",
    "mercariSoldListings": 2274, "mercariOnSaleListings": 1849,
    "mercariMedianDaysToSell": 6, "mercariMedianListingAgeDays": 6,
    "mercariSoldMedianJpy": 14250, "mercariOnSaleMedianJpy": 8350,
    "mercariAskPremiumPct": -41.4,
    "yahooSoldPerDay": 5.52, "yahooSoldAuctionsIndexed": 1102,
    "yahooDaysSinceLastSale": 0.76, "yahooSoldMedianJpy": 6708,
    "yahooMedianBids": 6,
    "paypayLiveListings": 589, "paypayAskMedianJpy": 12675,
    "note": "mercariSellThroughRate is a share of listing stock and yahooSoldPerDay is a flow per day — different units, never average them."
  },
  "markets": {
    "mercari": {
      "demandBasis": "stock_ratio",
      "soldListings": 2274, "onSaleListings": 1849,
      "sellThroughRate": 0.5515, "rateBound": "exact",
      "countsCapped": {"sold": false, "onSale": false},
      "soldPriceJpy":   {"min": 2900, "p25": 7375, "median": 14250, "p75": 20500, "max": 67999, "average": 16757},
      "onSalePriceJpy": {"min": 500,  "p25": 5500, "median": 8350,  "p75": 14999, "max": 97900, "average": 11774},
      "priceGap": {"soldMedianJpy": 14250, "onSaleMedianJpy": 8350, "askPremiumJpy": -5900, "askPremiumPct": -41.4,
                   "sellingBandJpy": {"p25": 7375, "median": 14250, "p75": 20500},
                   "unsoldSide": "open_ask"},
      "speed": {"medianDaysToSell": 6, "soldWithinDays": 7, "soldWithinDaysPct": 57.0,
                "daysToSell": {"p25": 3, "median": 6, "p75": 14, "max": 262},
                "medianListingAgeDays": 6, "olderThan30DaysPct": 17.0},
      "priceBands": [
        {"label": "≤ ¥6,000", "soldSampled": 23, "onSaleSampled": 32, "sellThroughPct": 46.9, "basis": "sampled_scaled"},
        {"label": "> ¥19,000", "soldSampled": 28, "onSaleSampled": 16, "sellThroughPct": 68.3, "basis": "sampled_scaled"}
      ]
    },
    "yahoo_auction": {
      "demandBasis": "sold_flow",
      "sellThroughRate": null,
      "sellThroughRateNote": "Yahoo! Auctions' closedsearch index contains auctions that sold …",
      "soldAuctionsIndexed": 1102, "sampledAuctions": 100,
      "soldPerDay": 5.52, "sampleWindowDays": 17.94,
      "newestSoldAt": "2026-08-06T21:55:21+09:00", "daysSinceLastSale": 0.76,
      "soldPriceJpy": {"p25": 3675, "median": 6708, "p75": 18150, "max": 93000},
      "bidCount": {"p25": 1, "median": 6, "p75": 15, "max": 50},
      "instantBuy": {"auctionsWithInstantBuyPrice": 15, "closedAtInstantBuyPct": 26.7,
                     "medianPriceToInstantBuyPct": 79.7}
    },
    "paypay_flea": {
      "demandBasis": "supply_only", "sellThroughRate": null,
      "liveListings": 589, "askPriceJpy": {"median": 12675}, "listingsWithLikesPct": 82.0
    }
  },
  "marketsWithDemandSignal": ["mercari", "yahoo_auction"],
  "definitions": { "sellThroughRate": "…", "soldPerDay": "…", "askPremiumPct": "…" },
  "checkedAt": "2026-08-07T07:03:40+00:00"
}
```

With `includeIndividualItems: true` you additionally get one record per sampled listing, tagged with `market` and `side` (`sold` / `listed`).

### Use cases

- **Sourcing decisions** — a 70% sell-through with a 6-day median is a product you can buy; a 20% sell-through with 200-day-old listings is dead stock whatever the price says
- **Pricing to actually sell** — `priceGap.sellingBandJpy` is the p25–p75 of what changed hands, and `priceBands` shows where the rate falls off
- **Deciding where to list** — Mercari's rate and Yahoo's `soldPerDay` describe two different sales mechanics; `paypayLiveListings` is the competition on a third
- **Inventory triage** — schedule the Actor over your SKU list and watch `sellThroughRate` and `daysSinceLastSale` move
- **Demand research** — how does sell-through vary by price band and category across the Japanese resale market

### Notes & limits — how the statistics are defined

**These are sample-based statistics, not a census.** Read this before quoting a number.

- **`sellThroughRate` is a stock ratio, not a conversion rate.** It is `sold-out listings / (sold-out + on-sale listings)` from Mercari's own hit counts for the keyword — a snapshot of the listing population, not "N% of listings sell within X days". It is not comparable with Yahoo's `soldPerDay`.
- **Mercari caps its hit count at 15,000**, so a rate built from a capped count is a bound and `rateBound` says which: `lower_bound` (sold side capped), `upper_bound` (on-sale side capped), or **`unknown`** — in which case the rate is `null`, because two capped counts force exactly 0.5 by construction. Measured: `nintendo switch` returns 15000/15000 and gets no rate; `ライカ M6` returns 396/297 and gets an exact 57.1%.
- **`soldPerDay` is measured over the sampled window**, so always read `sampleWindowDays` beside it. On a huge keyword 30 samples can span 0.03 days and the extrapolated rate is instantaneous, not a daily average. Raise `maxItemsPerMarket` to widen the window.
- **Price, speed and bid statistics come from a sample** of up to `maxItemsPerMarket` listings per side, taken in each site's default result order. The listing counts and the sell-through rate do not.
- **`priceBands` is an estimate.** Each band weights its sampled sold and on-sale counts back up by that side's total listing count, because the two sides are sampled at different rates. `soldSampled` / `onSaleSampled` are published so a band resting on three listings is visible as such. Mercari's own hit count could not be used here: measured 2026-08-07, adding a price ceiling makes it repeatably **non-monotone** (the sold side answered 1,604 for `≤¥3,000` but 1,101 for `≤¥6,000`), so a ladder of ceilings cannot be differenced into band counts.
- **This Actor deliberately has no price filter.** A client-side price window would filter the sample but not the site's hit counts, silently breaking the rate it is supposed to support. The price-band table answers the same question without corrupting anything.
- **Mercari's `daysToSell` is `updated - created`**, which also moves on price edits, so it skews low — a liquidity signal, not an exact time-to-sale. The age of a live listing uses `created` and the wall clock instead, so an edit cannot make a stale listing look fresh.
- **A negative `askPremiumPct` usually means product mix, not a bargain**: the on-sale pool holds accessories and parts that the sold pool does not. Use `priceBands`.
- **Yahoo's `instantBuy` excludes fixed-price listings**, where `price == buyNowPrice` by definition and a "take rate" would be meaningless.
- **A market that fails does not fail the run**: it comes back as `available: false` with an `error`, and the other markets still report. Only a keyword where *no* market measured demand fails the run.
- Read-only, no login, no browser. Requests are throttled to one per 1.5 s, and Yahoo! Auctions and PayPay Flea Market are queried **sequentially** because they share one backend.
- No personal data is collected — sellers are excluded from every record.

***

### 日本語ガイド

**キーワード1件につき、日本の中古市場の「売れ行き(消化率)」を1レコードで返す Actor です。**「いくらか」ではなく「そもそも売れているのか」に答えます。

- **メルカリ**: `sellThroughRate` = 売り切れ件数 /(売り切れ+販売中)。メルカリ自身の検索ヒット件数から算出します。加えて売れるまでの日数、売れ残りの掲載日数、**価格帯別の消化率**を返します。
- **ヤフオク**: **落札率は返しません**。ヤフオクの「落札相場」は落札済みのみを収録しており(2026-08-07 実測: 4キーワード200件すべて入札1件以上)、そこから消化率を出すと必ず 1.0 になるためです。代わりに**1日あたりの落札件数**・最終落札からの経過日数・落札価格分布・入札数・即決価格の到達率を返します。
- **PayPayフリマ**: 売却済みを公開していないため**供給(出品件数と提示価格)のみ**です。
- **数値の性質が市場ごとに違います**(`demandBasis`)。メルカリは「在庫に対する割合」、ヤフオクは「1日あたりの件数」で単位が異なるため、平均してはいけません。全フィールドが市場名を含む形で分かれています。
- **メルカリのヒット件数は 15,000 で頭打ちになります**。両側が頭打ちだと比率が必ず 0.5 になるので、その場合は `rateBound: "unknown"` として**数値を出しません**(実測: `nintendo switch` は 15000/15000 で非公開、`ライカ M6` は 396/297 で 57.1%)。
- **料金**: キーワード1件 **$0.02**(市場を何個選んでも同額)、個別明細は **$0.002/件**(既定 OFF なので既定実行は $0.02 固定)。**どの市場も需要を測れなかったキーワードには課金しません**。サブスクリプション不要です。
- **注意**: 価格・日数・入札数の統計は各サイトの既定並び順から最大 `maxItemsPerMarket` 件の**標本**です(全数ではありません)。消化率と件数のみサイトのヒット件数由来です。価格帯別の消化率は標本を母数で重み付けした**推定値**です(メルカリのヒット件数は価格上限を付けると単調でなくなることを実測したため、件数の差分では計算できません)。ブラウザ不使用・ログイン不要・1.5秒に1リクエスト、ヤフオクと PayPayフリマは同一基盤のため逐次取得しています。個人情報は取得しません。

# Actor input Schema

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

One or more search keywords to measure demand for. Japanese usually matches far more listings than English (象印 圧力IH炊飯器, ライカ M6, Nintendo Switch). Narrow keywords give sharper rates: a broad keyword mixes products, and Mercari caps its hit counts at 15,000 so very broad keywords cannot produce an exact sell-through rate. Each keyword costs $0.02.

## `markets` (type: `array`):

Mercari Japan is the only one that publishes both sold and on-sale listing counts, so it is the only source of a real sell-through RATE. Yahoo! Auctions publishes completed sales only — it contributes sales PER DAY, realized prices and bid competition. PayPay Flea Market publishes live listings only — it contributes competing supply. The price of a keyword is the same whichever markets you pick.

## `maxItemsPerMarket` (type: `integer`):

How many listings to sample per market and per side (sold / on sale) before computing price, speed and bid statistics. The headline sell-through rate and the listing counts do NOT depend on this — they come from the sites' own hit counts. The price-band table does: a larger sample makes the per-band rates steadier. Larger samples are slower — Yahoo returns 50 per request, Mercari 120, PayPay 100, and requests are throttled to one per 1.5 s.

## `includeIndividualItems` (type: `boolean`):

Off by default: a run costs a flat $0.02 per keyword, whatever the number of markets. Enable to also get every sampled listing (title, price, sold/listed side, dates, condition, URL) at +$0.002 per listing.

## `convertToUsd` (type: `boolean`):

Adds USD statistics next to JPY using the current exchange rate (open.er-api.com, looked up once per run).

## Actor input object example

```json
{
  "keywords": [
    "象印 圧力IH炊飯器"
  ],
  "markets": [
    "mercari",
    "yahoo_auction",
    "paypay_flea"
  ],
  "maxItemsPerMarket": 100,
  "includeIndividualItems": false,
  "convertToUsd": true
}
```

# 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": [
        "象印 圧力IH炊飯器"
    ],
    "markets": [
        "mercari",
        "yahoo_auction",
        "paypay_flea"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpmarketdata/japan-sell-through-rate").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": ["象印 圧力IH炊飯器"],
    "markets": [
        "mercari",
        "yahoo_auction",
        "paypay_flea",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("jpmarketdata/japan-sell-through-rate").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": [
    "象印 圧力IH炊飯器"
  ],
  "markets": [
    "mercari",
    "yahoo_auction",
    "paypay_flea"
  ]
}' |
apify call jpmarketdata/japan-sell-through-rate --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jpmarketdata/japan-sell-through-rate"
        }
    }
}

```

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/RCkeZEmlVWv8CFexu/builds/QNdbIm7w9h08lzN4z/openapi.json
