# Japan Used Camera Market — Multi-shop Search, Stats & Alerts (`keiya_dev/japan-used-camera-market`) Actor

Search, benchmark and monitor Japan's used camera shops (Fujiya Camera, more coming) with a unified schema: normalized condition grades, JPY/USD prices, stock status. Monitor mode emits only new/price-drop/sold-out events and can POST them to Slack/Discord/n8n.

- **URL**: https://apify.com/keiya_dev/japan-used-camera-market.md
- **Developed by:** [Keiya](https://apify.com/keiya_dev) (community)
- **Categories:** E-commerce, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Japan Used Camera Market — Multi-shop Search, Stats & Alerts

### Quick start

1. Click **Try for free** / open the Actor in Apify Console.
2. Keep the prefilled input (`{"mode": "search", "sources": ["fujiya", "sanpou", "naniwa", "hardoff"], "keywords": ["Leica"], "maxItems": 10}`) or type your own keywords.
3. Press **Start** — listings from all four shops appear in the Output tab in about 20–30 seconds. (Without `maxItems` the default is 200 matches, which can mean reading most of the shops' listing pages, a minute or two.)

Search, benchmark and **monitor Japan's used camera shops** — second-hand cameras and lenses from Tokyo's specialist shops — with one unified schema.
Built by someone who reads Japanese and knows what *AB-* vs *現状品* actually means.

Japan is the world's deepest used-camera market (Leica, Voigtländer, Contax, Nikon F, Hasselblad, Fujifilm…), but the shops only publish in Japanese, each with its own condition grading. This Actor turns them into clean JSON/CSV you can pipe into Google Sheets, n8n, Slack, Discord or your own pricing model. Use it to buy a used camera from Japan online, to check the Japan price of a Leica Q3, M11 or M6 before you order, or to source used Japanese cameras for resale.

### What you can do

| Mode | What it does | Who uses it |
|---|---|---|
| **search** | Pull listings matching keywords/brand/condition grade/price. Sold-out listings are excluded unless `includeSoldOut: true`. | eBay "From JAPAN" sellers sourcing stock, collectors hunting a specific body, proxy-buying services |
| **stats** | Model stats of in-stock listings: count, min / median / max in JPY and USD, broken down by shop and condition grade, plus the cheapest listing URL. | KEH / MPB / regional dealers benchmarking against Tokyo prices, anyone pricing a trade-in |
| **monitor** | Run on a schedule. Keeps a snapshot and emits **only what changed**: `NEW`, `PRICE_DROP`, `PRICE_UP`, `SOLD_OUT` (sold-out listings are tracked internally regardless of `includeSoldOut`; `maxItems` is ignored). Optional webhook → Slack / Discord / n8n / Make / Zapier. | Anyone who wants to be first on a one-of-a-kind listing the minute it's listed |
| **history** | Daily price history per model: min / median / count for each day, by shop and condition grade, from stored daily snapshots — no crawling. Needs `keywords`, `brands` or `models`. History is still being collected (since 2026-11-05), so treat the first 30 days as indicative. | Anyone timing a purchase or sale, dealers tracking how Tokyo prices move |

#### Shops

| Shop | Status | Listings | Notes |
|---|---|---|---|
| **Fujiya Camera** (`fujiya`, フジヤカメラ, Nakano Tokyo) | ✅ live | ~3,500 | full used stock; grade, brand, price, stock status (incl. 売り切れ), image |
| **Sanpou Camera** (`sanpou`, 三宝カメラ, Jiyugaoka Tokyo) | ✅ live | ~1,300 | full used stock (cameras, lenses, accessories); grade, brand, price, stock status (incl. 売り切れ), image |
| **Naniwa / Lemon-sha / Takachiho** (`naniwa`, カメラのナニワ・レモン社) | ✅ live — **new arrivals only (~200–300)** | ~200–300 | the shop's full-stock search is closed to crawlers (robots.txt), so only its "new used arrivals" list is read. Great for monitor mode; not a full price benchmark |
| **Hard Off Off Mall** (`hardoff`, ハードオフ オフモール, nationwide stores) | ✅ live | ~16,000 | cameras and lenses **on sale** ("販売中のみ"), newest first; Hard Off's own N / S / A / B / C / D / ジャンク ranks. Sold listings drop out of the list, so a Hard Off `SOLD_OUT` is detected on full scans. In the price history: weekly (Sundays) |
| Kitamura (ネット中古) | ✗ not crawlable | | listings are rendered by JavaScript from a private, key-protected API |
| Kitamura Camera Shinjuku (北村写真機店) | ✗ no online listing | | its ~5,000 used items are sold in store / via Kitamura's site |

Want a shop added? Open an issue on the Actor page — if it's publicly crawlable it goes on the roadmap.

### Condition grades, normalized

Every shop's label is mapped to one scale so you can compare across shops:

`NEW` > `A` > `AB+` > `AB` > `AB-` > `B` > `ASIS` (sold as-is, no warranty) > `PARTS` (parts / collection only)

The raw label is always kept in `conditionGradeRaw`. Shops use the same letters differently, so each is mapped with its own published scale:

| Shop | Raw labels → normalized |
|---|---|
| Fujiya | 未使用/未開封 → NEW · A · AB+ · AB · AB- · B · 現状品 → ASIS · コレクション/ジャンク → PARTS |
| Sanpou | 未使用品, 逆輸入品 → NEW · S → A · A → AB+ · AB → AB · B → B · C (major parts missing) → ASIS |
| Naniwa | 新同 → NEW · A → A · AB+ → AB+ · AB → AB · B+ → AB- · B, B- → B · C (some faults) → ASIS · ジャンク → PARTS |
| Hard Off | N (new, sealed) → NEW · S (like new) → A · A (barely used) → AB+ · B (normal use, few marks) → AB · C (visible use, many marks) → AB- · D (heavy wear) → B · ジャンク → PARTS |

### Input

```json
{
  "mode": "search",
  "sources": ["fujiya", "sanpou", "naniwa"],
  "keywords": ["Leica M", "Noctilux"],
  "grades": ["A", "AB+", "AB"],
  "maxPriceJpy": 600000,
  "maxItems": 100
}
```

Monitor example (schedule it hourly):

```json
{
  "mode": "monitor",
  "sources": ["fujiya", "sanpou", "naniwa"],
  "keywords": ["Voigtlander", "Leica"],
  "alertWebhookUrl": "https://hooks.slack.com/services/XXX/YYY/ZZZ",
  "alertEvents": ["NEW", "PRICE_DROP"]
}
```

The first monitor run only builds the snapshot (full scan) and emits nothing; every run after that emits monitor events. Only the event types listed in `alertEvents` are written to the dataset, charged and sent to the webhook.

**Snapshots per shop and filter.** Each monitor keeps one snapshot per shop, keyed by its filters (`keywords`, `brands`, `grades`, `minPriceJpy`, `maxPriceJpy`, `includeSoldOut`), so schedules with different filters never interfere. If you run several schedules with the *same* filters, give each a distinct `monitorId`.

**Request budget.** Every request is one listing page (Fujiya 50 listings, Sanpou 28, Naniwa ~25, Hard Off 30), read newest-first; product pages are never opened. By default monitor stops paging once it hits 20 already-known listings in a row in each list — **an hourly monitor on all four shops is normally 7 requests** (Fujiya 1, Sanpou 3 — cameras, lenses, accessories — Naniwa 1, Hard Off 2 — cameras, lenses). That catches every `NEW` listing and any sell-out or price change on those first pages, but changes to older listings further down can be missed — set `"fullScan": true` to read all pages (**full scan ≈ 670 requests, ~25 minutes**: Fujiya ≈ 70, Sanpou ≈ 50, Naniwa ≈ 8, Hard Off ≈ 540 — leave Hard Off out of `sources` for a ~4-minute full scan; and the only mode in which a listing that vanished from the listing pages counts as `SOLD_OUT`). A good setup is a frequent light monitor plus one daily full scan.

Measured run times (Fujiya, direct connection, Nov 2026): run time grows with how many listing pages it takes to find `maxItems` matches — **search "Leica", 20 listings ≈ 11 pages ≈ 40 s**; no keyword filter, 20 listings ≈ 1 page; **full scan ≈ 65 s**.

### Output schema

```json
{
  "source": "fujiya",
  "sourceName": "Fujiya Camera",
  "sourceItemId": "C2120187965805",
  "url": "https://www.fujiya-camera.co.jp/shop/g/gC2120187965805/",
  "imageUrl": "https://…/C2120187965805.jpg",
  "title": "FUJIFILM X-T20 ボディ ブラック",
  "brand": "FUJIFILM",
  "brandJa": "フジフイルム",
  "model": "fujifilm x-t20",
  "variant": null,
  "conditionGrade": "AB-",
  "conditionGradeRaw": "AB-",
  "priceJpy": 92950,
  "priceUsd": 619.67,
  "fxJpyPerUsd": 150,
  "inStock": true,
  "category": "used",
  "scrapedAt": "2026-11-04T00:00:00.000Z"
}
```

Monitor events add `eventType`; `PRICE_DROP` / `PRICE_UP` add `previousPriceJpy`, `priceChangeJpy`, `priceChangePct`, and a `SOLD_OUT` for a listing that flipped to 売り切れ adds `previousPriceJpy`. A `SOLD_OUT` for a listing that disappeared from the listing pages (full scan only) carries the last known fields from the snapshot. Listings first seen already sold out are not reported as `NEW`.

There are no `serial`, `listedAt` or condition-note fields: those live on product pages, which this Actor does not open (see Limitations).

Model stats rows look like:

```json
{
  "model": "leica m6",
  "brand": "Leica",
  "sampleTitle": "M6 ボディ ブラック",
  "count": 7,
  "variants": [],
  "minJpy": 398000, "medianJpy": 455000, "maxJpy": 528000,
  "minUsd": 2653.33, "medianUsd": 3033.33,
  "cheapestUrl": "https://…",
  "cheapestGrade": "AB-",
  "byGrade": { "A": { "count": 2, "minJpy": 498000, "medianJpy": 513000, "maxJpy": 528000 }, "AB": { … } },
  "byShop":  { "fujiya": { "count": 7, … } },
  "fxJpyPerUsd": 150,
  "computedAt": "2026-11-04T00:00:00.000Z"
}
```

Stats only count in-stock listings with a price; `includeSoldOut` has no effect in stats mode.

### Price history since 2026-11-05

The Actor's own scheduled full scans store the **complete inventory** of each shop (every listing, price, grade and stock flag): **Fujiya, Sanpou and Naniwa every day**, and **Hard Off once a week, on Sundays** (its ~16,000 listings take ~540 pages, about 17 minutes) as one compressed snapshot per shop per day. It keeps them indefinitely. `history` mode reads those snapshots, so it costs no shop requests and returns in seconds:

```json
{ "mode": "history", "keywords": ["Leica M6"], "days": 90 }
```

or by exact model key (as shown in the `model` field of stats mode):

```json
{ "mode": "history", "models": ["fujifilm x100vi", "nikon zf"], "days": 30 }
```

One row per model × day:

```json
{
  "model": "leica m6", "date": "2026-11-20", "brand": "Leica",
  "count": 3, "minJpy": 390000, "medianJpy": 430000, "maxJpy": 460000,
  "byShop":  { "fujiya": { "count": 2, "minJpy": 390000, "medianJpy": 425000, "maxJpy": 460000 }, "sanpou": { "count": 1, … } },
  "byGrade": { "A": { … }, "AB+": { … }, "AB": { … } },
  "byShopGrade": { "fujiya": { "A": { … }, "AB": { … } }, "sanpou": { "AB+": { … } } }
}
```

- Only in-stock listings with a price count. Days on which a model wasn't listed have no row.
- **Hard Off is weekly:** its numbers appear only on Sunday rows (`byShop.hardoff`). On the other days a row covers Fujiya, Sanpou and Naniwa only, so compare Hard Off week to week, not day to day.
- **History is still being collected.** Snapshots start on 2026-11-05, so for the first 30 days the series is short and should be treated as indicative only.
- Naniwa contributes its new-arrivals list only (see Shops), so Naniwa numbers describe what was newly listed, not its full stock.
- Model keys are recomputed when you query, so grouping improvements apply to old days too.

### Pricing

Pay per event, no subscription:

| Event | Price |
|---|---|
| `listing` (search mode, per listing) | $0.003 |
| `model-stats` (stats mode, per model row) | $0.005 |
| `alert-event` (monitor mode, per monitor event: NEW / PRICE_DROP / PRICE_UP / SOLD_OUT) | $0.01 |
| `history-row` (history mode, per model × day row) | see the Actor's Pricing tab |

A monitor run that finds nothing new costs you only platform compute (~$0.01–0.03). Apify's free plan includes $5/month of usage, enough for hourly monitoring of a keyword set.

### Integrations

- **Google Sheets**: Apify → Integrations → Google Sheets, pick the dataset.
- **Slack / Discord**: paste the incoming-webhook URL into `alertWebhookUrl`; messages are pre-formatted.
- **n8n / Make / Zapier**: use the Apify node with this Actor, or point `alertWebhookUrl` at your workflow's webhook trigger.
- **AI agents**: see the next section.

### AI agents (MCP)

A dedicated MCP server, [`@keiya-dev/japan-used-market-mcp`](https://github.com/Enu27/japan-used-market-mcp) (open source, MIT), gives Claude, Cursor and other MCP clients tools backed by this Actor. The same server also covers used watches (`"market": "watch"`); cameras are the default, so no `market` is needed here.

| Tool | Mode |
|---|---|
| `search_listings` | search |
| `price_stats` | stats |
| `price_history` | history |
| `start_monitor` | creates a scheduled monitor (Task + Schedule) in your Apify account |
| `list_markets` | shops and grades per market (no run) |

**Claude Desktop**: add this to `claude_desktop_config.json`. On macOS it is `~/Library/Application Support/Claude/claude_desktop_config.json`; on Windows, `%APPDATA%\Claude\claude_desktop_config.json`. Then restart the app:

```json
{
  "mcpServers": {
    "japan-used-market": {
      "command": "npx",
      "args": ["-y", "@keiya-dev/japan-used-market-mcp"],
      "env": { "APIFY_TOKEN": "apify_api_..." }
    }
  }
}
```

Get the token at Apify Console → Settings → API & Integrations. Runs are billed to your Apify account, as with any other run.

Then just ask: *"What's the cheapest AB-or-better Leica M6 in Tokyo shops right now?"*, *"Compare Nikon Zf prices by shop and grade"*, *"How has the median X100VI price moved over the last 30 days?"*, *"Watch for new Voigtländer lenses under ¥80,000 and post them to my Slack webhook."*

**Claude Code**: `claude mcp add japan-used-market -e APIFY_TOKEN=apify_api_... -- npx -y @keiya-dev/japan-used-market-mcp`

**Remote / HTTP clients**: run `npx -y @keiya-dev/japan-used-market-mcp --http --port 3000`. The endpoint is `/mcp` (Streamable HTTP); send your token as `Authorization: Bearer <APIFY_TOKEN>`.

Already using the old `@keiya-dev/japan-used-camera-mcp`? It keeps working (it now starts the new server); switch the package name when convenient.

The generic [Apify MCP server](https://mcp.apify.com) also works: add the Actor `keiya_dev/japan-used-camera-market` as a tool.

### Limitations & fair use

- Prices are tax-included retail (税込) in JPY; USD is a live mid-market conversion (frankfurter.app) for convenience, not a quote. If that FX API is unreachable, the run still succeeds and uses a **fallback rate of 150 JPY per USD** (logged as a warning, visible in `fxJpyPerUsd`); set `jpyPerUsd` to use your own rate.
- Naniwa is new arrivals only (~200–300 listings at a time), so a model missing from Naniwa in search/stats doesn't mean Naniwa doesn't have it.
- Hard Off is read with its "on sale only" filter (its sort and search parameters are closed to crawlers by robots.txt, its default order is newest first), so Hard Off listings are always in stock and a sold one simply disappears.
- Fujiya, Sanpou and Naniwa keep sold listings on their listing pages for a while (marked 売り切れ / SOLD OUT, Sanpou without a price); `inStock` is read from that badge. `SOLD_OUT` fires when a listing flips to sold out on a page the run reads, or, on a full scan only, when it disappears from the listing pages.
- Serial numbers, listing dates and seller notes live on product pages, which this Actor does not open (Fujiya serves them behind a bot-protection JS challenge). Everything comes from the listing pages. Use the time of the `NEW` event as the listing date.
- Crawling is polite (concurrency 2, 300–700 ms random delay, no login, public listing pages only). If the shop's bot protection challenges a run, a listing page can't be loaded, or the shop changes its page layout, the run fails with a message saying what happened and what to do next — without writing partial data, charging, or updating the monitor snapshot. Please don't hammer monitor mode more than every 15 minutes — nothing changes faster than that.
- This Actor is not affiliated with any of the shops.

### Changelog

- **0.4** — Fourth shop: Hard Off Off Mall (cameras + lenses on sale, ~16,000 listings, its N–D / ジャンク ranks mapped to the common scale). Model keys keep the model code when a title is nothing but a code (e.g. "WG-30").
- **0.3** — `history` mode: daily price history per model by shop and grade, from daily full-inventory snapshots (collected since 2026-11-05).
- **0.2** — Two more shops: Sanpou Camera (full stock) and Naniwa / Lemon-sha / Takachiho (new arrivals). Per-shop condition-grade scales. All three shops are selected by default.
- **0.1** — Fujiya Camera: search / stats / monitor, webhook for monitor events.

### Related

- [Japan Used Watch Market](https://apify.com/keiya_dev/japan-used-watch-market): the same four modes for used watches (WATCHNIAN / Ippuukishi, Hard Off Off Mall), with reference numbers and box / warranty card. Grand Seiko, Rolex, Omega and more.

***

If this saved you a trip to Nakano, a review on the Store helps others find it.

# Actor input Schema

## `mode` (type: `string`):

search = return listings. stats = model stats of in-stock listings (count, min / median / max by shop & condition grade). monitor = compare against the last run and emit only NEW / PRICE_DROP / PRICE_UP / SOLD_OUT events (use with a Schedule). history = daily min / median / count per model, by shop and condition grade, from stored daily snapshots (no crawling; needs keywords, brands or models). History is collected since 2026-11-05 — treat the first 30 days as indicative.

## `sources` (type: `array`):

Which shops to search. Naniwa only exposes its new-arrivals list (~200–300 listings) to crawlers, so it is best for monitor mode; Fujiya, Sanpou and Hard Off (cameras + lenses on sale, ~16,000) are searched in full.

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

Only keep listings whose title/brand contains any of these (case-insensitive, matches Japanese or English). Leave empty to get everything. Examples: "Leica M6", "Voigtlander", "X100", "Noctilux".

## `brands` (type: `array`):

Optional brand filter (English brand name as the shop prints it, e.g. Leica, Nikon, Canon, SONY, Voigtlander, HASSELBLAD).

## `models` (type: `array`):

History mode: only these exact model keys, as shown in the "model" field of stats mode (e.g. "leica m6", "fujifilm x100vi", "nikon zf"). Combine with or use instead of keywords.

## `days` (type: `integer`):

History mode: how many days back to return, counting today (JST).

## `minPriceJpy` (type: `integer`):

Drop listings cheaper than this.

## `maxPriceJpy` (type: `integer`):

Drop listings more expensive than this.

## `grades` (type: `array`):

Keep only these normalized grades. NEW > A > AB+ > AB > AB- > B > ASIS (as-is, no warranty) > PARTS (collection / parts only).

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

Search mode: also return listings marked sold out (売り切れ) — the shop keeps them on its listing pages for a while. Stats mode always aggregates in-stock listings only. Monitor mode always tracks sold-out listings internally to detect SOLD_OUT.

## `fullScan` (type: `boolean`):

Monitor mode only. Off (default): pages are read newest-first and the crawl stops after 20 already-known listings in a row (normally 1 request per hourly run; each page = 50 listings) — catches NEW listings, but price changes / sell-outs of older listings are missed. On: scan every listing page (Fujiya ≈ 70, Sanpou ≈ 50, Naniwa ≈ 8, Hard Off ≈ 540 requests — about 25 minutes with all four) to catch every PRICE_DROP / PRICE_UP / SOLD_OUT. Tip: schedule a frequent light run plus a daily full scan.

## `monitorId` (type: `string`):

Optional. Each monitor keeps its own snapshot, keyed by its filters (keywords, brands, grades, price range, includeSoldOut). Set a monitorId to separate several schedules that use the same filters, or to keep the snapshot when you edit the filters. Letters, digits and - \_ . only.

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

Stop after this many matching listings across all selected shops (0 = no limit). Fujiya has ~3,500 used listings, Sanpou ~1,300, Naniwa new arrivals ~200–300, Hard Off ~16,000 cameras and lenses. Ignored in monitor mode.

## `jpyPerUsd` (type: `number`):

Exchange rate used for priceUsd. Leave empty to fetch the current rate automatically.

## `alertWebhookUrl` (type: `string`):

Optional. In monitor mode every batch of monitor events is POSTed as JSON to this URL. Works with Slack/Discord incoming webhooks, n8n, Make, Zapier.

## `alertEvents` (type: `array`):

Monitor mode: only these event types are written to the dataset, charged, and sent to the webhook.

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

Off by default (direct connection). Datacenter proxies are more likely to be challenged by the shop's bot protection; switch to residential proxy only if runs get blocked.

## Actor input object example

```json
{
  "mode": "search",
  "sources": [
    "fujiya",
    "sanpou",
    "naniwa",
    "hardoff"
  ],
  "keywords": [
    "Leica"
  ],
  "days": 90,
  "includeSoldOut": false,
  "fullScan": false,
  "maxItems": 10,
  "alertEvents": [
    "NEW",
    "PRICE_DROP"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items. Shape depends on mode — see the dataset schema (listing / model stats row / monitor event / history row).

## `overview` (type: `string`):

No description

## `stats` (type: `string`):

No description

## `history` (type: `string`):

No description

# 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 = {
    "sources": [
        "fujiya",
        "sanpou",
        "naniwa",
        "hardoff"
    ],
    "keywords": [
        "Leica"
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("keiya_dev/japan-used-camera-market").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 = {
    "sources": [
        "fujiya",
        "sanpou",
        "naniwa",
        "hardoff",
    ],
    "keywords": ["Leica"],
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("keiya_dev/japan-used-camera-market").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 '{
  "sources": [
    "fujiya",
    "sanpou",
    "naniwa",
    "hardoff"
  ],
  "keywords": [
    "Leica"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call keiya_dev/japan-used-camera-market --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,keiya_dev/japan-used-camera-market"
        }
    }
}
```

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/OEpGmF6el3UG9oug0/builds/koCl3etxttJgHfiAI/openapi.json
