# Fujiya Camera Japan Used Gear — Condition-Rank Price Stats (`jpmarketdata/fujiya-camera-market-checker`) Actor

Used camera and lens price stats from Fujiya Camera (フジヤカメラ) in one call: the exact population count and median for every condition rank (未使用/A/AB+/AB/AB-/B/現状品), the rank premium between them, used-price quartiles and the new-price reference. From $0.02. フジヤカメラの中古相場をランク別に1コールで。

- **URL**: https://apify.com/jpmarketdata/fujiya-camera-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

## Fujiya Camera Japan Used Gear — Condition-Rank Price Stats in One Call

**How much more is an AB body worth than a B body?** That spread is what the Japanese used-camera export trade prices off, and it is the only number a plain listing scraper cannot give you. One call per keyword returns it.

This Actor reads [Fujiya Camera](https://www.fujiya-camera.co.jp/) (フジヤカメラ, Nakano — one of Japan's reference used-camera dealers, whose grading is quoted across the trade) and returns **one compact market record per keyword**:

- **`rankStats` — the exact population count and median for every condition rank** (未使用 / A / AB+ / AB / AB- / B / 現状品 / コレクション). Not a sample: each rank is a filter on the search, so its count is the population count and its median is read out of the population
- **`rankPremium`** — how much each rank costs over the cheapest ranked bucket, in percent
- **`usedPriceJpy`** — min / Q1 / median / Q3 / max of the whole used result set, with the basis labelled
- **`newMedianJpy` / `usedVsNewDiscountPct`** — the new-price reference the used gear is discounted against
- **`brandTop`**, **`rankMixSampled`**, plus USD conversion at the current rate
- Optionally every sampled listing (title, brand, price, condition rank, URL)

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` | `["Nikon Z6"]` | Maker, model or mount. Each keyword costs $0.02 |
| `conditionRanks` | `["1001","1003"]` | Optional: `1000` 未使用/未開封品, `1001` A, `1002` AB+, `1003` AB, `1004` AB-, `1005` B, `1006` 現状品, `1007` コレクション. Empty = the whole ladder |
| `includeNewReference` | `true` | Also measure the new/outlet price so the used discount can be reported |
| `maxItemsPerKeyword` | `50` | Listings kept for the brand mix (30–300, 50 per page). Does **not** affect the rank counts, rank medians or quartiles |
| `includeIndividualItems` | `false` | Enable to also get each sampled listing as a record |
| `convertToUsd` | `true` | Adds USD stats at the current exchange rate |

### Why the rank numbers are exact, and where the basis is labelled

The condition rank is a **search filter**, not a label the Actor has to infer. So for each rank:

| Situation | How the median is obtained | `medianBasis` |
|---|---|---|
| The rank has ≤50 listings | The page **is** the population — its median is the population median | `exact` |
| The rank has more | One extra request jumps to the page holding rank ceil(count/2) of a price-ascending sort — that listing **is** the population median | `population_quantiles` |
| Time budget spent, or the page could not be read | Median of the listings that were inspected | `sample` |

The same three-way labelling applies to `usedPriceJpyBasis` for the overall used quartiles. The fallback is the point: if the shop ever changes its sort behaviour, the Actor **stops claiming population figures** instead of quietly returning wrong percentiles.

`brandTop` and `rankMixSampled` are always sample-based (`sampledListings` tells you the size).

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

```json
{
  "type": "market_summary",
  "keyword": "Nikon Z6",
  "totalListingsFound": 1325,
  "usedListingsFound": 665,
  "newListingsFound": 660,
  "sampledListings": 50,
  "usedPriceJpy": { "min": 3300, "q1": 39800, "median": 104500, "q3": 199100, "max": 748000, "count": 665 },
  "usedPriceJpyBasis": "population_quantiles",
  "rankStats": [
    { "rank": "unused", "rankLabel": "未使用/未開封品", "count": 12,  "medianJpy": 268400, "medianBasis": "exact" },
    { "rank": "A",      "rankLabel": "A",              "count": 88,  "medianJpy": 179300, "medianBasis": "population_quantiles" },
    { "rank": "AB",     "rankLabel": "AB",             "count": 234, "medianJpy": 119900, "medianBasis": "population_quantiles" },
    { "rank": "B",      "rankLabel": "B",              "count": 41,  "medianJpy": 74800,  "medianBasis": "exact" }
  ],
  "rankPremium": { "baseRank": "B", "baseMedianJpy": 74800, "premiumPct": { "AB": 60.3, "A": 139.7, "unused": 258.8 } },
  "newMedianJpy": 289080,
  "usedVsNewDiscountPct": 63.9,
  "brandTop": [["Nikon", 47]],
  "checkedAt": "2026-08-01T05:31:12.004Z",
  "sourceUrl": "https://www.fujiya-camera.co.jp/shop/goods/search.aspx?search=x&keyword=Nikon+Z6&ps=50&p=1&sort=4&category=20"
}
```

### A caveat worth stating plainly

`usedVsNewDiscountPct` can come out **negative**. Measured for `Nikon Z6` on 2026-08-01: used median ¥280,500 against a new median of ¥222,750, i.e. −25.9%. That is not a bug — a keyword that names a body also matches accessories (filters, straps, flashes) whose new prices are low, so the "new" side of a loose keyword is not the same product as the "used" side.

Use a keyword specific enough to name one product when you want the discount to mean something, and read `newListingsFound` (7 in that measurement) as the sanity check. 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 PII.** The shop is a single dealer; there are no individual sellers to expose

### Notes on the data

- **`sort` is always sent explicitly.** The shop's default order is おすすめ順 (merchandising-weighted) and would skew every price statistic
- **Ranks are the shop's own ladder,** read from its `secondhand_state` filter. A listing occasionally carries a rank that is not on the filter ladder; `conditionRank` then reports the shop's wording verbatim rather than forcing it into a bucket
- Prices are asking prices including tax as displayed by the shop
- A run costs roughly 1 + 4 + (1–2 per rank) + 1–2 requests per keyword, throttled at 1.2 s. Multi-keyword runs carry a wall-clock budget and set `truncatedForTimeLimit` rather than silently truncating

# Actor input Schema

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

One or more search keywords — a maker, a model or a mount works best (Nikon Z6, EOS R6, SIGMA 24-70, Leica M6). Latin script is indexed; the shop's catalog is bilingual. Each keyword costs $0.02.

## `conditionRanks` (type: `array`):

Which of the shop's condition ranks to measure. Each rank costs 1-2 extra requests, so narrowing this speeds up multi-keyword runs. Codes: 1000=未使用/未開封品, 1001=A, 1002=AB+, 1003=AB, 1004=AB-, 1005=B, 1006=現状品, 1007=コレクション. Leave empty for the whole ladder.

## `includeNewReference` (type: `boolean`):

Also measure the new/outlet price for the same keyword, so the used discount (usedVsNewDiscountPct) can be reported. Costs 1-2 extra requests.

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

How many listings to keep per keyword for the brand mix and the sampled rank mix. The rank counts, rank medians and used quartiles are read from the whole result set and are not affected. Results come 50 per page; this only caps 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, price, condition rank, 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": [
    "Nikon Z6"
  ],
  "conditionRanks": [],
  "includeNewReference": true,
  "maxItemsPerKeyword": 50,
  "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": [
        "Nikon Z6"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpmarketdata/fujiya-camera-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": ["Nikon Z6"] }

# Run the Actor and wait for it to finish
run = client.actor("jpmarketdata/fujiya-camera-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": [
    "Nikon Z6"
  ]
}' |
apify call jpmarketdata/fujiya-camera-market-checker --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ktnx2nyLCDWfKmq2d/builds/ZIDnkyQfat20a6TtU/openapi.json
