Migrating from pokemontcg.io

pokemontcg.io's API stops on March 1, 2027. RarityDB serves the same /v2 endpoints with the same response shape, so most apps switch with two changes:

  1. Base URL: https://api.pokemontcg.io/v2 → https://raritydb.com/v2
  2. Key: create one at your account and send it in the same X-Api-Key header (or Authorization: Bearer). A key is required on every call; pokemontcg.io allowed a few keyless ones.
curl -H "X-Api-Key: $RARITYDB_KEY" "https://raritydb.com/v2/cards?q=name:charizard%20set.id:base1&select=id,name"
{"data":[{"id":"base1-4","name":"Charizard"}],"page":1,"pageSize":250,"count":1,"totalCount":1}

Endpoints

Endpoint Notes
GET /v2/cards q, page, pageSize (max 250, default 250), orderBy, select
GET /v2/cards/:id pokemontcg.io IDs (sv3pt5-6) or ours (sv03.5-006); select
GET /v2/sets, GET /v2/sets/:id Same parameters
GET /v2/types, /v2/subtypes, /v2/supertypes, /v2/rarities {"data": [...]}

Errors look like pokemontcg.io's: {"error": {"message": "...", "code": 404}}. Rate limits are your plan's (see Authentication and limits).

IDs

Every card and set pokemontcg.io had keeps its pokemontcg.io ID, so stored IDs keep working. Sets released after pokemontcg.io stopped updating, and cards it never listed, use our IDs (TCGdex's), like me1-1. Both forms work anywhere an ID is accepted.

Search syntax (q)

The same Lucene-style syntax:

Example Meaning
name:charizard Name contains the word "charizard" (case-insensitive)
name:"charizard ex" A phrase
name:char* Wildcard
!name:charizard Exact name
-types:water Not
hp:[150 TO *], nationalPokedexNumbers:{* TO 152} Inclusive [ ] / exclusive { } ranges; also set.releaseDate:[2023/01/01 TO *]
types:fire OR types:water, (subtypes:mega OR subtypes:vmax) set.series:sword* OR and parentheses; terms side by side are ANDed

Fields: id, name, supertype, subtypes, types, hp, evolvesFrom, number, artist, rarity, flavorText, regulationMark, nationalPokedexNumbers, convertedRetreatCost, attacks.name, abilities.name, weaknesses.type, resistances.type, legalities.standard|expanded|unlimited, and set.id, set.name, set.series, set.ptcgoCode, set.releaseDate, set.total, set.printedTotal, set.legalities.*. Sets take the same set. fields without the prefix.

Unlike pokemontcg.io, an unknown field is an error (400) rather than an empty result, so typos don't fail silently.

orderBy takes name, number, hp, rarity, supertype, nationalPokedexNumbers, id, set.releaseDate, set.name, set.series, set.id for cards (- for descending, comma-separated), and name, releaseDate, series, id, total, printedTotal, ptcgoCode for sets. Without it, cards come in set release order, then card number.

What's different

  • English cards only, like pokemontcg.io. Japanese and other Asian cards are in the GraphQL API, with English names.

  • Card data comes from TCGdex, so a little wording differs:

    • Set names: "Base Set", not "Base".
    • Rarities: "Ultra Rare" and "Secret Rare", where pokemontcg.io uses era-specific labels like "Rare Holo GX" or "Rare Rainbow".
    • Text: attack and ability text writes Energy as symbols ("{W}" rather than "Water").
    • Rule boxes: rules is filled for Trainers and Energy, but not with the "Pokémon ex rule" box.
    • Not included: level and evolvesTo.
    • Matched to pokemontcg.io's style:
      • card numbers ("6", not "006");
      • names ("Venusaur-EX", "Nidoran ♂");
      • subtypes ("MEGA" on Mega Evolution cards, "Pokémon Tool");
      • rarity casing ("Double Rare", and "Rare Holo" for holo-only rares).

    We check this against the live pokemontcg.io API: on modern sets most cards match field for field.

  • Images are TCGdex scans (images.small / images.large). A few sets have no scan yet.

  • Prices: cardmarket.prices has Cardmarket's daily EUR figures with the same field names. tcgplayer has the product url but no prices: TCGplayer USD prices come through your own price-provider key on the GraphQL API.

  • Legalities list unlimited plus standard / expanded where legal, from the current rotation; pokemontcg.io's may lag behind. We don't track bans.

Beyond the compatibility layer

The /v2 endpoints are a bridge. The GraphQL API has everything they have plus printings (1st edition, reverse holo, stamps), sealed products, pull rates, Japanese cards, photo identification, condition grading and fake checks. You can migrate endpoint by endpoint: the IDs are the same in both.

This page as Markdown: /docs/migrating-from-pokemontcg-io.md