Skip to content
· 8 min read

Card API Endpoint Reference: What Each One Returns (2026)

What pokemontcg.io/v2/cards, Scryfall bulk data, MTGJSON AtomicCards, lorcana-api and PriceCharting actually return — payload fields, price coverage and freshness, all checked live.

referenceapipokemonmagic the gatheringlorcanapricing

If you got here by pasting an endpoint URL into a search box, you wanted one thing: to know what that endpoint returns before you build against it.

Every payload below was fetched live on 26 August 2026 and the field lists are copied from the actual responses, not from documentation. Where an API returns no prices, or stale ones, it says so with the timestamp that proves it.

api.pokemontcg.io/v2/cards

The Pokémon TCG API. Free, API key optional for low volume.

It does return prices — this is the most common misconception about it. Each card carries both a tcgplayer and a cardmarket block:

{
"id": "hgss4-1",
"name": "Aggron",
"tcgplayer": {
"url": "...",
"updatedAt": "2026/08/26",
"prices": {
"holofoil": { "low": , "mid": , "high": , "market": , "directLow": },
"reverseHolofoil": { "low": , "mid": , "high": , "market": , "directLow": }
}
},
"cardmarket": { "updatedAt": "2026/07/01", "prices": { } }
}

Full card field list: artist, attacks, cardmarket, convertedRetreatCost, evolvesFrom, flavorText, hp, id, images, legalities, name, nationalPokedexNumbers, number, rarity, resistances, retreatCost, set, subtypes, supertype, tcgplayer, types, weaknesses.

Three things to know before you build on it:

  1. TCGPlayer prices are currentupdatedAt read 2026/08/26 on the day of checking. Do not assume they are stale; they are not.
  2. Cardmarket prices were not. The same card reported cardmarket.updatedAt: "2026/07/01" — about eight weeks behind. If you are pricing for a European audience off this block, check that timestamp yourself.
  3. There is no price history. You get one snapshot per card per finish. To chart a card over time you have to poll and store it yourself.

One reliability note, honestly scoped: two of three requests I made returned HTTP 500 before one succeeded. That is a three-request sample at a single moment and is not enough to call the API unreliable — but build in a retry, because I needed one.

data.scryfall.io bulk files

Requested via https://api.scryfall.com/bulk-data, which returns the current download URI for each dataset. As of 26 August 2026 there are seven, all rebuilt that morning:

typeName
oracle_cardsOne card per Oracle ID (~24 MB compressed)
default_cardsOne per printing, English preferred
all_cardsEvery printing in every language
unique_artworkOne per distinct artwork
rulingsAll rulings
art_tags / oracle_tagsCommunity tagging data

The format changed and this trips people up. The bulk object now exposes jsonl_download_uri pointing at a .jsonl.gz file — newline-delimited JSON, gzipped:

https://data.scryfall.io/default-cards/default-cards-20260826090541.jsonl.gz

If you are searching for data.scryfall.io default-cards … json and finding a dead link, that is why. Read it line by line rather than JSON.parse-ing the whole file:

const meta = await (await fetch('https://api.scryfall.com/bulk-data')).json();
const entry = meta.data.find(b => b.type === 'default_cards');
// entry.jsonl_download_uri → .jsonl.gz — one JSON object per line, not an array

Never hardcode the dated filename. It changes every build. Resolve it from /bulk-data each time.

Scryfall’s card objects carry a prices block (a daily snapshot per finish), but no history and no per-condition breakdown.

mtgjson.com/api/v5/AtomicCards.json

MTGJSON ships versioned bulk files, not a query API. Current build at the time of checking was 5.3.0+20260826, verifiable at /api/v5/Meta.json.

FileCompressed sizeWhat it is
AtomicCards.json.gz~51 MBOne entry per unique card name, printing-independent
AllPrices.json.gz~150 MBPrice history across providers
AllPricesToday.json.gz~5.5 MBToday’s prices only

AllPrices.json.gz is the one people miss — MTGJSON does publish price history, unlike Scryfall. The cost is that it is a 150 MB download you host and index yourself, refreshed on MTGJSON’s daily build cadence rather than queried per card.

Every file is also served uncompressed at the same path without .gz. Take the gzipped one.

api.lorcana-api.com/bulk/cards

Returns 2,694 records in a single call, free and unauthenticated.

Fields: Artist, Body_Text, Card_Num, Classifications, Color, Cost, Date_Added, Date_Modified, Franchise, Image, Inkable, Lore, Name, Rarity, Set_ID, Set_Name, Set_Num, Strength, Type, Unique_ID, Willpower.

There are no price fields. Cost is ink cost — the resource you pay to play the card, not money. If you are building a Lorcana collection valuator, this endpoint gives you everything about the card and nothing about its value. The Lorcana API guide covers pairing it with a pricing source.

PriceCharting price-history

There is no such endpoint, which is why searching for it returns nothing useful. PriceCharting’s own API documentation states plainly:

Historic prices and historic sales are not supported.

PriceCharting API documentation

Their API returns current values per condition grade. If your requirement is a time series, PriceCharting is not the source, and no combination of parameters will make it one.

mp-search-api.tcgplayer.com/v1/search/request

This is TCGPlayer’s internal search endpoint — the one their own website calls. It is unauthenticated and reachable, which is why developers find it after discovering that TCGPlayer’s official API is closed to new applicants.

I am not going to publish a request body for it, and you should think hard before building on it:

  • There is no stability contract. It is undocumented, which means it can change shape or disappear in any deploy, with no notice, no changelog and no deprecation window. Note the mpfev=2961 parameter in the URLs floating around — that is a build number, and it moves.
  • There is no grant of use. Reachable is not the same as licensed. Check TCGPlayer’s terms yourself before shipping anything commercial against it.
  • There is no support. When it breaks at 2am, there is no status page and nobody to ask.
  • Unbounded request volume gets you blocked, and the block lands on your production IP.

If you need TCGPlayer marketplace pricing with an actual contract behind it, that is what this API is for — see the comparison below.

Where TCG API fits

We cover the gap the list above keeps hitting: prices with history, across games, from one integration.

SourcePricesHistoryPer-conditionGames
pokemontcg.ioYes (TCGPlayer + Cardmarket)NoNoPokémon
ScryfallDaily snapshotNoNoMagic
MTGJSONYes, bulkYes, bulkNoMagic
lorcana-api.comNoneLorcana
PriceChartingYesNoBy gradeMany
TCG APIYesYesYes (Pro+)54

Prices come from TCGPlayer marketplace data, refreshed daily for the top games and every ~3 days across the rest of the catalogue.

Terminal window
curl "https://api.tcgapi.dev/v1/cards/12345/history?days=90" \
-H "X-API-Key: YOUR_KEY"

Already have a TCGPlayer product ID from a CSV or a scrape? Resolve it directly without maintaining a mapping table:

Terminal window
curl "https://api.tcgapi.dev/v1/cards/tcgplayer/187172" \
-H "X-API-Key: YOUR_KEY"

Get a free API key — 100 requests a day, no credit card. See the price endpoints for the full history and change-tracking reference, or the ID resolution guide for bulk lookups.


Every payload above was verified live on 26 August 2026. Field lists and timestamps come from actual responses. If one of these APIs has changed since, tell us on Discord and we will recheck and update the page.

Ready to get started?

Free tier includes 100 requests per day. No credit card required.