# Digimart Japan Used Instruments — Price & Condition Stats (`jpmarketdata/digimart-instrument-market-checker`) Actor

Used-instrument price stats for any keyword on Digimart (デジマート), where ~2,000 Japanese shops list: population quartiles of the whole result set — not a first-page sample — plus the used-vs-new spread, condition split, brand and shop mix. From $0.02. デジマートの中古楽器相場を1コールで。

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

## Pricing

from $20.00 / 1,000 keyword market 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

## Digimart Japan Used Instruments — Price & Condition Stats in One Call

**What does this guitar actually go for in Japan?** One call per keyword answers it with the **quartiles of the entire result set** — not the first page, not an average of whatever the search felt like showing first.

This Actor reads [Digimart](https://www.digimart.net/) (デジマート — the listing platform roughly 2,000 Japanese instrument shops publish their stock on, including Ishibashi Music and Kurosawa Music) and returns **one compact market record per keyword**:

- **`priceJpy` — min / Q1 / median / Q3 / max of the whole population.** For a 9,038-hit keyword that is the real 25th/50th/75th percentile of all 9,038 listings, obtained in 5 requests, not an estimate from 100 samples
- **`usedVsNew`** — the median used price, the median new price, and the discount between them. The number a cross-border buyer actually acts on
- **`conditionBreakdown`** — new / used / **vintage** / new-outlet / B-stock. Digimart is one of the few marketplaces that labels vintage as its own condition rather than leaving it in the title
- **`brandTop`**, **`categoryTop`**, **`inStockRatioSampled`**, plus USD conversion at the current rate
- Optionally every sampled listing (title, brand, category, price, condition, in-stock, URL)

The Japanese domestic used-instrument market is **not** the same population as the Japanese sellers who cross-list on international platforms: a `stratocaster` search returns ~9,000 listings on Digimart against ~900 Japan-located listings on the largest international marketplace. This Actor measures the domestic one.

No login, no API key, nothing stored between runs.

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

| Event | Price | When |
|---|---|---|
| Keyword market summary | **$0.02** | Per keyword analyzed |
| Individual listing | **$0.002** | Only if you enable **Include individual listings** |

A default run (1 keyword, summary only) costs **$0.02**. **A keyword that returns zero listings is never charged.**

### Input

| Field | Example | Notes |
|---|---|---|
| `keywords` | `["Stratocaster"]` | Model names work best. Latin and Japanese both index. Each keyword costs $0.02 |
| `categoryId` | `"2001"` | **Strongly recommended.** Without it, parts share the keyword index with instruments — a `Stratocaster` search returns ¥150 switch tips and drags the low quartiles down. Copy the number out of any Digimart category URL |
| `maxItemsPerKeyword` | `100` | Listings inspected for the condition / brand mix (30–400, 100 per page). Does **not** affect the quartiles |
| `includeIndividualItems` | `false` | Enable to also get each sampled listing as a record |
| `convertToUsd` | `true` | Adds USD stats at the current exchange rate |

### Exact vs population quantiles vs sample — always labelled

Every record carries **`priceJpyBasis`**, so you never have to guess how a number was produced:

| `priceJpyBasis` | What it means | How it is obtained | When you get it |
|---|---|---|---|
| **`exact`** | True statistics over **every matching listing** | The whole result set fits on one page (≤100 hits) — 1 request | Narrow keywords |
| **`population_quantiles`** | min / Q1 / median / Q3 / max are **real population quantiles**, `count` = the full hit count | Listings are sorted by price ascending and the Actor jumps straight to the page holding the rank of each quantile, plus one descending page for the maximum — 5 requests | Most keywords |
| **`sample`** | Ordinary sample statistics over the listings inspected, `count` = sample size | Fallback. Used when the price order turns out **not** to be monotonic across pages, or when a multi-keyword run hits its time budget (then `truncatedForTimeLimit: true` is also set) | Rare |

The fallback is the point: if Digimart ever changes its sort behaviour, the Actor **stops claiming population quantiles** instead of quietly returning wrong percentiles.

`usedPriceJpy`, `newPriceJpy`, `usedVsNew`, `conditionBreakdown`, `brandTop`, `categoryTop` and `inStockRatioSampled` are **always sample-based** (`sampledListings` tells you the size). With the default `maxItemsPerKeyword: 100` the sample is the 100 cheapest listings; raise it to 200/400 and the sample is automatically spread across the price range using the quantile pages that are fetched anyway — **no extra requests, no extra time.**

### Output example (`type: "market_summary"`)

```json
{
  "type": "market_summary",
  "keyword": "Stratocaster",
  "categoryId": null,
  "totalListingsFound": 9038,
  "sampledListings": 100,
  "priceJpy": { "min": 150, "q1": 39800, "median": 98000, "q3": 198000, "max": 4980000, "count": 9038 },
  "priceJpyBasis": "population_quantiles",
  "usedPriceJpy": { "min": 150, "q1": 1980, "median": 6800, "q3": 24800, "max": 79800, "count": 61 },
  "newPriceJpy": { "min": 275, "q1": 1650, "median": 3300, "q3": 8800, "max": 39600, "count": 39 },
  "usedVsNew": { "usedMedianJpy": 6800, "newMedianJpy": 3300, "discountVsNewPct": -106.1 },
  "conditionBreakdown": { "new": 34, "used": 58, "vintage": 3, "new_outlet": 5, "b_stock": 0 },
  "inStockRatioSampled": 0.93,
  "brandTop": [["Fender", 21], ["ALLPARTS", 14]],
  "categoryTop": [["エレキギター", 46]],
  "checkedAt": "2026-08-01T05:14:07.221Z",
  "sourceUrl": "https://www.digimart.net/search?keyword=Stratocaster&readCount=100&currentPage=1&sortKey=PRICE_ASC"
}
```

`usedVsNew.discountVsNewPct` is negative here on purpose: with no `categoryId` the "new" side of an unfiltered `Stratocaster` search is dominated by cheap parts, so the used instruments are *above* it. That is exactly the artefact `categoryId` removes — and the Actor reports the number rather than hiding it.

### What this Actor does not do

- **No listing dumps by default.** The product is the statistic; individual listings are opt-in and separately priced
- **No login-only data.** Everything comes from public search pages
- **No stored dataset.** Every run fetches live; nothing is retained between runs
- **No seller PII.** Shop-level names only, never individuals

### Notes on the data

- **Condition codes** come from Digimart's own `instru_type` field: 1 new, 2 used, 3 vintage, 4 new-outlet, 5 B-stock. They are read from the structured payload the site emits, not guessed from the title
- **`sortKey` is always sent explicitly.** The platform default is a relevance order that would skew every price statistic — the same trap as a portal's "recommended" sort
- **Parts noise is real.** Use `categoryId` for any keyword that names an instrument shape rather than a specific model
- Prices are the listed asking prices including tax as shown by the seller; Digimart is a listing platform, so these are **asking** prices, not sold prices

# Actor input Schema

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

One or more search keywords — model names work best (Stratocaster, Les Paul, SG Standard, Jazz Bass, MG-M). Latin and Japanese both work: Digimart indexes the maker's own spelling. Each keyword costs $0.02.

## `categoryId` (type: `string`):

Restrict the search to one Digimart category. Without it, parts and accessories share the keyword index with instruments — a 'Stratocaster' search returns ¥150 switch tips and drags the low quartiles down. Copy the number out of any Digimart category URL (…/search?categoryId=<number>). Leave empty to search everything.

## `maxItemsPerKeyword` (type: `integer`):

How many listings to inspect per keyword for the condition split, brand mix and in-stock share. The price quartiles are read from the whole result set and are not affected. Results come 100 per page, so values above 100 reuse the quantile pages that are fetched anyway — the sample spreads across the price range at no extra request — while values below 100 only limit how many individual listings are returned (and billed) when 'Include individual listings' is on (+$0.002 per listing).

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

Off by default: a run costs a flat $0.02 per keyword summary. Enable to also get every sampled listing (title, brand, category, price, condition, in-stock, URL) at +$0.002 per listing.

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

Adds USD statistics next to JPY using the current exchange rate (open.er-api.com).

## Actor input object example

```json
{
  "keywords": [
    "Stratocaster"
  ],
  "maxItemsPerKeyword": 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": [
        "Stratocaster"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpmarketdata/digimart-instrument-market-checker").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": ["Stratocaster"] }

# Run the Actor and wait for it to finish
run = client.actor("jpmarketdata/digimart-instrument-market-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "Stratocaster"
  ]
}' |
apify call jpmarketdata/digimart-instrument-market-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=jpmarketdata/digimart-instrument-market-checker",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cdcTapHj1nbBDQxv6/builds/7LoRRepfiXmVi5QG1/openapi.json
