# Anime Figure Aftermarket Search (`angelic_saucer/figure-aftermarket-search`) Actor

Search AmiAmi, Mandarake and eBay US for anime figures in one call. Normalized listings with JPY + USD prices, unified condition grades and JAN barcodes. The Japan-vs-US price spread in one sorted list.

- **URL**: https://apify.com/angelic\_saucer/figure-aftermarket-search.md
- **Developed by:** [JC](https://apify.com/angelic_saucer) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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.

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

## Anime Figure Aftermarket Search

One schema across the anime figure aftermarket. Single-site scrapers give you one shop's HTML;
this gives you **three markets normalized into one price-sorted list** — so the cheapest copy of a
figure is row one, and the Japan-vs-US arbitrage spread is visible at a glance.

Covers **AmiAmi pre-owned**, **Mandarake**, and **eBay US** (official Browse API).

### A real result

`nendoroid madoka`, August 2026:

| Source | Price | Condition | Item |
|---|---|---|---|
| Mandarake | **$12.59** (¥2,000) | good | Nendoroid Madoka Kyouno 265 |
| AmiAmi | $35.75 (¥5,680) | — | Nendoroid Kyoko Sakura |
| eBay US | $69.73 (¥11,079) | new | Nendoroid Sakura |
| eBay US | **$94.99** (¥15,092) | new | Nendoroid 174 Madoka Kaname |

Same franchise, same line, **7.5× spread** between the cheapest Japanese listing and the most
expensive US one. That gap is the product.

### What you get per listing

- **Price in JPY and USD**, converted at the live rate on every run
- **Unified condition scale** — `new` / `like-new` / `good` / `fair` / `junk` / `unknown` — plus
  the source-native grades (AmiAmi's `ITEM:A / BOX:B`), so shops that grade differently can be
  compared directly. See *Condition coverage* below for which sources supply it
- **JAN barcode** (enable *Fetch JAN barcodes*) — join the same figure across shops, or against a
  catalog like MyFigureCollection
- **Original retail price** where available, so the aftermarket premium is computable
- Maker, stock status, image URL, direct product URL, holding shop (Mandarake)

### What it's for

- **Arbitrage** — buy in Japan, sell in the US, with the spread already calculated
- **Collection valuation** — price what you own against live listings, not stale guides
- **Deal alerts** — schedule it and diff the results
- **Agent / LLM pipelines** — structured JSON, not HTML you have to parse

### Input

```json
{
  "keywords": "nendoroid madoka",
  "sources": ["amiami", "mandarake", "ebay"],
  "maxResultsPerSource": 50,
  "fetchJanCodes": true
}
```

> **Tip:** `fetchJanCodes` also fills in AmiAmi's condition grades, not just barcodes. Leave it off
> for the fastest run; turn it on when you care about condition or need to match figures across
> shops.

### Condition coverage

Condition is reported per source, and the sources genuinely differ — `unknown` means the shop did
not publish a grade, never that the item is unremarkable:

| Source | Condition available? |
|---|---|
| **eBay US** | Yes, on every listing (`New`, `Like New`, `Used`, `For parts`, …) |
| **AmiAmi** | Yes — real per-unit grades (`ITEM:A / BOX:B`), but only with `fetchJanCodes: true`, since they live on the detail page |
| **Mandarake** | **No.** Their search results carry no condition field, so these rows are `unknown` |

Sold-out and in-stock are separate from condition and always populated, via `inStock`.

### Sources

| Source | What it covers | Access |
|---|---|---|
| AmiAmi | pre-owned Japanese stock | JSON API |
| Mandarake | Japanese aftermarket, incl. rarities | HTML, session-warmed |
| eBay US | live US listings | official eBay Browse API |

### Reliability

AmiAmi sits behind bot protection that occasionally challenges shared cloud IPs. In testing on the
current build, **6 of 7 platform runs returned full AmiAmi results**; the challenge is random per
run rather than persistent, and the actor now retries on a fresh proxy session when it happens.
Mandarake and eBay are unaffected. If a run does come back light on AmiAmi, the log says so — just
re-run.

### Fair use

Requests are rate-limited and polite. All data comes from public listing pages. You are charged per
listing returned, so a search that finds nothing costs nothing beyond the actor start.

# Actor input Schema

## `keywords` (type: `string`):

Figure name, character, or line to search for (e.g. 'nendoroid madoka').

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

Which shops to search.

## `maxResultsPerSource` (type: `integer`):

Maximum number of listings to return from each source.

## `fetchJanCodes` (type: `boolean`):

Fetch AmiAmi item detail pages. This is the only source of JAN barcodes AND of AmiAmi's per-unit condition grades (ITEM:A / BOX:B) - with it off, every AmiAmi row is returned as condition 'unknown'. Costs about one extra second per AmiAmi result; turn it off for the fastest possible run.

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

Proxy used for AmiAmi requests (AmiAmi returns empty results to datacenter IPs without one).

## Actor input object example

```json
{
  "keywords": "nendoroid madoka",
  "sources": [
    "amiami",
    "mandarake",
    "ebay"
  ],
  "maxResultsPerSource": 50,
  "fetchJanCodes": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

One row per aftermarket listing across AmiAmi, Mandarake and eBay US, normalized to a single schema: price in JPY and USD at the run's live exchange rate, condition mapped to one scale across all three shops, plus JAN barcodes when the fetchJanCodes input is enabled. Sorted cheapest first, so row one is the best price found for the search.

# 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": "nendoroid madoka",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("angelic_saucer/figure-aftermarket-search").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": "nendoroid madoka",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("angelic_saucer/figure-aftermarket-search").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": "nendoroid madoka",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call angelic_saucer/figure-aftermarket-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,angelic_saucer/figure-aftermarket-search"
        }
    }
}

```

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/mhWg7WykI71Xo5ZH6/builds/jDOei24Z2f7S9558Z/openapi.json
