# magi Japan Card Prices — Sold, Asking, Shop or Person (`jpmarketdata/magi-japan-card-price-checker`) Actor

Type a card name and get what copies sold for on magi, Japan's card-only marketplace, and what sellers still ask. Returns median sold price and range, how many copies have sold, new versus used counts, and the share sold by card shops. $0.02 per card name, no results = no charge. Unofficial.

- **URL**: https://apify.com/jpmarketdata/magi-japan-card-price-checker.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 card price 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/actors/running/actors-in-store.md#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

## magi Japan Card Prices — Sold, Asking, Shop or Person

> **Unofficial** — independent tool, **not affiliated with, endorsed by, or sponsored by magi**. It reads only publicly visible pages. Support, reliability guarantees and the full disclaimer are at the bottom of this page.

**What it does:** Type a Japanese card name and get what copies of it sold for on magi, Japan's card-only marketplace, and what sellers are still asking.

**You enter:** one or more card names in Japanese, e.g. `リザードン` (Charizard).

**You get:** one row per card name: how many copies have sold and how many are still for sale, the typical sold price and its range, the same for asking prices, the used / new / not-stated split, and the card shop share of the listings read.

**Price:** $0.02 per card name. +$0.002 per row if you also want the list. No results = no charge.

**Example:** enter `リザードン` → 4,210 copies (3,024 already sold + 1,186 still for sale) · typical sold price ¥54,157, from ¥100 to ¥4,680,000 · 71.8% of copies have sold · used 2,819 / new 11 / not stated 194 · 55.9% of the 658 listings read came from a card shop (real run, 2026-09-09)

> Unofficial — not affiliated with magi. Reads public pages only.

### Pricing — $0.02 per card name

| Event | Price | When |
|---|---|---|
| Card market summary | **$0.02** | Per card name measured |
| Individual listing | **$0.002** | Only if you enable **Include individual listings** |

A default run (1 card name, summary only) costs **$0.02**. You pay per card name; there is no monthly fee. **A card name that returns zero listings is never charged**, and neither is a run that stops because magi's robots.txt has closed its search pages — or could not be read at all.

### Input

