TCGPlayer API

TCGPlayer API Documentation

Complete REST access to TCGPlayer's catalog and marketplace data — 9 endpoints covering games, expansions, cards, prices, SKU pricing, sales history, historic prices, and live listings.

Chainable Workflow

How the TCGPlayer API Works

categoryId → groupId → productId → skuId. Each call returns the IDs you need for the next.

1

List Games

/api/v2/games

Returns categoryId for each supported game.

2

Get Expansions

/api/v2/expansions/:categoryId

Use categoryId to fetch every expansion. Each row carries groupId.

3

Get Cards

/api/v2/cards/:groupId

Use groupId to fetch every card in the set. Each row carries productId.

4

Get Prices / SKUs / Listings

/api/v2/prices/:productId

Use productId to fetch prices, SKU prices, sales history, historic prices, or live listings.

9 Endpoints

TCGPlayer API Endpoints

Authenticated via x-api-key.

GET/api/v2/games
Public

List all supported games. Each row carries categoryId for the next step.

GET/api/v2/expansions/:categoryId
Hobby+

Paginated expansions for a game. Each row carries groupId.

GET/api/v2/cards/:groupId
Hobby+

Paginated cards in an expansion with images, names, numbers, rarities. Each row carries productId.

GET/api/v2/prices/:productId
Business+

Latest TCGPlayer prices for a card across all printings (Normal / Foil / 1st Edition / etc).

GET/api/v1/skuprices/:skuId
Unlimited

Per-SKU price for one specific condition + printing + language combination.

GET/api/v1/skuprices/product/:productId
Unlimited

Every SKU price for a card in one call — typically 50-150 SKUs covering all conditions, printings, languages.

GET/api/v2/sales-history/:productId
Business+

Live recent-transactions feed from TCGPlayer marketplace (~100 most recent sales). Includes statistics block.

GET/api/v2/sales-history/:productId/full
Business+

Full historic sales archive — 90+ days of bucketed data. Server-side filters by condition, variant, language, date range. Best for trend charts and per-condition pricing.

GET/api/v2/historic-prices/:productId
Business+

Daily price snapshots over time, broken out per variant (Normal/Foil). Ideal for trend charts.

GET/api/v2/livelistings/:productId
Unlimited

Real-time marketplace listings — every active seller with condition, printing, language, quantity, price, shipping.

Full Schemas

Every Field We Expose

Complete field-by-field reference for every TCGPlayer-source endpoint, so you know exactly what you can build with.

Games

GET /api/v2/games
Public

Top of the catalog tree. One row per supported trading card game.

FieldTypeDescription
categoryIdintegerTCGPlayer category ID — use this to fetch expansions.
gameNamestringHuman-readable name (e.g. "Magic: The Gathering").
gameAbbreviationstringShort code (e.g. "MTG", "POK", "YGO").
gameSeoNamestringURL-safe slug used by TCGPlayer.

Expansions

GET /api/v2/expansions/:categoryId
Hobby+

All expansions (sets) for a game. Use the groupId to drill into cards.

FieldTypeDescription
groupIdintegerTCGPlayer group ID — use this to fetch cards in this set.
groupNamestringInternal group name from TCGPlayer.
expansionNamestringFull set name (e.g. "Crown Zenith").
expansionAbbreviationstringShort set code (e.g. "CRZ").
releasedOnISO dateRelease date of the set.
gameNamestringParent game.
categoryIdintegerParent category ID.

Cards

GET /api/v2/cards/:groupId
Hobby+

Every card (single) in an expansion with metadata and image.

FieldTypeDescription
productIdintegerTCGPlayer product ID — primary key for prices, listings, sales, SKUs.
namestringDisplay name (may include variant suffixes).
cleanNamestringStripped name for matching/joining.
numberstringCollector / set number (e.g. "025/200").
raritystringRarity tier (Common, Rare, Holo Rare, Mythic, Secret, etc.).
imageUrlstringHosted card image URL.
expansionNamestringParent expansion.
gameNamestringParent game.

