# TCGplayer Scraper - Card Prices, Listings & Market Data (`goat255/tcgplayer-scraper`) Actor

Scrape TCGplayer card and sealed product prices without a login. Search any card or browse a whole game, filter by set, rarity and type, and get market price, lowest price with shipping, listing count, card details and the cheapest live offers. Optional price change tracking.

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

## Pricing

from $3.00 / 1,000 products

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

## TCGplayer Scraper - Card Prices, Listings and Market Data

Extract trading card and sealed product prices from the TCGplayer marketplace without a login or API key. Search any card, browse a whole game, or narrow down by set, rarity and product type, and every product comes back in one clean row with its market price, lowest price, lowest price with shipping, live listing count and the cheapest offers on sale right now.

Works for every game on the marketplace, including Pokemon, Pokemon Japan, Magic: The Gathering, Yu-Gi-Oh!, One Piece Card Game, Disney Lorcana, Flesh and Blood, Digimon and Star Wars: Unlimited.

### What it does

- **Search** - every product matching a phrase such as a card name, a set or a sealed product, in the marketplace's own ranking or sorted by best selling, market price, release date or name.
- **Browse a game** - leave the search empty, pick a game, and sweep its catalogue set by set or rarity by rarity.
- **Filters** - game, set, rarity and product type (single cards or sealed product). A filter value that matches nothing is reported in the run log, so a typo never passes silently.
- **Prices** - market price, median listing price, lowest price and lowest price with shipping, all in US dollars.
- **Market depth** - the number of live listings for each product.
- **Cheapest live offers** - price, shipping, condition, printing, language, quantity and seller details for the lowest-priced listings.
- **Card details** - card number, rarity, release date and the game's own attributes (for example HP, energy type, attacks, colour, card type).
- **Price watch** - turn on change tracking and schedule the actor. Each run adds the previous market price, lowest price and listing count, plus the change in each, so you build a price and supply history without any extra tooling.
- **Pagination** - walked automatically, 50 products at a time, until your limit is reached. Duplicates are removed across the whole run.

### Use cases

- Price a collection or a buylist against the live market.
- Track daily price moves and listing counts for the cards you sell.
- Spot underpriced offers by comparing the lowest price with shipping to the market price.
- Feed a price tracker app, a spreadsheet or a dashboard on a schedule.

### Input

| Field | Type | Description |
|---|---|---|
| `searchQueries` | array | Phrases to search. Example: `charizard`, `black lotus`, `booster box`. |
| `productLines` | array | Games to include. Example: `pokemon`, `magic`, `yugioh`, `one piece card game`, `lorcana`. Short forms `mtg`, `ygo`, `fab` work too. |
| `setNames` | array | Sets as the marketplace shows them. Example: `SV03: Obsidian Flames`. |
| `rarities` | array | Rarities as the marketplace shows them. Example: `Special Illustration Rare`. |
| `productTypes` | array | `Cards` for singles, `Sealed Products` for boxes, packs and tins. |
| `sort` | string | `relevance`, `best_selling`, `price_high`, `price_low`, `newest`, `name`. |
| `maxItemsPerSource` | integer | Cap per search phrase (or per game when browsing). Default 100, up to 9,999. |
| `trackChanges` | boolean | Add changes against the previous run with the same watch name. Default off. |
| `watchName` | string | Name of the price watch to compare against. Default `default`. |
| `concurrency` | integer | Search phrases processed in parallel. Default 3. |
| `proxyConfiguration` | object | Optional proxy settings. The default works for most runs. |

At least one of `searchQueries` or `productLines` is required.

#### Example input

```json
{
  "searchQueries": ["charizard", "pikachu"],
  "productLines": ["pokemon"],
  "productTypes": ["Cards"],
  "sort": "price_high",
  "maxItemsPerSource": 200,
  "trackChanges": true,
  "watchName": "pokemon-chase-cards"
}
```

### Output

Each item is one product.

