TCG Price API: One Key for 12 Card Games, from Pokémon to Lorcana
TCG price API for 12 card games under one key: Pokémon, One Piece, Magic, Yu-Gi-Oh!, Lorcana, Riftbound. What's free, what needs Ultra, and how to call it.

One API, 12 Trading Card Games: Prices for Pokémon, One Piece, Magic, Yu-Gi-Oh!, Lorcana & More
🔵 IN THIS GUIDE: Your PokéWallet API key now covers ten more trading card games on top of Pokémon and One Piece. Catalog data is free for every game. Prices and analytics for the ten new games need the Ultra plan or the 7-day trial, and Pro does not cover them.
Quick Answer: PokéWallet is a REST API that covers 12 trading card games with one API key: Pokémon, One Piece, and ten more under their own path prefixes, including Magic: The Gathering (
mtg, 514 sets), Yu-Gi-Oh! (ygo, 706 sets), Disney Lorcana (lor, 24 sets) and Riftbound (rft, 15 sets). Sets, cards, search and images are free on every plan, starting at 100 requests/hour and 1,000/day. Prices come from TCGplayer (USD) and CardMarket (EUR) and refresh once a day: single cards show them on every plan, while set-wide prices and analytics for the ten new games need Ultra (€29/month) or the 7-day trial. Pro (€20/month) only unlocks prices for Pokémon and One Piece.
If you already use PokéWallet for Pokémon or BerryWallet for One Piece, nothing changes in how you authenticate. You send the same X-API-Key header to the same https://api.pokewallet.io base URL and add a game code to the path. /mtg/sets returns Magic sets, /lor/search?q= searches Lorcana cards, and /ygo/prices/:set returns Yu-Gi-Oh! prices on Ultra. All of them use the same response shapes.
This article is about coverage: which games, which endpoints, what each plan unlocks, and where the data runs out. It does not explain what a card API is or how to design a collection app around one. We already covered that in how TCG APIs power modern collection apps and in our developer experience guide to Pokémon TCG APIs. Read those first if you are starting from zero.
Here's the short version. If your app, shop tool or Discord bot touches more than one game, you can now use one integration and one invoice. You don't need a separate data source for each game.
Key Takeaways
- 🎴 12 games, one key — Pokémon, One Piece, Magic, Yu-Gi-Oh!, Lorcana, Flesh and Blood, Dragon Ball Super, Digimon, Star Wars Unlimited, Cardfight!! Vanguard, Riftbound and Cyberpunk.
- 🆓 Catalog is free everywhere —
/{game}/sets,/sets/:set,/cards/:id,/searchand/images/:idwork on the free tier for all ten new games. - 💳 Ultra, not Pro, for new-game prices — Pro (€20) unlocks paid endpoints for Pokémon and One Piece only. Ultra (€29) unlocks them for all 12.
- 🧪 Test before you pay — the 7-day trial unlocks Ultra endpoints. You start it from the dashboard after you log in.
- 💱 Two currencies, never mixed — TCGplayer prices are in USD and CardMarket prices are in EUR. The API does not convert between them, so your code shouldn't either.
- 📅 Prices refresh daily — this data suits valuation, collection tracking and trend work. It is too slow for sniping listings.
- 📉 Price history is Pokémon-only — the other 11 games get current prices plus 7-day trend and growth analytics, but no per-card history.
- 🔍 Treat IDs and rarities as per-game — Magic uses
M/R/U/Cwhile Lorcana usesEnchanted/Iconic. Don't hardcode one rarity scheme.
⚡ Quick Navigation
The 12 Games at a Glance
Pokémon has the root paths (/search, /sets, /prices/:setCode). One Piece lives under /op/. Each of the other ten games gets its own prefix. Each row below links to that game's tab in the API documentation.
| Game | Path prefix | Sets covered | Prices | Docs |
|---|---|---|---|---|
| Pokémon TCG | (root) | All sets, 50,000+ cards | TCGplayer + CardMarket, plus price history | Pokémon API docs |
| One Piece Card Game | op | All English and Japanese sets from OP01 | TCGplayer + CardMarket | One Piece API docs |
| Magic: The Gathering | mtg | 514 | TCGplayer + CardMarket, daily | Magic API docs |
| Yu-Gi-Oh! | ygo | 706 | TCGplayer + CardMarket, daily | Yu-Gi-Oh! API docs |
| Disney Lorcana | lor | 24 | TCGplayer + CardMarket, daily | Lorcana API docs |
| Flesh and Blood | fab | 128 | TCGplayer + CardMarket, daily | Flesh and Blood API docs |
| Dragon Ball Super | dbs | 198 | TCGplayer + CardMarket, daily | Dragon Ball Super API docs |
| Digimon | dgm | 106 | TCGplayer + CardMarket, daily | Digimon API docs |
| Star Wars Unlimited | swu | 34 | TCGplayer + CardMarket, daily | Star Wars Unlimited API docs |
| Cardfight!! Vanguard | cfv | 420 | TCGplayer + CardMarket, daily | Vanguard API docs |
| Riftbound | rft | 15 | TCGplayer + CardMarket, daily | Riftbound API docs |
| Cyberpunk | cpk | 15 | TCGplayer + CardMarket, daily | Cyberpunk API docs |
Together, the ten new games add 2,160 sets. Magic and Yu-Gi-Oh! make up more than half of that. The set counts are what the API reports today, and they will grow as new products are listed. The live Magic sets endpoint already returns "total": 514, matching the table, and Lorcana returns "total": 24. Read the total field instead of hardcoding these numbers.
Two newer releases are already in the catalog. Magic's Reality Fracture (FRA, released 2026-10-02) shows 782 cards in its set listing. Lorcana's Attack of the Vine! (set 13, released 2026-07-17) shows 270. If you want to browse before you write code, the card catalog shows the same data in a browser.
One Key, One Response Format
You don't need a new account or a new key. If you already have a PokéWallet key, it works for /mtg/, /ygo/, /lor/ and the rest right now. Authentication works as before: send an X-API-Key header to https://api.pokewallet.io.
The more useful part is that the responses are consistent across games. Every card comes back with the same three blocks:
card_infoholds the fields every game shares:name,clean_name,set_name,set_code,set_id,card_number,rarity,card_type,product_type,variants,card_text.tcgplayerholds apricesarray and the producturl.cardmarketholdsproduct_name, apricesarray and theproduct_url.
Game-specific fields go inside card_info next to the shared ones. A Magic card adds sub_type, p, t, flavor_text and upc. Emrakul, the Exigent Doom comes back as a Legendary Creature — Eldrazi with "p": "12" and "t": "12". A Lorcana card adds ink_type, cost_ink, strength, willpower, lore_value, classification, character_version and a few more. Woody - Helping a Friend is Amber, costs 4, and has 2 lore. Your rendering code can handle the shared fields once and then switch on the game code for the rest.
Three things don't carry over between games. Design around them from the start:
- Rarity vocabularies differ. Magic returns codes like
M,R,U,C,T,L. Lorcana returns words likeCommon,Super Rare,Enchanted,Iconic. Map them per game in your own code. - Set codes are not unique. Lorcana's Attack of the Vine! has
set_code: "13". Useset_id(24666) in paths, as the documentation examples do. - Card IDs are opaque. Most new-game IDs start with the game code (
mtg_…,lor_…), but don't parse that prefix. Store the ID as-is and track the game code separately.
To see every game and its endpoint templates in one call, use GET /games. That endpoint is public.
What Is Free and What Needs Ultra
There are two kinds of endpoints for each new game: catalog and paid. The plan you need depends only on which kind you call.
| Endpoint (per game code) | Free / Coffee | Pro (€20/mo) | Ultra (€29/mo) or 7-day trial |
|---|---|---|---|
/{game}/sets, /{game}/sets/:set | ✅ | ✅ | ✅ |
/{game}/cards/:id, /{game}/search?q= | ✅ | ✅ | ✅ |
/{game}/images/:id | ✅ | ✅ | ✅ |
/{game}/prices/:set | ❌ | ❌ | ✅ |
/{game}/sets/:set/statistics | ❌ | ❌ | ✅ |
/{game}/sets/:set/completion-value | ❌ | ❌ | ✅ |
/{game}/sets/trending | ❌ | ❌ | ✅ |
/{game}/analytics/top-cards | ❌ | ❌ | ✅ |
One detail can trip you up. In the /games response, the paid endpoints sit under a key called pro_endpoints. Despite that name, the Pro plan does not unlock them for the ten new games. Pro covers the paid endpoints of Pokémon and One Piece only. Ultra covers them for all 12 games.
Rate limits are shared across games because they belong to your key, not to the game:
| Plan | Price | Requests/hour | Requests/day | Paid endpoints |
|---|---|---|---|---|
| Free | €0, no card | 100 | 1,000 | None |
| Coffee Addicted | Pay what you want (Ko-fi) | 1,000 base | 10,000 base | None |
| Pro | €20/month | 5,000 | 50,000 | Pokémon + One Piece |
| Ultra | €29/month | 7,000 | 70,000 | All 12 games |
| Business | Custom | Custom | Custom | Contact via Discord |
Each coffee adds +25% to the Coffee Addicted limits for one month.
Here's our recommendation. If you only need card data such as names, images, text and set lists, stay on Free. If you need prices for Pokémon or One Piece and nothing else, Pro is the right plan. If you need a price for even one card from another game, take Ultra. It costs €9 more than Pro and covers ten more games.
Start with the trial so you can check that your integration works before you pay. Log in at /auth/login, open the dashboard, and activate the 7-day trial there. The full feature breakdown is on the pricing page. If you want to know how we got to these plans, see our earlier article on the pricing tiers.
Where the Prices Come From
There are two sources, and each one keeps its own currency:
- TCGplayer (USD):
low_price,mid_price,high_price,market_price,direct_low_price, one row per finish (sub_type_name:Normal,Foil,Cold Foil…). - CardMarket (EUR):
avg,low,trend,avg1,avg7,avg30, one row per finish (variant_type:normalorfoil).
Both sources refresh once a day. The updated_at field shows the last time that price changed, not the last time we checked it. A card with stable prices can therefore show an updated_at that is several days old.
Here is what one card looks like across both markets. These are price rows from /mtg/prices/24684 and /lor/prices/24666, last changed on 2026-09-30 and retrieved on 2026-10-13:
| Card | Finish | TCGplayer market (USD) | CardMarket avg (EUR) | CardMarket trend (EUR) |
|---|---|---|---|---|
| Emrakul, the Exigent Doom (Reality Fracture #1) | Normal | $29.08 | €34.79 | €16.27 |
| Emrakul, the Exigent Doom | Foil | $39.85 | €59.99 | €18.78 |
| Woody - Helping a Friend (Attack of the Vine! 1/207) | Normal | $0.33 | €0.25 | €0.19 |
| Woody - Helping a Friend | Cold Foil | $0.77 | €0.73 | €0.88 |
Two lessons come out of this table. First, finish names don't match across sources: TCGplayer's "Cold Foil" is CardMarket's foil. The /prices endpoint already pairs them into one row with a single variant, so use that endpoint instead of joining the two sources yourself. Second, CardMarket's avg and trend can be far apart for a set that is two weeks old, as Emrakul's €34.79 average and €16.27 trend show. A new set's price hasn't settled yet. Show both numbers and don't present one of them as "the price."
The analytics endpoints are built on the same data. For Lorcana's Attack of the Vine!, /statistics lists Belle & Beast - Certain as the Sun (Iconic) as the most expensive card at $2,008.20 on TCGplayer and €1,177 on CardMarket, with CardMarket's trend direction marked down. /completion-value puts one copy of every card in base finish at $7,274.63 at TCGplayer market prices. The per-rarity breakdown shows where that money goes: the 18 Enchanted cards ($3,527.69) and 2 Iconic cards ($3,637.54) make up about 98% of the total. A Lorcana collector who wants to know how much a full set really costs gets the answer in one call.
Your First Multi-Game Request
The script below calls /games, then runs the same search endpoint against Magic and Lorcana, then (on Ultra) runs the same prices endpoint against one set from each game. It uses Node 18+ with built-in fetch. Save it as .mjs so top-level await works.
const BASE = "https://api.pokewallet.io";
const headers = { "X-API-Key": process.env.POKEWALLET_API_KEY };
async function get(path) {
const res = await fetch(`${BASE}${path}`, { headers });
if (!res.ok) throw new Error(`GET ${path} failed: HTTP ${res.status}`);
return res.json();
}
// 1. Discover games and their endpoint templates (public)
const games = await get("/games");
for (const game of games.data) {
console.log(`${game.code.padEnd(4)} ${game.name} -> ${game.endpoints.search}`);
}
// 2. Same catalog endpoint, two games (free tier)
const queries = { mtg: "Emrakul", lor: "Helping" };
for (const [code, q] of Object.entries(queries)) {
const { results, pagination } = await get(`/${code}/search?q=${encodeURIComponent(q)}`);
console.log(`\n${code}: ${pagination.total} matches for "${q}"`);
for (const card of results) {
const { name, set_name, rarity, variants } = card.card_info;
console.log(` ${name} (${set_name}, ${rarity}) [${variants.join(", ")}]`);
}
}
// 3. Same price endpoint, two games (Ultra or 7-day trial)
const sets = { mtg: "24684", lor: "24666" }; // Reality Fracture, Attack of the Vine!
for (const [code, setId] of Object.entries(sets)) {
const { set_code, data } = await get(`/${code}/prices/${setId}`);
console.log(`\n${code} ${set_code}:`);
for (const row of data.slice(0, 4)) {
const usd = row.tcgplayer?.market_price ?? "n/a";
const eur = row.cardmarket?.avg ?? "n/a";
console.log(` ${row.name} [${row.variant}] TCGplayer $${usd} CardMarket €${eur}`);
}
}
According to the sample responses, the Magic search for "Emrakul" reports 53 matches and the Lorcana search for "Helping" reports 4. In step 3, the first rows are the four price rows from the table in the previous section. The code for Magic and Lorcana is the same: only the game code and the set ID change. Swap in ygo, fab or rft and it still runs.
On a free key, steps 1 and 2 work and step 3 returns an error. That's intended, since step 3 is where Ultra starts. The res.ok check makes that error show up clearly instead of failing silently.
Single-card lookups are a different story: /{game}/cards/:id and /{game}/search already include the current TCGplayer and CardMarket prices of each card on every plan. What Ultra adds is the whole set in one call, plus statistics, completion value, trending sets and top cards.
For a complete walkthrough with storage, scheduling and alerts, use the Pokémon price tracker tutorial or the One Piece price tracker tutorial. The structure carries over to every game: replace the root or /op/ paths with /{game}/.
Who It Is For
Multi-game collection apps. This is the main reason we built the ten new games. If your users collect Pokémon and Lorcana, or Magic and One Piece, you used to need one data source per game, each with its own ID scheme and pricing gaps. Now one key and one card schema cover all of them.
Local game stores and sellers. Stores rarely sell only one game. Daily TCGplayer and CardMarket prices across all twelve games are enough for buylist pricing, inventory valuation and checking whether a price is out of date. Having USD and EUR side by side helps if you buy in one market and sell in the other.
Discord bots and community tools. The search and catalog endpoints are free and return images, card text and game-specific stats, which covers a card-lookup bot. On Ultra, /sets/trending and /analytics/top-cards give you a weekly "what's moving" post for any game. Recently, for example, Alpha Edition showed +78.9% in CardMarket average price over 7 days.
Developers already on PokéWallet or BerryWallet. You don't need to migrate anything. Your Pokémon and One Piece code keeps working, and new games are new path prefixes.
What about the single-game specialists? Scryfall for Magic, YGOPRODeck for Yu-Gi-Oh! and Lorcast for Lorcana are good at what they do. Their data models are built around one game and its players, and their communities know those games well. If you only need one game, rules-level data and deckbuilding fields, start with the specialist. PokéWallet makes sense once you need one key for 12 games with TCGplayer and CardMarket prices in the same response format. For a direct comparison in one game, see BerryWallet vs one-piece-api.com.
What It Does Not Do Yet
Here's what the API doesn't do yet. Check this list before you build anything on top of it.
- No price history outside Pokémon.
/cards/:id/price-historyexists only for Pokémon. For the other 11 games you get current prices plus CardMarket's built-inavg1/avg7/avg30and 7-day trend/growth analytics. To build your own history for Magic or Lorcana, save a daily snapshot from/prices/:set. - Trending only uses CardMarket for now. For the new games, the
tcgplayerblock in/sets/trendingcurrently returns"status": "work_in_progress"with the message "TCGPlayer price history not yet available". Build your trend UI around the CardMarket numbers. - Growth rankings are noisy at the low end. The top Magic "growth" card in the sample is Sandstorm Eidolon, a Dissension common, at +753.8% to €14.43 in 7 days. Moves like that on cheap cards often reflect a handful of listings rather than demand. Set a price floor before you call anything a trend.
- No eBay, no graded prices. We only use TCGplayer and CardMarket. There are no sold-listing prices from eBay and no PSA/CGC data for any game.
- Daily refresh only. Prices update once a day. If your app needs to react to a new listing within minutes, this is the wrong data source.
- No currency conversion.
/completion-valuesays so in its ownnote: "Cross-currency comparison not available." Show USD and EUR as separate figures. - Counts can differ between endpoints. For Reality Fracture, the set listing shows 782 cards while
/statisticsreports 767 cards with price data. Use each endpoint's own count for its own purpose. - No SDK. Integration is plain HTTP. The docs include JavaScript, Python, Node.js and Go snippets, but there is no package to install.
Frequently Asked Questions
Is there a free API for Magic: The Gathering card prices?
Card data is free: sets, cards, search and images for Magic all work on PokéWallet's free tier (100 requests/hour, 1,000/day). Card detail and search already include each card's TCGplayer and CardMarket prices; set-wide prices and analytics need the Ultra plan (€29/month), or the 7-day trial if you want to test them first.
Does the Pro plan include Yu-Gi-Oh! or Lorcana prices?
No. Pro (€20/month) unlocks the paid endpoints for Pokémon and One Piece only. Prices and analytics for Yu-Gi-Oh!, Lorcana, Magic and the other seven games need Ultra (€29/month), which also includes everything in Pro.
Is there a Riftbound API?
Yes. Riftbound has the game code rft and currently covers 15 sets. You get the same catalog endpoints as every other game (/rft/sets, /rft/search?q=, /rft/cards/:id), and TCGplayer plus CardMarket prices are available on Ultra.
How often are card prices updated?
Once a day, for both TCGplayer and CardMarket. The updated_at field shows when a price last changed, so a card whose price hasn't moved can show an older date. That is expected.
Can I get price history for Magic or Yu-Gi-Oh! cards?
Not yet. Per-card price history exists only for Pokémon. For the other games you get CardMarket's 1-, 7- and 30-day averages plus the 7-day trending and growth endpoints. You can also store daily snapshots yourself.
Do I need a separate API key for each game?
No. One PokéWallet key covers all 12 games. You change the path prefix (/mtg/, /ygo/, /lor/…), not the key, and rate limits are shared across everything you call.
Does the API include eBay sold prices or PSA graded values?
No. Prices come from TCGplayer (USD) and CardMarket (EUR) only, for every game. There is no eBay data and no grading data.
How do I start the 7-day Ultra trial?
Log in at pokewallet.io, open your dashboard and activate the trial there. It unlocks the paid price and analytics endpoints for all 12 games so you can test your integration before you subscribe.
💬 Price disclaimer: All prices in this article come from PokéWallet API responses retrieved on 13 October 2026. They reflect TCGplayer (USD) and CardMarket (EUR) data last changed on 30 September 2026. Plan prices and limits are as published on the pricing page at the time of writing. Card prices change daily, and nothing here is financial advice.
Start Building with the PokéWallet API
If your project covers more than one card game, you can use one key, one response format and one price pipeline for Pokémon, One Piece and ten more. Start free with the catalog, then try the Ultra trial when you need prices.
- 🔑 One API key for 12 trading card games — Pokémon, One Piece, Magic, Yu-Gi-Oh!, Lorcana, Riftbound and more
- 💰 TCGplayer (USD) and CardMarket (EUR) prices, refreshed daily
- 🆓 Catalog endpoints free on every plan — sets, cards, search and images
- ⚡ Ultra unlocks prices and analytics for every game — try it free for 7 days from your dashboard
- 💬 Developer support in our Discord
Get Started:
- 🚀 Get Your Free API Key — no credit card required
- 📖 Read the API documentation
- 💳 Compare plans on the pricing page
This article is for informational purposes only and is not financial advice. Details reflect information available at the time of writing; release dates, pricing and set contents are subject to change. Card prices are volatile — always verify current market pricing before buying or selling.