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.
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:
- TCGPlayer prices are current —
updatedAtread2026/08/26on the day of checking. Do not assume they are stale; they are not. - 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. - 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:
type | Name |
|---|---|
oracle_cards | One card per Oracle ID (~24 MB compressed) |
default_cards | One per printing, English preferred |
all_cards | Every printing in every language |
unique_artwork | One per distinct artwork |
rulings | All rulings |
art_tags / oracle_tags | Community 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.gzIf 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 arrayNever 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.
| File | Compressed size | What it is |
|---|---|---|
AtomicCards.json.gz | ~51 MB | One entry per unique card name, printing-independent |
AllPrices.json.gz | ~150 MB | Price history across providers |
AllPricesToday.json.gz | ~5.5 MB | Today’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=2961parameter 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.
| Source | Prices | History | Per-condition | Games |
|---|---|---|---|---|
| pokemontcg.io | Yes (TCGPlayer + Cardmarket) | No | No | Pokémon |
| Scryfall | Daily snapshot | No | No | Magic |
| MTGJSON | Yes, bulk | Yes, bulk | No | Magic |
| lorcana-api.com | None | — | — | Lorcana |
| PriceCharting | Yes | No | By grade | Many |
| TCG API | Yes | Yes | Yes (Pro+) | 54 |
Prices come from TCGPlayer marketplace data, refreshed daily for the top games and every ~3 days across the rest of the catalogue.
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:
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.