# TCGplayer Price Scraper – Pokémon, MTG & Yu-Gi-Oh Card Prices (`scrapeworkshq/tcgplayer-scraper`) Actor

TCGplayer price scraper & TCGplayer API alternative: market, low & mid card prices per condition and printing for Pokémon, Magic: The Gathering, Yu-Gi-Oh!, One Piece, Lorcana and more. Listing counts, 30-day sales, set, rarity. Price-change alerts. No login.

- **URL**: https://apify.com/scrapeworkshq/tcgplayer-scraper.md
- **Developed by:** [Scrapeworks HQ](https://apify.com/scrapeworkshq) (community)
- **Categories:** E-commerce, Games
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

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

## TCGplayer Price Scraper & API Alternative – Pokémon, MTG & Yu-Gi-Oh Card Prices by Condition

Get **TCGplayer card prices** for **Pokémon, Magic: The Gathering, Yu-Gi-Oh!, One Piece, Disney Lorcana, Flesh and Blood, Digimon, sports cards** and every other TCGplayer product line. You get **market, low and mid prices for each condition** (Near Mint, Lightly Played, Moderately Played, Heavily Played, Damaged) and printing (Normal, Foil, Holofoil, 1st Edition…), listing counts, recent sales, set, rarity, card number, images and product URLs.

No TCGplayer API key, no login and **no seller personal data**. Export to JSON, CSV, Excel or use the Apify API.

### 🚀 Quick start (60 seconds)

1. Click **Try for free** – the input is prefilled with a working example.
2. Press **Start**. A small run finishes in seconds and costs fractions of a cent.
3. Open the **Output** tab (table view) and export **CSV, Excel, JSON** or connect Google Sheets.

```json
{
  "searchKeywords": [
    "charizard"
  ],
  "maxResultsPerSearch": 10,
  "sortBy": "price-desc"
}
```

#### Sample output

| productName | setName | rarity | marketPrice | lowestPrice | totalListings |
|---|---|---|---|---|---|
| Charizard | Base Set | Holo Rare | 954.65 | 180 | 134 |
| Charizard ex | SV: Obsidian Flames | Double Rare | 2.10 | 1.50 | 410 |

### Why this TCGplayer price scraper (TCGplayer API alternative)?

| | This Actor | Typical TCGplayer scrapers |
|---|---|---|
| Market price **per condition** (NM/LP/MP/HP/DMG) | ✅ | ❌ one price per product |
| Low & **mid (median) listing price per condition** | ✅ exact | ❌ |
| Listing count per condition | ✅ | ❌ |
| Sales in last 30/90/180/365 days per condition (qty, low, high, last sale date) | ✅ | partial |
| Filter by **game, set, rarity, product type** | ✅ | ❌ keywords only |
| Product URLs / IDs as input | ✅ | ❌ |
| Seller names, IDs, ratings | ❌ never collected (privacy) | ✅ |
| Price | **from $0.80 / 1,000 products** | $2.00+ / 1,000 |

### Use cases – card price checker, price guide & price alerts

- 📈 **Price tracking** – schedule daily runs to build your own TCGplayer price history.
- 💵 **Buylist & arbitrage** – compare NM vs LP prices, market vs lowest listing.
- 🏪 **Store inventory pricing** – price singles by condition from TCGplayer market data.
- 📊 **Collection valuation** – feed a list of product URLs and get current values.
- 🤖 **Data for apps, bots and spreadsheets** – Google Sheets, Make, Zapier, n8n, API.

### Input

| Field | Description |
|---|---|
| `searchKeywords` | Card / product names, e.g. `charizard`, `black lotus`, `blue-eyes white dragon` |
| `productUrls` | TCGplayer product URLs (`https://www.tcgplayer.com/product/42382/...`) or IDs |
| `games` | `pokemon`, `magic` (`mtg`), `yugioh`, `one-piece`, `lorcana`, `flesh-and-blood`, `digimon`, `pokemon-japan`, … |
| `sets` | Set names, e.g. `Base Set`, `SWSH: Crown Zenith`, `Double Masters 2022` |
| `rarities` / `productTypes` | e.g. `Secret Rare`; `Cards` (singles only) or `Sealed Products` |
| `sortBy` | relevance, price high→low, price low→high, name |
| `maxResultsPerSearch` / `maxResultsTotal` | Limits |
| `includeConditionPrices` | Per-condition prices (default on). Turn off for fast, cheap catalog scraping |
| `priceHistoryRange` | Sales window: month, quarter, semi-annual, annual |
| `englishOnly` | Ignore non-English SKUs |

Filters work with or without keywords — e.g. every Pokémon Base Set single sorted by price:

```json
{ "games": ["pokemon"], "sets": ["Base Set"], "productTypes": ["Cards"], "sortBy": "price-desc", "maxResultsPerSearch": 102 }
```

### Output example

```json
{
  "productId": 42382,
  "productName": "Charizard",
  "game": "Pokemon",
  "setName": "Base Set",
  "setCode": "BS",
  "rarity": "Holo Rare",
  "number": "004/102",
  "marketPrice": 954.65,
  "lowestPrice": 180,
  "totalListings": 134,
  "url": "https://www.tcgplayer.com/product/42382/pokemon-base-set-charizard",
  "imageUrl": "https://tcgplayer-cdn.tcgplayer.com/product/42382_in_1000x1000.jpg",
  "conditionSummary": [
    { "condition": "Near Mint", "listingCount": 17, "lowPrice": 1100, "lowPriceWithShipping": 1100, "midPriceWithShipping": 1750.99 },
    { "condition": "Lightly Played", "listingCount": 47, "lowPrice": 485, "lowPriceWithShipping": 485, "midPriceWithShipping": 575.95 }
  ],
  "conditions": [
    { "printing": "Holofoil", "condition": "Near Mint", "language": "English", "marketPrice": 954.65,
      "sales": { "range": "month", "quantitySold": 5, "transactions": 5, "lowSalePrice": 500, "highSalePrice": 1500, "lastSaleDate": "2026-10-13" } }
  ],
  "printingPrices": [ { "printing": "Holofoil", "marketPrice": 954.65, "listedMedianPrice": 600 } ],
  "scrapedAt": "2026-10-21T21:10:00.000Z"
}
```

Field notes: `marketPrice` is TCGplayer's market price (based on recent sales). `conditionSummary` uses *all* live listings for each condition: exact count, lowest price, and the median ("mid") listing price including shipping. `conditions[].lowPrice/midPrice` are computed from the cheapest sampled listings of that SKU.

### ⭐ Unique: Monitor mode, CSV-ready output & webhook summary

Build a **price tracker** in two clicks: schedule the Actor with `monitorMode: "changes"` and a `monitorKey` per watchlist. Each run returns only cards whose market/low/median price or listing count moved, with `previousPrice`, `priceChange` and `priceChangePct`. Unchanged cards are free.

- **Monitor mode** (`monitorMode`: `all` | `changes` | `onlyNew`, plus `monitorKey`) – cross-run dedupe and field-level diffs (`changeType`, `changedFields`, `changes`, `firstSeenAt`). Skipped items cost **$0**.
- **Flat / CSV-ready output** (`outputFormat: "flat"`) – one column per field, perfect for Excel and Google Sheets.
- **Run summary** – a free `SUMMARY` record in the run's key-value store (also linked in the Output tab) and optionally POSTed to `summaryWebhookUrl`.
- **Changes** dataset view – see what's new/changed at a glance.

### 💰 Pricing (pay per result)

| Event | Price |
|---|---|
| Run start | $0.001 |
| Product (basic prices) | **$0.80 / 1,000** |
| Product + condition/printing prices | **$1.50 / 1,000** |

Typical TCGplayer Actors charge $2–$32 / 1,000 – this one is ≥25% cheaper.

🎁 **Sweetener:** in Monitor mode you only pay for new/changed items, and duplicates within a run are never charged. Run summary + webhook are free.

### Speed & politeness

The Actor uses the same public JSON endpoints as tcgplayer.com, with a global rate limit (default 120 requests/min), limited concurrency, and exponential back-off with `Retry-After` support. Basic mode needs 1 request per 50 products; condition mode about 3–12 requests per product.

### FAQ

**Do I need a TCGplayer account or API key?** No. Only publicly visible data is used.

**Is seller data collected?** No. Listings are read only to compute aggregated counts and prices; seller names, IDs, ratings and addresses are discarded and never stored.

**Is it legal?** It collects public pricing data. Respect TCGplayer's terms and applicable law in how you use the data.

**I get 403 / 429 errors.** Lower `maxRequestsPerMinute` or enable Apify Proxy.

This Actor is not affiliated with or endorsed by TCGplayer or eBay.

### 🔌 Integrations & API

Works with Zapier, Make, n8n, Google Sheets, Slack, Airbyte, LangChain/LlamaIndex and the Apify MCP server (AI agents).

**JavaScript**

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('scrapeworkshq/tcgplayer-scraper').call({"searchKeywords": ["charizard"], "maxResultsPerSearch": 10, "sortBy": "price-desc"});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**Python**

```python
from apify_client import ApifyClient
client = ApifyClient('<APIFY_TOKEN>')
run = client.actor('scrapeworkshq/tcgplayer-scraper').call(run_input={"searchKeywords": ["charizard"], "maxResultsPerSearch": 10, "sortBy": "price-desc"})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

**cURL (sync, returns items)**

```bash
curl -X POST 'https://api.apify.com/v2/acts/scrapeworkshq~tcgplayer-scraper/run-sync-get-dataset-items?token=<APIFY_TOKEN>&format=csv' \
  -H 'content-type: application/json' -d '{"searchKeywords": ["charizard"], "maxResultsPerSearch": 10, "sortBy": "price-desc"}'
```

### ❓ More FAQ

**Can I track price history?**\
Yes – Monitor mode keeps the last seen prices per watchlist and outputs the difference every run; the SUMMARY record counts price drops/rises.

**Does it scrape seller or buyer data?**\
No, only public product and price data.

**How does Monitor mode work?**\
The Actor remembers the IDs and key fields of items it returned before (in a named key-value store in *your* account, keyed by `monitorKey`). Next run, each item gets `changeType` = `new` / `changed` / `unchanged` plus a `changes` diff. In *Only new* / *Only new or changed* modes, the rest is skipped **and not charged**.

**How do I get a clean CSV / Excel / Google Sheet?**\
Set **Output format → Flat / CSV-ready**. Nested objects become `dot.columns` and lists are joined with `|`, so every export is one row per item with no JSON blobs.

**Can I get notified when a run finishes?**\
Set **Summary webhook URL** (Zapier/Make/n8n catch hook, Slack workflow, your API). You receive one compact JSON: counts, new/changed, price drops/rises, dataset ID. Or use Apify's native webhooks/integrations.

**How do I limit cost?**\
Use the max-results inputs and Apify's *Maximum cost per run*. The Actor stops cleanly when the limit is reached.

Found a bug or need a field? Open an issue on the **Issues** tab – we usually reply within 24 h.

### Changelog

- **2026-10-21** – Monitor mode (new/changed only, free skips), flat CSV-ready output, SUMMARY record + webhook, Changes view.

# Actor input Schema

## `searchKeywords` (type: `array`):

Card or product names to search, e.g. "charizard", "lightning bolt". Leave empty to browse by game/set filters only.

## `productUrls` (type: `array`):

TCGplayer product pages (https://www.tcgplayer.com/product/42382/...) or bare product IDs.

## `games` (type: `array`):

Filter by game, e.g. pokemon, magic (or mtg), yugioh, one-piece, lorcana, flesh-and-blood, digimon, pokemon-japan.

## `sets` (type: `array`):

Filter by set name as shown on TCGplayer, e.g. "Base Set", "SWSH: Crown Zenith", "Double Masters 2022".

## `rarities` (type: `array`):

Exact rarity names, e.g. "Secret Rare", "Holo Rare", "Mythic".

## `productTypes` (type: `array`):

e.g. "Cards" (singles only) or "Sealed Products".

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

Sort order of search results.

## `maxResultsPerSearch` (type: `integer`):

Per keyword (or per filter-only browse).

## `maxResultsTotal` (type: `integer`):

0 = no overall limit.

## `includeConditionPrices` (type: `boolean`):

Market / low / mid price, listing count and recent sales for every condition (NM, LP, MP, HP, DMG) and printing. ~5–12 extra requests per product; turn off for fast bulk catalog scraping.

## `priceHistoryRange` (type: `string`):

Window for per-condition sales stats.

## `conditionListingSample` (type: `integer`):

Listings read (cheapest first) to compute low & mid prices. 0 skips listing stats.

## `englishOnly` (type: `boolean`):

Ignore non-English SKUs/listings in condition prices.

## `includeCardAttributes` (type: `boolean`):

Card text, HP, types, attacks, colors, etc. when TCGplayer provides them.

## `maxConcurrency` (type: `integer`):

Parallel products processed.

## `maxRequestsPerMinute` (type: `integer`):

Global polite rate limit across all requests.

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

Usually not needed. Use Apify Proxy if you see 403/429 errors.

## `monitorMode` (type: `string`):

Remembers items from previous runs (per Monitor key) and adds changeType = new/changed/unchanged plus a field-level diff. In the two 'only' modes, unchanged/old items are not output and not charged.

## `monitorKey` (type: `string`):

Name of the memory used by Monitor mode. Use a different key per schedule/task (e.g. 'daily-pokemon'), so separate watchlists don't mix.

## `outputFormat` (type: `string`):

Flat makes CSV/Excel/Google Sheets exports one clean column per field.

## `summaryWebhookUrl` (type: `string`):

At the end of the run, POST a compact JSON summary (counts, new/changed, price drops, dataset ID) to this URL – e.g. Zapier/Make/n8n catch hook or Slack workflow. Free.

## Actor input object example

```json
{
  "searchKeywords": [
    "charizard",
    "lightning bolt"
  ],
  "sortBy": "relevance",
  "maxResultsPerSearch": 10,
  "maxResultsTotal": 0,
  "includeConditionPrices": true,
  "priceHistoryRange": "month",
  "conditionListingSample": 50,
  "englishOnly": false,
  "includeCardAttributes": true,
  "maxConcurrency": 4,
  "maxRequestsPerMinute": 120,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "monitorMode": "off",
  "monitorKey": "default",
  "outputFormat": "full"
}
```

# Actor output Schema

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

All scraped items in the default dataset

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

No description

## `summary` (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 = {
    "searchKeywords": [
        "charizard",
        "lightning bolt"
    ],
    "maxResultsPerSearch": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapeworkshq/tcgplayer-scraper").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 = {
    "searchKeywords": [
        "charizard",
        "lightning bolt",
    ],
    "maxResultsPerSearch": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapeworkshq/tcgplayer-scraper").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 '{
  "searchKeywords": [
    "charizard",
    "lightning bolt"
  ],
  "maxResultsPerSearch": 10
}' |
apify call scrapeworkshq/tcgplayer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapeworkshq/tcgplayer-scraper"
        }
    }
}
```

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/KpNPhcsdoeIDJCksf/builds/GDNNm5lSgDd1mbmAl/openapi.json
