TCGplayer Price Monitor avatar

TCGplayer Price Monitor

Pricing

from $1.00 / 1,000 run starts

Go to Apify Store
TCGplayer Price Monitor

TCGplayer Price Monitor

Monitor TCGplayer market prices and listed medians per product/printing, with run-over-run change detection. Pure JSON API, no browser.

Pricing

from $1.00 / 1,000 run starts

Rating

0.0

(0)

Developer

Vic

Vic

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

23 days ago

Last modified

Categories

Share

Monitors TCGplayer market price and listed median price for trading-card products (Pokemon, Magic: The Gathering, Yu-Gi-Oh!, Lorcana, One Piece, and more) — one row per product x printing (Normal / Foil / 1st Edition ...), with optional run-over-run change detection so you only react to prices that actually moved.

Pure JSON-over-HTTP (no browser), built for cheap scheduled monitoring runs.

Quickstart (3 lines)

  1. Enter one or more search queries (e.g. charizard ex obsidian flames) or paste known product IDs / product URLs (e.g. 610532 or https://www.tcgplayer.com/product/610532).
  2. Run the Actor — each product yields one dataset row per printing with marketPrice and listedMedianPrice.
  3. Schedule it (e.g. daily) with a fixed productIds list: with enableChangeDetection on, every row carries priceChanged, prevMarketPrice, and marketPriceDelta versus your previous run.

What it does

  • Resolves search queries via TCGplayer's product search (paginated, capped by maxResultsPerQuery).
  • Accepts explicit productIds (skips search; metadata is resolved in one batched lookup) — the reliable mode for scheduled monitoring.
  • Fetches per-printing price points for every unique product: marketPrice, listedMedianPrice, buylistMarketPrice.
  • Joins in search metadata: set name, rarity, card number, lowest listed price, listing count.
  • Change detection: keeps a snapshot of your last run in a named key-value store (tcgplayer-price-monitor-state) and emits priceChanged / prevMarketPrice / prevListedMedianPrice / marketPriceDelta / changedAt.
  • Contract test on every run: a known-good product's response shape is validated; on upstream schema drift the run warns loudly (status message + one uncharged warning row) instead of silently emitting garbage.

What it does NOT do

  • No seller-level listings or seller-filtered pages (those are disallowed by tcgplayer.com robots.txt — we do not touch them).
  • No buying, sniping, or cart automation.
  • No historical backfill — price history accrues from your own scheduled runs.
  • No fabricated values: if TCGplayer has no market price for a printing, you get null (a price of 0 is also treated as "no price").

Input examples

One-shot search:

{
"queries": ["charizard ex obsidian flames"],
"productLine": "pokemon",
"maxResultsPerQuery": 25
}

Scheduled daily monitor of a fixed list (recommended):

{
"productIds": ["610532", "113670", "https://www.tcgplayer.com/product/477236"],
"printings": ["Foil"],
"enableChangeDetection": true
}

Output example (real rows from a test run, 2026-08-29)

{
"productId": 610532,
"productName": "Teal Mask Ogerpon ex - 177/131",
"setName": "SV: Prismatic Evolutions",
"productLine": "Pokemon",
"rarity": "Hyper Rare",
"number": "177/131",
"printingType": "Foil",
"marketPrice": 8.79,
"listedMedianPrice": 9.86,
"buylistMarketPrice": null,
"lowestPrice": 6.78,
"listingCount": 189,
"sealed": false,
"url": "https://www.tcgplayer.com/product/610532",
"scrapedAt": "2026-08-29T14:32:23.077Z",
"prevMarketPrice": null,
"prevListedMedianPrice": null,
"marketPriceDelta": null,
"priceChanged": false,
"changedAt": null
}

On a later run, after the market price moved:

{
"productId": 610532,
"printingType": "Foil",
"marketPrice": 8.79,
"prevMarketPrice": 7.50,
"marketPriceDelta": 1.29,
"priceChanged": true,
"changedAt": "2026-08-29T14:33:16.634Z"
}

(second example abbreviated; all rows always contain the full field set)

Notes on fields:

  • priceChanged is true when marketPrice or listedMedianPrice differs from the previous snapshot for that product+printing.
  • On the very first run there is no previous snapshot, so all rows have priceChanged: false and prev*: null.
  • productTypeName is emitted for completeness but TCGplayer's search payload currently does not populate it; use the sealed boolean to separate sealed products from singles.

Pricing (pay per event)

EventPriceCharged when
Run start$0.001once per run
Product price row$0.003for every product x printing row delivered to the dataset
Price change row$0.004 (additional)only for delivered rows with priceChanged: true

Failed fetches, filtered-out printings, nonexistent/unknown product IDs, and the schema-drift warning row are never charged.

Worked example: monitoring 500 rows daily (a row = one product x printing; use the printings filter to get exactly one row per product) where ~10% move per day costs about 500 x $0.003 + 50 x $0.004 + $0.001 = **$1.70/day ($51/month)**. A daily 100-row watchlist under the same assumptions is $0.34/day ($10/month).

Scheduling recipe

  1. Create an Apify Schedule (e.g. daily at 09:00) pointing at this Actor with your fixed productIds input.
  2. Add an Actor integration/webhook on run success and consume the dataset filtered to priceChanged = true (the dataset API supports field filtering), or plug the dataset into Make/Zapier/Google Sheets.
  3. The change snapshot lives in the named key-value store tcgplayer-price-monitor-state in your account — delete it to reset change detection.

Measured on the Apify platform (4 GB, default build). The cost driver is one pricepoints request per product (3 concurrent, polite):

run shapeduration (measured 2026-09-03)recommended timeout
10-20 products (typical watchlist)~20-40 s300s+
~300 products~2 mindefault 3600s
~500 products (max per query)~3-4 mindefault 3600s

Bound time and cost with maxResultsPerQuery or by listing explicit productIds.

Timeouts, partial runs, and resurrection (no double billing)

The Actor watches its own run timeout and stops gracefully ~20-30s before the platform would kill it: it flushes a delivery checkpoint into the run's key-value store, finishes as SUCCEEDED, and sets a status message like Partial: N of ~M rows delivered....

  • Resurrect the same run (Runs > resurrect, pick a longer timeout) and it continues where it left off - already-delivered rows are never re-pushed and never re-charged. The flat run-start fee is charged at most once per run.
  • Rows are charged strictly after they are written to the dataset: a row that never reached your dataset is never billed.

Data source & respect

Data comes from TCGplayer's public, unauthenticated JSON endpoints (the same ones the website itself uses) over plain HTTP — no browser, no login, no CAPTCHA circumvention. The Actor is deliberately polite: low concurrency, spacing between requests, exponential backoff on 429/5xx, and a descriptive User-Agent identifying this Actor. It never crawls HTML pages and never touches seller-filtered pages, which tcgplayer.com's robots.txt disallows. Prices are public market data; no personal information is collected.

Limitations

  • These are unofficial endpoints; TCGplayer can change them without notice. A schema contract test runs on every run and flags drift immediately; we target same-day fixes, 14 days worst case.
  • Search relevance is TCGplayer's — broad queries return whatever the site's search ranks first (may include sealed products; filter with sealed/productLine).
  • lowestPrice / listingCount come from the search payload and are null for products whose metadata lookup failed.
  • If more than 30% of requests to an endpoint fail, the run aborts with a clear error rather than emitting partial garbage.

Support

Use the Issues tab on this Actor's page — reports are answered within 24 hours, and breaking upstream changes are fixed within 14 days (usually much faster).