```json
{
  "productId": "100001",
  "productName": "Example Dragon ex - 201/190",
  "productLine": "Pokemon",
  "setName": "Example Set",
  "setCode": "EXS",
  "cardNumber": "201/190",
  "rarity": "Special Illustration Rare",
  "isSealed": false,
  "foilOnly": false,
  "url": "https://www.tcgplayer.com/product/100001/pokemon-example-set-example-dragon-ex-201-190",
  "marketPrice": 94.33,
  "medianListingPrice": 99.5,
  "lowestPrice": 85,
  "lowestPriceWithShipping": 86.49,
  "currency": "USD",
  "totalListings": 212,
  "releaseDate": "2025-08-11T00:00:00Z",
  "attributes": {
    "hp": "330",
    "stage": "Stage 2",
    "energyType": ["Fire"],
    "attack1": "[R] Example Blaze (180)"
  },
  "flavorText": null,
  "description": null,
  "imageUrl": "https://tcgplayer-cdn.tcgplayer.com/product/100001_in_1000x1000.jpg",
  "cheapestListings": [
    {
      "price": 85,
      "shippingPrice": 1.49,
      "priceWithShipping": 86.49,
      "condition": "Near Mint",
      "printing": "Holofoil",
      "language": "English",
      "quantity": 1,
      "sellerName": "Example Card Shop",
      "sellerRating": 99.9,
      "sellerSales": "10000+",
      "goldSeller": true,
      "verifiedSeller": true,
      "directSeller": false,
      "listedAt": null
    }
  ],
  "searchQuery": "charizard",
  "position": 1,
  "scrapedAt": "2026-10-12T09:00:00.000Z",
  "previousMarketPrice": 91.2,
  "marketPriceChange": 3.13,
  "marketPriceChangePercent": 3.4,
  "previousLowestPrice": 82,
  "lowestPriceChange": 3,
  "previousTotalListings": 220,
  "totalListingsChange": -8,
  "previousSnapshotAt": "2026-10-11T09:00:00.000Z",
  "isNewInWatch": false
}
```

The `previous...`, `...Change` and `isNewInWatch` fields appear only when change tracking is on. A product with no recent sales has a `null` market price; its lowest price and listings are still filled in.

If a search finds nothing, the dataset gets one row with `"ok": false` and `"error": "no_results"`, so an empty search is never mistaken for a failed run.

### Notes

- Prices are in US dollars, as listed on the US marketplace.
- Any single search can reach at most 9,999 results. For a full catalogue sweep, split it by set or by rarity.
- Change tracking compares runs with the same watch name. Use a separate watch name for each list you schedule.
- To improve our actors we collect anonymized usage telemetry (run stats and input patterns). No personal account data is collected.

**Found this useful?** [Leave a quick review](https://apify.com/goat255/tcgplayer-scraper/reviews). It takes a few seconds and it genuinely helps other people find the actor.

# Actor input Schema

## `searchQueries` (type: `array`):

Card names, set names or product names to search for, the same way you would type them into the marketplace search box. Each phrase is walked through as many result pages as your per-search limit allows. Leave empty and pick a game below to browse a whole game instead. Example: charizard, black lotus, booster box.

## `productLines` (type: `array`):

Restrict results to one or more games. Use the game name as the marketplace writes it, for example pokemon, pokemon japan, magic, yugioh, one piece card game, lorcana, flesh and blood, digimon card game, star wars unlimited. Short forms such as mtg, ygo and fab also work.

## `setNames` (type: `array`):

Restrict results to one or more sets, written as the marketplace shows them. Example: SV03: Obsidian Flames, Base Set, SWSH: Crown Zenith. A set name that matches nothing is ignored and reported in the run log.

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

Restrict results to one or more rarities, written as the marketplace shows them. Example: Special Illustration Rare, Mythic, Secret Rare.

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

Restrict results to singles or sealed product. Use Cards for single cards and Sealed Products for booster boxes, packs, tins and collections.

## `sort` (type: `string`):

Order of the results. Relevance is the marketplace's own ranking for the search phrase.

## `maxItemsPerSource` (type: `integer`):

Cap on products returned for each search phrase (or for the whole game when browsing). Results are walked 50 at a time until this is reached or the results run out. The marketplace serves at most 9,999 results for any one search, so split very large sweeps by set or rarity.

## `trackChanges` (type: `boolean`):

Compare every product with the previous run that used the same watch name, and add the previous market price, lowest price and listing count plus the change in each. Schedule the actor daily to get a price and supply history.

## `watchName` (type: `string`):

Name of the price watch to compare against when change tracking is on. Use a different name for each watch list you schedule, for example modern-staples or sealed-pokemon.

## `concurrency` (type: `integer`):

How many search phrases to process in parallel.

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

Optional proxy settings. The default works for most runs.

## Actor input object example

```json
{
  "searchQueries": [
    "charizard"
  ],
  "productLines": [],
  "setNames": [],
  "rarities": [],
  "productTypes": [],
  "sort": "relevance",
  "maxItemsPerSource": 20,
  "trackChanges": false,
  "watchName": "default",
  "concurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `products` (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 = {
    "searchQueries": [
        "charizard"
    ],
    "maxItemsPerSource": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("goat255/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 = {
    "searchQueries": ["charizard"],
    "maxItemsPerSource": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("goat255/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 '{
  "searchQueries": [
    "charizard"
  ],
  "maxItemsPerSource": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call goat255/tcgplayer-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,goat255/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/MVLYKn2i1neKAAunZ/builds/FofXv0bliK57fI76a/openapi.json