| Field | Example | Notes |
|---|---|---|
| `keywords` | `["リザードン"]` | Japanese card names. A shorter name matches more copies. Each name costs $0.02; a name magi finds nothing for is not charged. About 25–45 seconds per name (magi's search warms up slowly), so 2 or 3 per run |
| `includeSoldOut` | `true` | On by default — measures the copies that already sold. Off leaves only asking prices, and removes `soldShare`, `soldVsAskingRatio` and `conditionSplit` |
| `includeOnSale` | `true` | On by default — measures the copies still for sale. With both sides on, the two ends of the middle 50% range are read on the sold side first, so `onSale.p25` and `onSale.p75` come back empty (see below). Off removes `soldVsAskingRatio` |
| `sortBy` | `"price_asc"` | Which end of the market the individual listings come from: cheapest first or dearest first. The summary figures are read off the same positions either way — but if magi's price order wobbles on one side, that side falls back to the listings read and says so in its `priceBasis` |
| `maxItemsPerKeyword` | `96` | 1–288. How many individual listings come back per card name (+$0.002 each; 96 = one page of results). The typical price and the price range do not move with it — those come off magi's price order on a fixed 11 page reads. What it widens is the card shop share, which is measured on the listings read |
| `includeIndividualItems` | `false` | Enable to also get every listing read as its own row (+$0.002 each) |
| `convertToUsd` | `true` | Adds USD figures at the current exchange rate. A failed lookup never fails the run |

### Does a number cover every copy, or only the ones read?

Every price block carries a **`priceBasis`**, so you never have to guess:

| `priceBasis` | What it means |
|---|---|
| **`population`** | The figure covers **every matching copy**. magi lets you sort by price and that order holds from page to page, so the copy sitting at the middle of the whole list really is the middle price |
| **`sample`** | The figures cover only the listings actually read (`sampledCount` says how many). You get this when magi's count is saturated at 10,000, when that side's price order stops holding, or when the run's time budget cut the reads short. Those listings are page 1 plus the pages the position jumps landed on, so read the middle price as the middle of what was read and not of the market — and `average` is left empty rather than being the mean of two or three chosen price bands |
| **`null`** | Nothing on this side carried a price, so there is nothing to describe |

**Which side of the market the top-level prices describe.** `priceJpy`, `priceUsd` and `priceBasis` are about **one** side, and **`priceJpyCovers`** says which: `sold` for the copies that changed hands — the default, and the figure this Actor is built on — or `on_sale` for the asking prices, which is what you get when you turn **Sold copies** off. It is `null` only when nothing was measured. Both sides are always there in full under `sold` and `onSale` as well, each with its own `priceBasis`.

**`soldVsAskingRatio` exists only when both sides cover every copy.** It is the sold middle price divided by the asking middle price, and **`soldVsAskingRatioBasis`** sits next to it saying what that division covered. If either side has fallen back to `sample`, both come back `null` rather than dividing one side's whole market by the other side's handful of pages: measured 2026-09-09, a still-for-sale side that wobbled read a middle price of ¥33,650 where the whole set sat at ¥59,250, which would have printed 4.49 for a market at 2.55.

**Why the asking side usually shows two empty quarter marks.** A card name gets 11 page reads, and with both sides on they go to each side's count and one end of its range, the used / new counts, then both middle prices, both far ends, and the sold side's two ends of the middle 50% range — which is the eleventh read. So at the default input `onSale.p25` and `onSale.p75` come back `null` even though the rest of that block covers every copy. To measure them, turn **Sold copies** off and the asking side has the reads to itself. Raising **Listings read per card name** does not buy them: that input buys rows, not position jumps.

Two figures are **always** sample-based and say so:

- **`sellerMix`** — magi has no filter for the 認定出品者 (certified shop) badge, so the card shop share can only be measured on the listings read. It moves hard with price: 0 of 96 in the cheapest sold band, and 55.9% across the 658 listings the example run read.
- **`average`** is `null` whenever `priceBasis` is `population`. Reading the copy at a given position gives the middle prices of the whole list exactly, but an average cannot be recovered that way, and averaging whichever pages happened to be read would be a sample number wearing a bigger label. It is `null` in a `sample` built out of position jumps too, for the same reason: the mean of two or three chosen price bands is not a price anyone would want to quote.

### When a card name comes back empty

`keywordStatus` is `ok` as soon as magi returns copies, `not_found` when it returns none, and `unknown` when copies exist but none of the listings read carried a price — with `hint` naming the next thing to try in one sentence (`null` otherwise). **None of the three is charged unless it is `ok` with listings read.**

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

Measured on 2026-09-09 (real run, `{"keywords": ["リザードン"], "sortBy": "price_asc", "maxItemsPerKeyword": 96, "includeIndividualItems": false}` — 12 requests to magi.camp, 29 seconds). The whole record, nothing shortened.

```json
{
  "type": "card_market_summary",
  "keyword": "リザードン",
  "keywordStatus": "ok",
  "sortUsed": "price_asc",
  "robotsStatus": "allowed",
  "totalListingsFound": 4210,
  "totalFoundUnfiltered": 4210,
  "statusSplitConsistent": true,
  "countIsCapped": false,
  "distinctProductsMatched": 5103,
  "sampledListings": 658,
  "priceJpy": {
    "min": 100,
    "p25": 17877,
    "median": 54157,
    "p75": 114000,
    "max": 4680000,
    "average": null
  },
  "priceJpyCovers": "sold",
  "priceBasis": "population",
  "priceUsd": {
    "min": 0.65,
    "p25": 116.22,
    "median": 352.07,
    "p75": 741.11,
    "max": 30424.68,
    "average": null
  },
  "exchangeRateJpyUsd": 0.006501,
  "sold": {
    "count": 3024,
    "priceStats": {
      "min": 100,
      "p25": 17877,
      "median": 54157,
      "p75": 114000,
      "max": 4680000,
      "average": null
    },
    "priceBasis": "population",
    "sampledCount": 432
  },
  "onSale": {
    "count": 1186,
    "priceStats": {
      "min": 100,
      "p25": null,
      "median": 15836,
      "p75": null,
      "max": 29746000,
      "average": null
    },
    "priceBasis": "population",
    "sampledCount": 226
  },
  "soldShare": 0.7183,
  "soldVsAskingRatio": 3.4199,
  "soldVsAskingRatioBasis": "population",
  "conditionSplit": {
    "used": 2819,
    "brandNew": 11,
    "unspecified": 194
  },
  "sellerMix": {
    "certifiedShopShare": 0.5593,
    "certifiedShopCount": 368,
    "sampledCount": 658,
    "basis": "sample"
  },
  "facetLabels": {
    "sold_out": "SOLD OUT",
    "presented": "出品中",
    "old": "中古",
    "brand_new": "新品"
  },
  "monotonicityCheck": "ok",
  "notes": "magi publishes no sale dates, so the sold prices are an all-time snapshot of every copy that has sold under this name — there is no days-to-sell and no last-30-days figure.",
  "hint": null,
  "requestsUsed": 11,
  "sourceUrl": "https://magi.camp/items/search?forms_search_items%5Bkeyword%5D=%E3%83%AA%E3%82%B6%E3%83%BC%E3%83%89%E3%83%B3&forms_search_items%5Bsort%5D=price_asc&page=1",
  "checkedAt": "2026-09-09T12:07:49.875591+00:00",
  "truncatedForTimeLimit": false
}
```

Two things in that record are worth reading twice. `statusSplitConsistent` is the check that the sold count plus the still-for-sale count really is the number magi reports with no filter at all — if that ever comes back `false`, `soldShare` has stopped meaning what it says and the row tells you so. And a `soldVsAskingRatio` of 3.42 says the copies that sold were typically **dearer** than the ones still sitting there: on this card the cheap listings are the ones that linger. It is printed here with `soldVsAskingRatioBasis: "population"`, i.e. both sides of that division cover every matching copy; when they do not, both fields come back `null`.

With `includeIndividualItems` on you also get one row per listing (`type: "card_listing"`): `itemId`, `url`, `name`, `priceJpy`, `isSold`, `isCertifiedSeller`, `favoriteCount`.

### What this Actor does not do

- **No sale dates, and therefore no days-to-sell.** magi publishes no date on a sold listing — the item page shows only a coarse bucket like "over six months ago". The sold prices are an all-time snapshot of every copy that ever sold under the name, and every row says so in `notes`. If you need how fast something sells, our Mercari and Yahoo! Auctions tools have real timestamps
- **No seller identity.** No seller name, no seller id. The only thing said about a seller is whether magi gave them the 認定出品者 badge
- **No images and no item description text.** magi's terms reserve those
- **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, without cookies
- **Nothing is stored.** Every run reads the site live; nothing is kept between runs

### Notes on the data

- **magi's robots.txt is re-read at the start of every run**, and the run stops without charging if the `User-agent: *` group ever tells automated readers to stay off `/items/search`. This is not caution for its own sake: the file was rewritten three times in nine days (2026-09-01, 09-08 and 09-09), each time closing the search pages to more named bots, while leaving `User-agent: *` open. That check costs 1.2 KB and about 40 ms. If the file cannot be read at all — a server error, a timeout, no answer — the run ends the same way, with nothing read and nothing charged; a missing file (a plain `404`) is the one failure treated as a yes, which is what the standard says
- **Sold and still-for-sale are an exact split.** magi's `sold_out` and `presented` filters divide the same card name with no overlap and no gap, so `soldShare` has a real denominator rather than a guess. Measured 2026-09-09: 3,024 + 1,186 = 4,210
- **Used / new is *not* an exact split.** 3,024 sold copies against 2,819 used and 11 new leaves 194 with no condition set, which is why `conditionSplit.unspecified` is always reported. Treating new + used as everything would be wrong by 6%
- **Counts stop at 10,000.** A very broad name like `ポケモン` reads `10,000件` on both tabs — that is "at least 10,000", not a number. The row sets `countIsCapped: true` and does not claim the middle prices
- **`distinctProductsMatched`** is a different quantity from the listing counts: it is how many distinct card products match the name (5,103 for `リザードン`), while `totalListingsFound` counts copies for sale or sold
- **Both magi's own facet code and its on-screen label are reported** in `facetLabels` (`sold_out` → `SOLD OUT`, `presented` → `出品中`, `old` → `中古`, `brand_new` → `新品`), so if magi ever re-points one of those codes you can see it in the data instead of having the statistics change meaning underneath you
- **Price order is checked, not assumed, and each side is checked on its own.** Price order runs cleanly across pages but steps down once or twice inside a page (measured: ¥500,000 → ¥487,386 among sold copies). Up to two of those per page are tolerated. More on one side sets that side's `priceBasis` to `sample`, and `monotonicityCheck: "violated"` says at least one side wobbled — read each side's own `priceBasis` to see which figures it touched. Measured 2026-09-09: reading dearest-first, one still-for-sale page inside the ¥10,000–17,000 band stepped down four times (many copies share a price there), while every sold page in the same run was in perfect order — so the sold figures stayed exact and only the asking figures fell back
- Pages are UTF-8 and 54–175 KB. Requests are spaced at least 1.5 s apart (or magi's own `Crawl-delay`, if it ever sets one for `*`), and a card name costs 11 page reads plus the one robots.txt read — 12 for a default run, measured today at 24, 29 and 43 seconds (magi's search warms up slowly). Those 11 are fixed: asking for up to 288 rows adds at most 2 more reads and they go to listing pages, never to a position jump, so no summary figure moves with what you pay per row. Later card names in a long list skip the position jumps once the run's 90-second budget is spent and their row says `truncatedForTimeLimit: true`

### 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).
- **You never get a fake "empty" result.** If the site can't be read, the run fails and says so.
- **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, no personal data, and it goes easy on the site.

### More tools by the same author

- [Mercari Japan Sold Prices — What Items Really Sell For](https://apify.com/jpmarketdata/mercari-japan-price-checker)
- [Yahoo! Auctions Japan Sold Prices — Median, Range, Bids](https://apify.com/jpmarketdata/yahoo-auction-sold-comps)
- [Japan Used Camera & Lens — Dealer Price vs Sold Price](https://apify.com/jpmarketdata/japan-camera-gear-sold-comps)
- [Japan Figure & Gunpla — New Price vs Used Sold Price](https://apify.com/jpmarketdata/japan-figure-gunpla-resale-value)
- [Used iPhone & Android Prices Japan — Dealer vs Sold](https://apify.com/jpmarketdata/japan-phone-resale-value)
- [Yahoo, Mercari & PayPay Japan — Same Item, 3 Prices](https://apify.com/jpmarketdata/japan-resale-cross-market-checker)
- [Mercari & Yahoo Japan Demand — Sold vs Still Listed](https://apify.com/jpmarketdata/japan-sell-through-rate)
- [Pokemon Card Japan Sold Prices — Raw vs Graded per Card](https://apify.com/jpmarketdata/japan-tcg-sold-comps)

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 magi**. 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.

# Actor input Schema

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

The card names to look up on magi, in Japanese: `リザードン` (Charizard), `青眼の白龍` (Blue-Eyes White Dragon). A shorter name matches more copies. One row per name. Each card name is charged $0.02; a name magi finds nothing for is not charged. A name takes 25 to 45 seconds, so keep the list to 2 or 3. A run stops at its Maximum cost per run, $3.00 by default — raise it in the run options.

## `includeSoldOut` (type: `boolean`):

On by default. Measures the copies that have already sold: how many, their typical price, the cheapest and dearest they went for and the two ends of the middle 50% range, plus the used / new / not-stated split. Off, only the copies still for sale are measured — that drops the share that sold and the sold-to-asking comparison, and gives the asking side the middle 50% reads. Charges do not change.

## `includeOnSale` (type: `boolean`):

On by default. Measures the copies sellers are still asking for: how many, their typical price, and the cheapest and dearest asking price. With both sides on, the two ends of the middle 50% range are read on the sold side first, so here they come back empty — turn Sold copies off to get them on this side. Off, only sold copies are measured and the sold-to-asking comparison goes.

## `sortBy` (type: `string`):

Which end of the market the individual listings come from: `price_asc` starts at the cheapest copy, `price_desc` at the dearest. The typical price and the price range cover every matching copy either way, because they are read from magi's own price order — and when that order wobbles on one side, that side reports the listings read instead and says so. This does not change what you are charged.

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

How many individual listings come back per card name when Include individual listings is on: 96 is one page of results, 288 is three. At 288 you can be charged for up to 288 rows instead of 96. The typical price and the price range do not move with it — they come off magi's own price order, on a fixed number of page reads. It does widen the card shop share, which is measured on the listings read.

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

Off by default: a run costs a flat $0.02 per card name. Switch it on to also get every listing that was read as its own row — card name, price, sold or still for sale, whether the seller is a certified card shop, favourites and the link — at +$0.002 per row. How many rows you get is set by Listings read per card name.

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

Adds USD figures next to the yen ones at the current exchange rate (open.er-api.com). A failed rate lookup never fails the run — the yen numbers simply come back on their own. This does not change what you are charged.

## Actor input object example

```json
{
  "keywords": [
    "リザードン"
  ],
  "includeSoldOut": true,
  "includeOnSale": true,
  "sortBy": "price_asc",
  "maxItemsPerKeyword": 96,
  "includeIndividualItems": false,
  "convertToUsd": true
}
```

# Actor output Schema

## `cardMarketSummaries` (type: `string`):

One row per card name with the sold and asking sides side by side — median price and range in yen, how many copies each side holds, and the share sold by certified card shops.

# 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": [
        "リザードン"
    ],
    "includeSoldOut": true,
    "includeOnSale": true,
    "sortBy": "price_asc",
    "maxItemsPerKeyword": 96,
    "includeIndividualItems": false,
    "convertToUsd": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpmarketdata/magi-japan-card-price-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": ["リザードン"],
    "includeSoldOut": True,
    "includeOnSale": True,
    "sortBy": "price_asc",
    "maxItemsPerKeyword": 96,
    "includeIndividualItems": False,
    "convertToUsd": True,
}

# Run the Actor and wait for it to finish
run = client.actor("jpmarketdata/magi-japan-card-price-checker").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": [
    "リザードン"
  ],
  "includeSoldOut": true,
  "includeOnSale": true,
  "sortBy": "price_asc",
  "maxItemsPerKeyword": 96,
  "includeIndividualItems": false,
  "convertToUsd": true
}' |
apify call jpmarketdata/magi-japan-card-price-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jpmarketdata/magi-japan-card-price-checker"
        }
    }
}

```

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/eG85j68s03KOcbPmF/builds/BCUje2em6rxXjzi4v/openapi.json
