# Yahoo Auctions Sold/Completed + Seller Intel (`sigma-dev/yahoo-auctions-sold-completed-seller-intel`) Actor

Know what Japanese buyers actually paid. Scrapes 180 days of sold Yahoo! Auctions Japan listings with bids, bidders, watchers and views, then computes price comps (median, trimmed mean, P25-P75, trend) and per-seller GMV and velocity. No login needed.

- **URL**: https://apify.com/sigma-dev/yahoo-auctions-sold-completed-seller-intel.md
- **Developed by:** [Sigma Dev](https://apify.com/sigma-dev) (community)
- **Stats:** 1 total users, 1 monthly users, 90.9% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 results

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/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

## Yahoo! Auctions Japan Sold Prices & Seller Intel

Current listings tell you what an item is *for sale* for. Sold listings tell you what it is *worth* — and that is the buying decision.

This Actor scrapes **Yahoo! Auctions Japan (ヤフオク!) sold/closed history** — up to 180 days of it — and returns not just the raw sales but computed price comps and per-seller intelligence. No Yahoo account or login needed.

Built for resellers sourcing from Japan, proxy-buying services, arbitrage buyers, and anyone who needs to know what Japanese buyers actually paid.

### What makes this different

Most Yahoo Auctions scrapers hand you a list of listings. This one also tells you what the listings *mean*:

- **Real demand signals, not just prices.** Every sale comes with its bid count, **distinct bidder count**, watcher count, **page views** and **impressions**. Two items that both sold for ¥30,000 are not equal if one drew 40 bidders and the other drew one.
- **Price trend, not just a median.** Every query gets a `priceTrend30v90` figure comparing the last 30 days' median against days 31–90. You learn whether a price is holding, climbing or sliding.
- **Seller intelligence.** Per-seller GMV, median price, sales velocity, category mix and a relist-rate proxy — who the real players are in your niche, and what they clear.
- **Gets past Yahoo's 10,000-result ceiling.** Yahoo silently truncates any query at ~10,000 rows. This Actor detects that and automatically splits the query into price bands so you get the whole result set.
- **Built to survive Yahoo's redeploys.** Yahoo's result rows use hashed CSS class names that change on every front-end deploy, which is why selector-based scrapers break so often. This Actor reads each row's structured `data-cl-params` payload instead, with a text fallback if that ever disappears.

### What you get

#### Sold items (default dataset)

| Field | Description |
| --- | --- |
| `auctionId`, `url`, `title`, `imageUrl` | Listing identity |
| `finalPrice`, `startPrice`, `currency` | What it sold for, and what it opened at |
| `priceVsStartMultiple` | Final ÷ start — how hard bidding drove it |
| `bidCount`, `bidderCount` | Total bids, and how many distinct people competed |
| `watchCount`, `pageViews`, `impressions` | Demand before the sale |
| `viewsPerBid` | Views needed per bid — attention-to-action efficiency |
| `startedAt`, `endedAt`, `lastBidAt`, `durationHours` | Full timing, ISO 8601 UTC |
| `conditionLabel` | Yahoo's condition grade (未使用, 目立った傷や汚れなし, …) |
| `categoryId`, `categoryPath` | Category and breadcrumb trail |
| `sellerId`, `sellerUrl`, `sellerRating` | Who sold it, and their rating % |
| `shipsFromPrefecture`, `freeShipping` | Dispatch region and shipping terms |
| `isAppraised`, `catalogId` | Yahoo appraisal badge; product-catalog grouping id |
| `marketplace` | `auction` or `fleamarket` |

#### Price comps (`COMPS` in the key-value store)

`soldCount`, `minPrice`, `maxPrice`, `avgPrice`, `medianPrice`, `trimmedMeanPrice`, `p25Price`, `p75Price`, `p25ToP75Spread`, `stdDevPrice`, `totalGmv`, `avgBidCount`, `avgBidderCount`, `pctSingleBid`, `avgWatchCount`, `avgPageViews`, `soldPerWeek`, `topSellers`, `topCategories`, `historyCoverageDays`, `sold30d`, `sold31to90d`, `priceTrend30v90`, `priceTrendPct`, `priceTrendStrata`.

Three fields worth calling out:

- **`trimmedMeanPrice`** discards the top and bottom 10% before averaging. Sold-price data is polluted by ¥1 junk lots and outlier whale sales, so this is usually a better "what is it worth" number than the raw average. On a real ロレックス sample the raw average was ¥183,175 while the trimmed mean was ¥46,798 — the average was being dragged by a single ¥3.5M sale.
- **`pctSingleBid`** is the share of sales that closed with one bid. A high value means buyers are not competing, so the price is closer to a ceiling than a floor.
- **`priceTrend30v90`** needs history depth to exist, and this is worth understanding before you rely on it. Yahoo returns results newest-first and offers no date filter, so a popular keyword's first few hundred rows may all come from the last day or two. `historyCoverageDays` tells you how far back your sample actually reached; if the trend is null, `priceTrendNote` explains exactly why and what to change. To get a usable trend, narrow the query (a specific model rather than a brand, a category, or a price range) or raise `maxItems` so the crawl reaches past 30 days.

  The trend is computed **stratified by sub-query**, not on the pooled sample. When a query is split into price bands, those bands reach different depths in time, so comparing pooled windows would compare different price mixes rather than price movement. Ratios are computed within each band and the median taken; `priceTrendStrata` reports how many bands qualified. For the same reason, `median30d` and `median31to90d` are only populated for queries that were not split.

Yahoo's own reported lowest/average/highest (`yahooMinPrice`, `yahooAvgPrice`, `yahooMaxPrice`) and total (`yahooReportedTotal`) are included so you can cross-check our figures against the source.

#### Seller intelligence (`SELLERS` in the key-value store)

`displayName`, `ratingPercent`, `ratingCount`, `isVerified`, `activeListingCount`, `soldCount180d`, `gmv180d`, `medianSoldPrice`, `avgBidCount`, `soldPerWeek`, `soldToActiveRatio`, `relistRateProxy`, `uniqueTitles`, `categoryMix`, `firstSeenSoldAt`, `lastSoldAt`.

### How to use it

Give it at least one of: **search terms**, **category IDs**, **seller IDs**, or **start URLs**.

Japanese keywords return far more than English ones, because that is how items are listed. `ロレックス` returns roughly 18,000 sales; "Rolex" returns a fraction of that.

#### Example: what did this watch actually sell for?

```json
{
  "searchTerms": ["ロレックス エクスプローラー"],
  "excludeKeywords": "ジャンク レプリカ 修理",
  "minPrice": 100000,
  "soldWithinDays": 90,
  "maxItems": 500
}
```

#### Example: profile a competitor

```json
{
  "sellerIds": ["JH3J1n3GZZA4rXChorKRKxMekEgw"],
  "marketplace": "both",
  "includeSellerIntel": true
}
```

Returns that seller's entire 180-day sold history plus a computed intel record.

Aggregates are written to the run's key-value store under `COMPS` and `SELLERS`, and linked from the Output tab. Set `writeNamedDatasets` to also mirror them into persistent `comps` and `sellers` datasets; that is off by default because named datasets accumulate across runs and are not available on every plan.

#### Example: sweep a category daily for new sales

```json
{
  "categoryIds": ["23336"],
  "soldWithinDays": 2,
  "incrementalMode": true,
  "autoSlicePriceBands": true
}
```

With `incrementalMode`, previously seen sales are remembered and skipped, so a scheduled run returns only what is new. State lives in a **named** key-value store (`stateStoreName`, default `yahoo-auctions-sold-state`) because a run's own default store is created fresh each time and cannot carry state forward. Give each scheduled watch list its own `stateStoreName` so their histories stay separate.

### Limitations — read these before you buy

These are properties of Yahoo's data, not bugs, and we would rather you know up front.

- **180 days maximum.** Yahoo does not retain sold history beyond that. `soldWithinDays` cannot exceed 180.
- **Sold data contains only items that sold.** Listings that ended without a sale are not published by Yahoo anywhere. **A true sell-through rate is therefore not computable from this source, and we do not pretend otherwise.** What you get instead: `soldToActiveRatio` (180-day sales against current active listings) as a velocity proxy, and `relistRateProxy` (repeated identical titles from one seller) as an indirect unsold signal.
- **No custom sort order.** Yahoo's robots.txt disallows the `select=` parameter, so results come back newest-first only. In practice this is the useful order anyway, and it is what makes date-bounded and incremental crawling efficient.
- **No seller feedback history or bidder identities.** Yahoo's robots.txt disallows `/jp/show/rating` and `/jp/show/bid_hist`, so this Actor does not touch them. You get the seller's aggregate rating %, not their individual reviews; and bidder *counts*, not bidder names.
- **~10,000 rows per query**, worked around by automatic price-band splitting. With `autoSlicePriceBands` off, broad queries truncate.
- **Flea Market rows are mixed in.** Yahoo returns Auctions and Flea Market (フリマ) sales together, and the auction share depends heavily on the keyword — around 44 of 50 rows for `ロレックス`, but only about 2 of 50 for `ポケモンカード`. Flea-market sales are fixed-price, so they carry no bid, bidder or watcher data. Default is auctions only; set `marketplace` to `both` to keep everything.
- **Trend figures need history depth, and often will not be available on broad keywords.** Because Yahoo serves newest-first with no date filter, reaching days 31–90 means paginating that far back. `priceTrend30v90` is null unless a single sub-query holds at least 5 sales in *both* windows; `historyCoverageDays` and `priceTrendNote` always tell you where you stand. Narrow queries get trends; "every Rolex ever" does not.

### Compliance

This Actor only requests paths Yahoo's `robots.txt` permits. `/closedsearch/closedsearch` is explicitly allowed there (an `Allow:` rule that overrides the broader `Disallow: /closedsearch/`), as is the bare `/seller/<id>` profile path.

Parameters Yahoo disallows — `n`, `select`, `aucminprice`, `aucmaxprice`, `istatus`, `thumb`, `pstagefree`, `offer`, `abatch`, `jpypayment`, `wheel_spec_id` — are refused in code, in the one module that builds every request URL. If you paste a browser URL containing one into `startUrls`, it is stripped and the URL rebuilt before the request goes out.

No login is used and no personal data is collected: seller IDs are Yahoo's own opaque pseudonymous identifiers, and locations are coarse prefecture-level dispatch regions.

Separately, Yahoo! JAPAN's Terms of Service place restrictions on automated access. Complying with those, and with the laws that apply to you, is your responsibility as the operator of this Actor.

### Proxies and blocking

Yahoo tolerates datacenter IP ranges inconsistently. The Actor starts on **Apify Proxy's automatic mode** (datacenter IPs, available on every plan) and escalates to **Japanese residential** only if the first tier returns no data and shows block signals — so you pay for residential traffic only when it is actually needed. Tiers whose proxy groups your plan does not include are skipped automatically rather than failing the run.

If your plan includes proxy country selection, setting the country to Japan in the proxy input improves results: a Japanese exit IP keeps prices and shipping in their domestic form.

Set `escalateToResidentialOnBlock` to `false` to cap costs strictly.

### Pricing

Pay per result:

| Event | Price |
| --- | --- |
| Sold item | $0.003 |
| Seller profile | $0.010 |
| Price comps report | $0.050 |

### Output example

```json
{
  "auctionId": "p1246400393",
  "title": "未開封 ポケカ30周年BOXシュリンクあり30th CELEBRATION 拡張パック BOX",
  "marketplace": "auction",
  "finalPrice": 25500,
  "startPrice": 1,
  "currency": "JPY",
  "priceVsStartMultiple": 25500.0,
  "bidCount": 17,
  "bidderCount": 12,
  "watchCount": 14,
  "pageViews": 142,
  "impressions": 3038,
  "viewsPerBid": 8.35,
  "startedAt": "2026-09-29T23:03:36Z",
  "endedAt": "2026-10-02T01:03:35Z",
  "durationHours": 50.0,
  "conditionLabel": "未使用",
  "categoryPath": ["トレーディングカードゲーム", "ポケモンカードゲーム", "パック、ボックス、特殊セット"],
  "sellerId": "72SwpB56r5WsLEsThadruLfbxe3Sn",
  "sellerRating": 100.0,
  "shipsFromPrefecture": "東京都",
  "freeShipping": false,
  "isAppraised": true,
  "catalogId": "e67ddf3616"
}
```

### Running it locally

```bash
apify run
```

Put your input in `storage/key_value_stores/default/INPUT.json`. Results land in `storage/datasets/default/`.

### Support

Found a field that stopped populating, or a keyword that returns nothing? Yahoo changes its front end regularly. Open an issue on the Actor's page with the input you used and it will be looked at.

# Actor input Schema

## `searchTerms` (type: `array`):

Japanese or English keywords to look up in Yahoo! Auctions sold history. Each term becomes its own query and its own price-comps record. Japanese terms return far more results, since that is how items are listed.

## `categoryIds` (type: `array`):

Yahoo category IDs (the `auccat` value in a Yahoo URL), e.g. 23336 for watches. Used alone to sweep a whole category's sold history, or combined with search terms to restrict those terms to these categories.

## `sellerIds` (type: `array`):

Yahoo seller IDs. Each one returns that seller's complete 180-day sold history — the richest input for seller intelligence. Find an ID in any seller profile URL: auctions.yahoo.co.jp/seller/<ID>.

## `startUrls` (type: `array`):

Yahoo sold-search URLs to crawl directly, for filters this input does not expose. Parameters Yahoo's robots.txt disallows (n, select, aucminprice, aucmaxprice, thumb, …) are stripped automatically and the URL rebuilt.

## `anyKeywords` (type: `string`):

Space-separated words; a listing matches if it contains at least one of them. Maps to Yahoo's `vo` parameter.

## `excludeKeywords` (type: `string`):

Space-separated words to exclude. Maps to Yahoo's `ve` parameter. Useful for stripping out ジャンク (junk), 修理 (repair) and レプリカ (replica) so comps reflect sellable stock.

## `marketplace` (type: `string`):

Yahoo returns Auctions and Flea Market (フリマ) sales in one response. Auction rows carry bids, bidders and watcher counts; flea-market rows are fixed-price and carry none. Auction share varies by keyword — around 44 of 50 rows for ロレックス, but only about 2 of 50 for ポケモンカード, so choosing 'both' can retrieve far more for flea-heavy terms.

## `soldWithinDays` (type: `integer`):

Only keep sales that ended within this many days. Yahoo retains 180 days of sold history, which is the maximum. Results come back newest-first, so a smaller window also means a much shorter crawl.

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

Ignore sales below this final price, in yen. Filtering out 1-yen junk lots materially improves the median and trend figures.

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

Ignore sales above this final price, in yen. Leave empty for no ceiling.

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

Total cap on sold items across the whole run. Each Yahoo request returns 50 rows, so 200 items is about 4 requests. Raise it for a deeper sweep; note that deeper history is what makes the price-trend figure computable.

## `maxItemsPerQuery` (type: `integer`):

Per-term cap, so one broad keyword cannot consume the entire run budget when several terms are supplied.

## `autoSlicePriceBands` (type: `boolean`):

Yahoo stops serving results past about 10,000 rows per query, silently truncating anything broader. When enabled, an over-cap query is automatically split into narrower price bands so the full result set is retrievable. Leave on unless you want strictly the newest sales.

## `includeSellerIntel` (type: `boolean`):

Build a per-seller report (GMV, median price, velocity, category mix, relist rate) in the `sellers` dataset. Costs one extra request per unique seller to read their active-listing count.

## `maxSellerProfiles` (type: `integer`):

Cap on seller profile requests, to bound run cost on keywords with many distinct sellers. Sellers beyond the cap still receive list-derived metrics, just no active-listing count.

## `computeComps` (type: `boolean`):

Write a per-query statistics record (median, p25/p75, trimmed mean, GMV, bid competition, and the 30-day vs 31-90-day price trend) to the `comps` dataset.

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

Remember which sales were already seen and skip them on later runs, so a scheduled run returns only what is new. State is kept in a named key-value store that persists between runs (the run's own default store cannot be used, as it is created fresh each run).

## `stateStoreName` (type: `string`):

Named key-value store holding incremental state. Only used when incremental mode is on. Give each scheduled watch list its own name so their histories stay separate.

## `maxConcurrency` (type: `integer`):

Parallel requests. Yahoo's sold pages are static HTML, so 10 is comfortable; raise it carefully, as aggressive crawling invites blocking.

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

Yahoo blocks some datacenter IP ranges. The default is Apify Proxy's automatic (datacenter) mode, which every plan can use and is usually sufficient. If your plan includes proxy country selection, setting the country to Japan improves results — a Japanese exit IP keeps prices and shipping in their domestic form. If your plan includes residential proxies, the Actor can escalate to them automatically when blocked.

## `escalateToResidentialOnBlock` (type: `boolean`):

If the first proxy tier returns no data and shows block signals, retry the outstanding requests on Japanese residential proxies. Residential traffic costs more, so it is only used when the cheaper tier actually fails.

## `writeNamedDatasets` (type: `boolean`):

Mirror the price comps and seller intel into persistent named datasets (comps, sellers) in addition to the key-value store. Off by default: named datasets accumulate across runs and can be refused on some plans. The key-value store copy is always written either way.

## Actor input object example

```json
{
  "searchTerms": [
    "ロレックス"
  ],
  "categoryIds": [],
  "sellerIds": [],
  "startUrls": [],
  "excludeKeywords": "ジャンク レプリカ",
  "marketplace": "auctions",
  "soldWithinDays": 180,
  "minPrice": 1000,
  "maxPrice": 500000,
  "maxItems": 200,
  "maxItemsPerQuery": 200,
  "autoSlicePriceBands": true,
  "includeSellerIntel": true,
  "maxSellerProfiles": 25,
  "computeComps": true,
  "incrementalMode": false,
  "stateStoreName": "yahoo-auctions-sold-state",
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "escalateToResidentialOnBlock": true,
  "writeNamedDatasets": false
}
```

# Actor output Schema

## `soldItems` (type: `string`):

Every sold listing retrieved, with price, bids, bidders, watchers and page views.

## `priceComps` (type: `string`):

Per-query price statistics, including the 30-day versus 31-90-day price trend.

## `sellerIntel` (type: `string`):

Per-seller sold volume, GMV, velocity, category mix and relist-rate proxy.

## `runSummary` (type: `string`):

Counts of what was retrieved and skipped, plus the effective configuration.

# 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 = {
    "searchTerms": [
        "ロレックス"
    ],
    "anyKeywords": "",
    "excludeKeywords": "ジャンク レプリカ",
    "minPrice": 1000,
    "maxPrice": 500000
};

// Run the Actor and wait for it to finish
const run = await client.actor("sigma-dev/yahoo-auctions-sold-completed-seller-intel").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 = {
    "searchTerms": ["ロレックス"],
    "anyKeywords": "",
    "excludeKeywords": "ジャンク レプリカ",
    "minPrice": 1000,
    "maxPrice": 500000,
}

# Run the Actor and wait for it to finish
run = client.actor("sigma-dev/yahoo-auctions-sold-completed-seller-intel").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 '{
  "searchTerms": [
    "ロレックス"
  ],
  "anyKeywords": "",
  "excludeKeywords": "ジャンク レプリカ",
  "minPrice": 1000,
  "maxPrice": 500000
}' |
apify call sigma-dev/yahoo-auctions-sold-completed-seller-intel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sigma-dev/yahoo-auctions-sold-completed-seller-intel"
        }
    }
}
```

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/seU5hzVaZdjNX84BQ/builds/6ph1yso0rdQznAqis/openapi.json
