Trading Card Scanner API
A trading card scanner API takes a photo of a card and tells your app exactly which card it is. With TCG API, one request to POST /v1/identify reads a card, graded slab or sealed product and returns the matching catalog item, its TCGPlayer ID and, if you ask, its current prices, for every game in the catalog.
Why building a card scanner is hard
Recognising "a Charizard" is easy. Recognising which Charizard is the part that matters, because the price depends on it.
- The same art is printed many times. 1st Edition and Unlimited, holo and reverse holo, prerelease stamps, retailer exclusives and reprints share one picture. An image match alone picks one of them and can be wrong by hundreds of dollars.
- Every game prints numbers differently.
087/147,OP03-045,SR14-EN027,DG/EN-S03-E028. A scanner has to know each format and the catalog has to store it the same way. - A match is only useful with an ID and a price. Recognition services return a name; your app still has to map it to a product it can price, list or store.
How the scan works
- Send one photo as a file upload, base64 JSON or raw image bytes (JPEG, PNG or WebP, up to 8 MB). Phone photos work as they are.
- The photo is read like a person would read it: name, collector number or card code, set, edition stamp, foil, language, and the grade on a slab.
- The read is matched against the catalog by printed number first, then name, set and stamp, so the answer is a real product with a TCGPlayer ID.
- You get a status and ranked candidates:
matchedwhen exactly one printing fits,ambiguouswhen several do,retakewhen the photo isn't good enough,not_foundorunsupported.
Scan a card in a few lines
The same call from a terminal and from a browser or Node app. include=prices adds the top match's prices at no extra charge.
curl -X POST "https://api.tcgapi.dev/v1/identify?include=prices" \
-H "X-API-Key: YOUR_KEY" \
-F "[email protected]" async function scanCard(file) {
const form = new FormData();
form.append("image", file); // a File from <input type="file" accept="image/*" capture>
const res = await fetch("https://api.tcgapi.dev/v1/identify?include=prices", {
method: "POST",
headers: { "X-API-Key": API_KEY },
body: form,
});
const { data, meta } = await res.json();
if (data.status === "matched") {
const card = data.candidates[0];
return { card_id: card.card_id, name: card.name, set: card.set.name, prices: card.prices };
}
if (data.status === "retake") throw new Error(data.message); // e.g. glare over the number
return { choose: data.candidates }; // ambiguous: let the user pick the printing
} What comes back
A real response for a photo of Darkrai from Burning Shadows, shortened to the first candidate. card_id works with every other endpoint, and suggested_printing picks the printing the photo shows.
{
"data": {
"status": "matched",
"read": { "game": "pokemon", "name": "Darkrai", "number": "87/147", "finish": "holo", "stamp": null },
"candidates": [{
"card_id": 24535,
"tcgplayer_id": 138577,
"name": "Darkrai",
"number": "87/147",
"set": { "name": "SM - Burning Shadows" },
"match": { "number": "exact", "name": 1, "edition": true },
"printings": ["Holofoil", "Reverse Holofoil"],
"suggested_printing": "Holofoil",
"prices": [{ "printing": "Holofoil", "market_price": 1.23, "price_change_30d": -10.22 }]
}]
},
"meta": { "charged": "scan", "scans_remaining": 24 }
} What sets it apart
It reads the printing
Collector number, set and stamp decide the match, so 1st Edition, prerelease and reverse holo printings are told apart instead of guessed.
It says when it isn't sure
A card is only matched when nothing else fits. On 81 real phone photos it never matched the wrong card.
IDs and prices in the same call
Every candidate carries its TCGPlayer ID and catalog card_id; prices are one parameter away, not a second API.
Every game, cards and sealed
The scanner works on every game in the catalog, plus graded slabs and sealed products, with no per-game setup.
How accurate is it?
Measured on October 14, 2026 with the endpoint's own code against the live catalog. On 81 real phone photos of Pokemon cards and sealed products taken by a card vendor, the right item was confirmed as matched 88% of the time, was among the candidates every time, and no photo was matched to the wrong item. On catalog photos of cards from every game, the right card was among the candidates 92% of the time; most of the rest were versions that share one printed number.
The full method and per-game results are on the Identify reference. For how this compares with other recognition APIs, see Trading card recognition APIs compared.
What it costs
| Scans | Price | Per scan |
|---|---|---|
| 25 | Free | once per account |
| 1,000 | $15 | 1.5¢ |
| 5,000 | $60 | 1.2¢ |
| 25,000 | $250 | 1.0¢ |
| 100,000 | $800 | 0.8¢ |
Packs never expire and are separate from your plan's daily request limit. See pricing.
Card scanner API questions
Which card games can it scan?
Every card game in the TCG API catalog: Pokemon (English and Japanese), Magic: The Gathering, Yu-Gi-Oh!, One Piece, Lorcana, Flesh and Blood, Digimon, Dragon Ball Super, Weiss Schwarz, Star Wars Unlimited and the rest of the games listed on the games page. Pass game when your app already knows it; leave it out and the photo decides.
Can it tell 1st Edition, reverse holo and promo versions apart?
That is what it is built for. The reader looks at the printed collector number or card code, the set, the edition stamp (1st Edition, Prerelease, Pokemon Center and other event or retailer stamps) and the foil, and only answers matched when exactly one printing fits. When two printings look the same in the photo, it answers ambiguous and lists both.
Does it work on graded slabs and sealed products?
Yes. Slabs are read through the case and the grading company and grade come back in read.grade. Booster boxes, packs, Elite Trainer Boxes, decks and cases are matched against the sealed products in the catalog.
What does a scan cost?
Every account gets 25 free scans once. After that, prepaid packs cost 1.5¢ to 0.8¢ per scan (1,000 scans for $15 up to 100,000 for $800) and never expire. Scans are separate from your daily request limit and work on every plan, Free included. AI agents can pay $0.02 per photo with x402 instead.
How fast is it?
About 3.5 seconds per photo, almost all of it spent reading the photo. Requests can run in parallel, so an app scanning a stack of cards can send the next photo while the previous one is still being read.
What happens with a blurry photo?
The answer is retake with a message saying what to fix (glare, blur, a cut-off number, several items in one photo). Candidates found from the readable parts are still listed. The scan is used, because the photo was read.
Are prices included?
Add include=prices and the top candidate comes back with its current market, low and lowest-with-shipping prices per printing, plus 7- and 30-day changes, at no extra charge.
Key API Endpoints
Scan your first card today
Every account gets 25 free scans. No credit card required.