Migrate from pokemontcg.io
Endpoints and fields of the Pokémon TCG API, mapped to Rarity.
The Pokémon TCG API is deprecated: it no longer takes registrations, and existing keys work through March 1, 2027. This guide maps its v2 API, as its public documentation describes it, to Rarity.
What changes first
| pokemontcg.io | Rarity | |
|---|---|---|
| Base URL | https://api.pokemontcg.io/v2 | https://api.rarity.dev/v1 |
| Key | X-Api-Key header | Authorization: Bearer rar_live_..., optional |
| Required headers | none | User-Agent with your app and a contact, and Accept |
| Pagination | page, pageSize up to 250 | cursor, limit up to 100 |
| End of the list | compare page and totalCount | has_more |
| Prices | decimals | integers in minor units: 275 is 2.75 |
| Languages | English | lang=en and lang=ja |
A Rarity search needs no game filter, but a Pokémon client should send game=pokemon: other games are in the same catalog.
Endpoints
| pokemontcg.io | Rarity |
|---|---|
GET /v2/cards | GET /v1/cards?game=pokemon |
GET /v2/cards/{id} | GET /v1/cards/{id}, with a Rarity id |
GET /v2/sets | GET /v1/sets?game=pokemon |
GET /v2/sets/{id} | no single-set read: page through GET /v1/sets?game=pokemon and match code in your client |
GET /v2/types | no equivalent |
GET /v2/subtypes | no equivalent |
GET /v2/supertypes | no equivalent: category on the card |
GET /v2/rarities | no equivalent |
Rarity adds GET /v1/cards/suggest for autocomplete, POST /v1/cards/collection for up to 100 lookups in one call, GET /v1/changes to sync, and GET /v1/bulk for the whole catalog.
Search
# pokemontcg.io
curl -H 'X-Api-Key: ...' \
'https://api.pokemontcg.io/v2/cards?q=name:charizard&pageSize=50&orderBy=name'
# Rarity
curl -A 'my-app/1.0 (you@example.com)' \
'https://api.rarity.dev/v1/cards?game=pokemon&lang=en&q=name:charizard&limit=50&order=name'| pokemontcg.io | Rarity |
|---|---|
q=name:charizard | q=name:charizard |
q=set.id:sv3 | set=OBF or q=set:OBF, with a Rarity set code |
q=rarity:Promo | rarity=promo |
q=supertype:Trainer | category=trainer |
page, pageSize | cursor, limit |
orderBy | order=number or order=name |
select | no equivalent: a card comes whole |
Rarity's q= follows the Scryfall syntax, not Lucene: or and parentheses work, a term is negated with -, and * is a prefix only at the end of the last word. Details are in the reference for search.
Card ids
Rarity does not know pokemontcg.io ids such as base1-4, and Rarity ids are opaque. Match each stored card once and keep the new id:
- Find the Rarity set by name in
GET /v1/sets?game=pokemon. - Look the cards up in a batch with
POST /v1/cards/collection, bygame,setandnumber.
The print also carries external_ids.tcgplayer and external_ids.cardmarket, the product ids of those sites.
Check the result by hand on a few sets. Rarity's Pokémon catalog comes from TCGplayer, so set codes and numbers follow TCGplayer: a number can read 001/015 where pokemontcg.io has 1.
Card fields
| pokemontcg.io | Rarity |
|---|---|
id | id, a different value |
name | name |
supertype | category, in lowercase |
subtypes | attributes.stage for evolution stages; no equivalent for the rest |
hp | attributes.hp |
types | attributes.type, one string, and colors, in lowercase |
abilities[].type, .name, .text | attributes.abilities[].kind, .name, .text |
attacks[].name, .text, .damage | attributes.attacks[].name, .text, .damage |
attacks[].cost | attributes.attacks[].cost, a string of energy symbols such as RR |
weaknesses | attributes.weakness, a string such as Wx2 |
resistances | attributes.resistance, a string |
retreatCost | attributes.retreat_cost, a string |
set | set, the set code. Read the set from GET /v1/sets |
number | collector_number |
artist | no equivalent today: illustrator is null on Pokémon |
rarity | rarity, in lowercase, and it can be null |
legalities | legalities, a list of format, status and since |
images.small, images.large | image, one URL |
tcgplayer.prices | prices.tcgplayer.finishes |
cardmarket.prices | prices.cardmarket.finishes |
tcgplayer.updatedAt, cardmarket.updatedAt | updated_at under each source, a full timestamp |
level, evolvesFrom, evolvesTo, rules, ancientTrait, flavorText, nationalPokedexNumbers, regulationMark, convertedRetreatCost | no equivalent |
tcgplayer.url, cardmarket.url | no equivalent: build a link from external_ids |
attributes holds only strings, because a value like 100+ is not a number. GET /v1/games/pokemon publishes its schema. legalities is empty for Pokémon today, so don't build a format check on it yet.
Set fields
| pokemontcg.io | Rarity |
|---|---|
id | code, a different value |
name | name |
ptcgoCode | source_code, often the same value |
releaseDate | release_date, as YYYY-MM-DD, and it can be null |
updatedAt | updated_at |
series, printedTotal, total, legalities, images | no equivalent |
Every set has search_uri, a ready URL for its cards.
Prices
Amounts move from a flat object with decimal values to one object per finish, in minor units. A missing measure is absent, not null or 0.
| pokemontcg.io | Rarity |
|---|---|
tcgplayer.prices.normal | prices.tcgplayer.finishes.normal |
tcgplayer.prices.holofoil | prices.tcgplayer.finishes.holofoil |
tcgplayer.prices.reverseHolofoil | prices.tcgplayer.finishes.reverse_holofoil |
tcgplayer.prices.1stEditionHolofoil, 1stEditionNormal | a separate print, the 1st Edition one, with its own id |
low, mid, high, market, directLow | low, mid, high, market, direct_low |
cardmarket.prices.trendPrice | prices.cardmarket.finishes.<finish>.trend |
cardmarket.prices.averageSellPrice | prices.cardmarket.finishes.<finish>.avg |
cardmarket.prices.lowPrice | prices.cardmarket.finishes.<finish>.low |
cardmarket.prices.avg1, avg7, avg30 | prices.cardmarket.finishes.<finish>.avg1, avg7, avg30 |
cardmarket.prices.reverseHoloTrend and the other reverseHolo values | the same measures under prices.cardmarket.finishes.reverse_holofoil |
germanProLow, suggestedPrice, lowPriceExPlus | no equivalent |
<finish> is the print's base finish, which is normal or holofoil. Read the keys of finishes rather than assuming one.
prices: {} means Rarity has no certain link between the print and a product of that source, not that the card has no market. Rarity also adds prices.pricecharting for graded prices.
GET /v1/catalogs/price_sources states each source's market, currency, attribution and commercial terms. Check them before you resell or display prices.
Rate limits and errors
Without a key you get 30 requests a minute and 1,000 a day. A free key gives you 60 requests a minute per key and 2,000 a day per organization. Send If-None-Match, because a 304 does not count. Errors have a stable code and a doc_url, listed in the error pages.