Skip to content
pokemontcgapi.com

TCGplayer price data

TCGplayer prices for Pokémon cards, without a TCGplayer API key

US guide figures in dollars, low and market, per printing, read for up to 50 cards in one request. Signing up is one call with no application form, and a table keyed on TCGplayer ids joins on a field of the card.

Currency
USD, as published
Variants
LOW and MARKET, per printing
Basis
GUIDE: a published reference figure
Batch
Up to 50 card ids per request, 4 credits per 25

Developers look for TCGplayer prices because that is the figure the US hobby quotes. The rows with source: "TCGPLAYER" are those figures: low and market, in USD, one row per printing, so a holofoil and a reverse holo of the same card stay separate.

They arrive in the same response as the European rows and the EUR index. An app with users on both sides of the Atlantic shows each of them their own market from one call, instead of converting one currency into the other and being wrong for everybody.

One call, and what comes back

Two cards in one request, kept to the US guide rows with source=TCGPLAYER. Drop the filter and the same call returns every source your plan covers.

GET/v1/prices/current4 credits · from Trialfull reference
request.tsrequest.py
curl -s -G "https://api.pokemontcgapi.com/v1/prices/current" \
  --data-urlencode "ids=bs-4,bs-2" \
  --data-urlencode "source=TCGPLAYER" \
  -H "X-Api-Key: $PTCG_API_KEY"
const url = new URL("https://api.pokemontcgapi.com/v1/prices/current");
url.searchParams.set("ids", "bs-4,bs-2");
url.searchParams.set("source", "TCGPLAYER");

const res = await fetch(url, {
  headers: { "X-Api-Key": process.env.PTCG_API_KEY ?? "" },
});

if (!res.ok) {
  const { error } = await res.json();
  throw new Error(`${error.code}: ${error.message} (${error.request_id})`);
}

const { data, meta } = await res.json();
import os, httpx

res = httpx.get(
    "https://api.pokemontcgapi.com/v1/prices/current",
    params={"ids": "bs-4,bs-2", "source": "TCGPLAYER"},
    headers={"X-Api-Key": os.environ["PTCG_API_KEY"]},
)
res.raise_for_status()
payload = res.json()
response.json
{
  "data": [
    {
      "card_id": "bs-4",
      "index": {
        "eur": 556.23,
        "as_of": "2026-09-02",
        "sample_n": 16,
        "by_locale": [
          {
            "locale": "en",
            "printing": null,
            "eur": 556.23,
            "as_of": "2026-09-02",
            "sample_n": 16
          },
          {
            "locale": "fr",
            "printing": null,
            "eur": 900.58,
            "as_of": "2026-09-02",
            "sample_n": 3
          },
          {
            "locale": "de",
            "printing": null,
            "eur": 399.95,
            "as_of": "2026-09-02",
            "sample_n": 5
          },
          {
            "locale": "es",
            "printing": null,
            "eur": 1313.14,
            "as_of": "2026-09-02",
            "sample_n": 8
          },
          {
            "locale": "it",
            "printing": null,
            "eur": 400.64,
            "as_of": "2026-09-02",
            "sample_n": 11
          }
        ]
      },
      "quotes": [
        {
          "source": "TCGPLAYER",
          "variant": "LOW",
          "basis": "GUIDE",
          "amount": 510,
          "currency": "USD",
          "locale": "en",
          "condition": null,
          "printing": "HOLOFOIL",
          "grading": null,
          "as_of": "2026-07-30",
          "sample_n": null,
          "provenance": "TCGplayer"
        }
      ]
    },
    {
      "card_id": "bs-2",
      "index": {
        "eur": 181.35,
        "as_of": "2026-09-02",
        "sample_n": 16,
        "by_locale": [
          {
            "locale": "en",
            "printing": null,
            "eur": 181.35,
            "as_of": "2026-09-02",
            "sample_n": 16
          },
          {
            "locale": "fr",
            "printing": null,
            "eur": 350,
            "as_of": "2026-09-02",
            "sample_n": 1
          },
          {
            "locale": "de",
            "printing": null,
            "eur": 95.13,
            "as_of": "2026-09-02",
            "sample_n": 4
          },
          {
            "locale": "es",
            "printing": null,
            "eur": 240.64,
            "as_of": "2026-09-02",
            "sample_n": 5
          },
          {
            "locale": "it",
            "printing": null,
            "eur": 130.63,
            "as_of": "2026-09-02",
            "sample_n": 11
          }
        ]
      },
      "quotes": [
        {
          "source": "TCGPLAYER",
          "variant": "LOW",
          "basis": "GUIDE",
          "amount": 125,
          "currency": "USD",
          "locale": "en",
          "condition": null,
          "printing": "HOLOFOIL",
          "grading": null,
          "as_of": "2026-07-30",
          "sample_n": null,
          "provenance": "TCGplayer"
        }
      ]
    }
  ],
  "requested": 2,
  "found": 2
}

Moving an existing integration

If your code stores card ids in the set-number form, those resolve directly, including the historical aliases, and GET /v1/cards/batch reports the ones it cannot resolve instead of dropping them. tcgplayer_id is a field of the card where the pairing is known, so a table keyed on TCGplayer product ids can be joined once the cards are read; there is no search by marketplace id.

The price object is flat and explicit: amount and currency rather than a nested map keyed by printing name. A row you do not understand is a row you can skip, and a new printing never breaks your parser.

What a nightly refresh costs

Reading a 5,000-card collection through /v1/prices/current, 50 ids a call, is 800 credits a night. Developer (€29/month) carries 50,000 credits a month, and GET /v1/changes lets you skip the cards that did not move. The trial covers the same routes with 800 credits, enough to run the job a few times before you decide.

What it is not

Read this before you build on it. Every line here is a support ticket somebody else already opened.

This is not the TCGplayer API
No listings, orders, inventory or seller tools. It serves price data with attribution for applications that display or analyse card values.
Guide figures, one point a day
Rows are published once a day, no sooner than 24 hours after the source, and carry the day they refer to in as_of. Check it before you call a number current.
Western printings
These rows exist for the cards the US guide lists, which is mostly the international print line. The coverage page shows what each print region holds.

Questions people ask before signing up

Is this the official TCGplayer API?
No, and it does not try to be: pokemontcgapi.com is independent of TCGplayer, which appears here as the stated source of a guide figure. Selling, buying or managing inventory on TCGplayer is their platform, not this API.
Can I look a card up by TCGplayer product id?
Not directly. tcgplayer_id is a field of the card where the pairing is known, so you can join on it after reading the cards, but searches go by name, set, number and the other catalogue fields. Reading a whole set is one paginated call.
Do you have both low and market price?
Yes. They are separate rows, variant LOW and variant MARKET, each per printing, in USD, with the day they refer to.
Do I get EUR prices too?
Yes, in the same response: Cardmarket and CardTrader rows in EUR and a composite EUR index. Nothing is converted between currencies. Cardmarket price data

Keep reading