Prices (per product)

GET /api/v2/prices/:productId
Business+

Latest aggregate prices for a card. Returns one row per printing (subType): Normal, Foil, 1st Edition, etc.

FieldTypeDescription
productIdintegerTCGPlayer product ID.
subTypestringPrinting variant — "Normal", "Foil", "1st Edition", "Holofoil", etc.
marketPricedecimalTCGPlayer's computed market price (recent sales + active listings).
lowPricedecimalLowest currently listed price.
midPricedecimalMedian listing price.
highPricedecimalHighest listed price.
directLowPricedecimalLowest TCGPlayer Direct (verified) price — null if none available.
lastUpdatedISO timestampWhen TCGPlayer last refreshed this row.

SKU Prices (per SKU or per product)

GET /api/v1/skuprices/:skuId · GET /api/v1/skuprices/product/:productId
Unlimited

The most granular pricing tier — one entry per (productId, condition, printing, language) combination. A typical card has 50-150 SKUs.

FieldTypeDescription
skuIdintegerTCGPlayer SKU ID.
productIdintegerParent product ID.
lowPricedecimalLowest current listing for this exact SKU.
lowestShippingdecimalCheapest shipping cost on the lowest listing.
lowestListingPricedecimallowPrice + lowestShipping — landed cost from the cheapest seller.
marketPricedecimalTCGPlayer market price for this exact SKU.
directLowPricedecimalLowest TCGPlayer Direct price for this SKU.
last_updatedISO timestampLast refresh of the SKU price row.

Sales History (Live)

GET /api/v2/sales-history/:productId
Business+

Recent completed sales pulled live from TCGPlayer marketplace transactions (~100 most recent).

FieldTypeDescription
dateISO timestampWhen the sale closed.
marketplacestringAlways "TCGPlayer".
conditionstringCard condition at time of sale (Near Mint, Lightly Played, etc.).
variantstringPrinting variant ("Normal", "Foil", "1st Edition", etc.).
pricedecimalFinal price paid (purchase price + shipping).
statisticsobjectSummary block: avg / median / min / max prices, total sales count, date range.

Sales History (Full Archive — Filterable)

GET /api/v2/sales-history/:productId/full
Business+

90+ days of bucketed sales archive per (condition + variant + language) SKU. Server-side filterable by condition, variant, language, date range. Distinct from the live recent-sales feed above.

FieldTypeDescription
data.summaryobjectAggregate stats: avgMarketPrice, minMarketPrice, maxMarketPrice, totalSalesAllBuckets, totalSalesLastBucket, lastBucketDate, lastUpdated.
data.available.skusarrayEvery (skuId, condition, variant, language) tuple discovered for this product — populate filter dropdowns from one call.
data.available.conditions / variants / languagesstring[]Distinct sorted lists of values present for this product.
data.rows[].skuIdstringTCGPlayer SKU ID this bucket belongs to.
data.rows[].conditionstringNM / LP / MP / HP / Damaged.
data.rows[].variantstringNormal / Foil / 1st Edition / etc.
data.rows[].languagestringEnglish / Japanese / etc.
data.rows[].bucketStartDatedate stringStart of the 3-day bucket (YYYY-MM-DD).
data.rows[].marketPricedecimalTCGPlayer market price snapshot for the bucket.
data.rows[].quantitySoldintegerNumber of units sold in the bucket (0 if no sales).
data.rows[].transactionCountintegerDistinct sale transactions in the bucket.
data.rows[].lowSalePrice / highSalePricedecimalLowest / highest single sale price in the bucket.
data.rows[].lowSalePriceWithShipping / highSalePriceWithShippingdecimalSame low/high but including shipping cost.

Historic Prices

GET /api/v2/historic-prices/:productId
Business+

Daily price snapshots back through the product's tracked history. Top-level prices map is keyed by date (YYYY-MM-DD), then by variant (Normal/Foil).

