Skip to content
pokemontcgapi.com
Documentation

Introduction

A REST API for Pokemon TCG cards, sets, artists and prices, with one response shape and pagination that never repeats or drops a row.

Everything is JSON over HTTPS. Every endpoint is a GET unless it uploads something, every response is cacheable unless it is about your account, and every error has a code you can switch on.

The base URL is https://api.pokemontcgapi.com. There is no sandbox host: the free tier is the sandbox.

Start here

PageWhat it answers
QuickstartFirst successful request, in three minutes.
AuthenticationWhere the key goes, and which key type to use in a browser.
Query syntaxThe whole query grammar, and which fields hold data today.
PaginationCursors, and why there is no page parameter.
ErrorsEvery code, its status, and what to do about it.
VersioningWhat /v1 guarantees and what may change without notice.
API referenceOne page per operation.

What the API covers

Counts below are from GET https://api.pokemontcgapi.com/v1/status and from the collection endpoints, read on 2026-08-27. They move as the catalogue grows; the endpoint is always the current answer.

  • Cards — 52,337 of them, searchable with a Lucene-style query grammar. Names, ids, collector numbers, rarity, artist, set membership and images.
  • Sets — 615, across three print regions: 176 Western, 379 Japanese, 60 Chinese. Codes, slugs, alternate ids, release dates, printed and true totals.
  • Six languages — card translations in en, ja, fr, de, es and it.
  • Artists — 399 illustrators with maintained card counts.
  • Prices — per source, in the source’s own currency, with the basis, the as-of timestamp and the provenance attached to every row. Graded rows carry the grading company and score.

What is not in here

This is a catalogue and price API that also carries card game text, in English, on the printings we hold it for — attacks, abilities, subtypes, rules text and retreat costs, roughly a third of the catalogue and four fifths of the Western printings. Format legalities are not populated at all. Every field publishes its measured fill rate on the card object, so you can tell before you integrate rather than after.

Design rules we do not break

These are the three that show up in the response body, so they are worth stating before you write any code.

RuleWhy it exists
Every sort ends with idWithout a tiebreaker, rows sharing a sort key have undefined order between queries, so paging duplicates and drops rows. With one, pagination never repeats or drops a row, at any page depth.
A client mistake is never a 5xxA malformed query returns 400, not 500. On resale marketplaces a 5xx sinks the listed service level for thirty days and is excluded from quota counting — a mislabelled response is both free traffic and burnt reputation.
Quota exhaustion is 429, not 402Gateways and CDNs in the middle handle 402 unpredictably — some cache it, some rewrite it. 429 QUOTA_EXCEEDED is unambiguous everywhere.

One request, end to end

first-request.sh
curl -s -G "https://api.pokemontcgapi.com/v1/cards" \
  --data-urlencode "q=name:charizard set.code:bs" \
  -H "X-Api-Key: $PTCG_API_KEY"

Query fields and response keys are spelled differently

The query above uses set.code; the card that comes back carries "set_code": "bs". Queries are camelCase and dotted, responses are snake_case, and neither spelling is accepted in the other’s place. It is the one thing worth reading query syntax for before anything else.

Documentation for machines

Every page here is also served as markdown: append /md to any docs URL. `/llms.txt` indexes the whole set in the llmstxt.org format, so a coding assistant can pull the reference at integration time instead of guessing at endpoint names.

view this page as markdown