FieldTypeDescription
productIdintegerTCGPlayer product ID.
createdAtISO timestampWhen tracking began for this product.
prices.<date>.<variant>.lowPricedecimalLowest sold price on that day for that variant.
prices.<date>.<variant>.midPricedecimalMedian sold price on that day for that variant.
prices.<date>.<variant>.highPricedecimalHighest sold price on that day for that variant.
prices.<date>.<variant>.marketPricedecimalTCGPlayer market price snapshot for that day.
prices.<date>.<variant>.directLowPricedecimalLowest TCGPlayer Direct price for the day (may be null).

Live Listings

GET /api/v2/livelistings/:productId
Unlimited

Every active TCGPlayer seller listing for a product, refreshed in real time.

FieldTypeDescription
listingIdstringUnique TCGPlayer listing ID.
sellerNamestringSeller display name.
sellerIdstringSeller account ID.
sellerRatingdecimalSeller star rating.
conditionstringCondition of the listed card.
printingstringPrinting variant of the listed card.
languagestringListing language (English, Japanese, etc.).
listingTypestringStandard, Direct, or other TCGPlayer listing class.
quantityintegerQuantity available from this seller.
pricedecimalPer-unit price from this seller.
shippingPricedecimalShipping cost from this seller.
currencystringAlways "USD".

Example: Per-Product Prices

One row per printing variant, with all five price points and the freshness timestamp.

GET /api/v2/prices/130289
{
  "success": true,
  "data": {
    "productId": 130289,
    "name": "Forest",
    "expansionName": "Magic 2014 (M14)",
    "gameName": "Magic: The Gathering",
    "prices": [
      {
        "subType": "Normal",
        "marketPrice": 0.21,
        "lowPrice": 0.01,
        "midPrice": 0.15,
        "highPrice": 8.00,
        "directLowPrice": 0.10,
        "lastUpdated": "2026-05-06T07:32:29.881Z"
      },
      {
        "subType": "Foil",
        "marketPrice": 0.85,
        "lowPrice": 0.04,
        "midPrice": 0.28,
        "highPrice": 5.99,
        "directLowPrice": null,
        "lastUpdated": "2026-05-06T07:32:29.881Z"
      }
    ]
  }
}

Frequently Asked Questions

What does the TCGPlayer API give me access to?

Everything TCGPlayer surfaces about a product: the catalog tree (categoryId -> groupId -> productId -> skuId), prices at three granularities (per-product, per-SKU, daily historic), real recent sales, and the live seller listings feed. You can build a price tracker, an inventory pricer, an arbitrage scanner, or a market-trend dashboard against the same set of endpoints.

How is per-product pricing different from per-SKU pricing?

Per-product (/prices/:productId) gives one row per printing variant (Normal / Foil / 1st Edition / Holofoil) — this is the headline price you usually see on TCGPlayer. Per-SKU (/skuprices/...) breaks every printing further down by condition (NM / LP / MP / HP / DMG) and language, so a typical card has 50-150 SKU rows. Use per-product for general dashboards, per-SKU when you need to price actual graded inventory.

When should I use sales-history vs sales-history/full vs historic-prices?

Three related but distinct surfaces. /sales-history/:productId is the live recent-transactions feed pulled from TCGPlayer marketplace each call (~100 most recent sales) — best for "what just sold" tickers. /sales-history/:productId/full is the stored archive (90+ days of 3-day buckets per condition+variant+language SKU) with server-side filters — best for trend charts, per-condition pricing, and CSV exports. /historic-prices/:productId is the per-day market-price snapshot collapsed to Foil/Normal — best for clean long-term price trend lines without the per-condition fan-out.

How fresh is the data?

Live listings hit TCGPlayer's marketplace API in real time (seconds-old). Per-product and per-SKU prices refresh on a continuous loop and carry a lastUpdated / last_updated field. Historic prices add a new daily bucket once per day. Sales history pulls the most recent N transactions live on each request.

What plan tier do I need?

/games is public, /expansions and /cards are Hobby+, /prices, /sales-history, and /historic-prices are Business+, /skuprices and /livelistings are Unlimited.