Quickstart
Get a key, make your first request, and page a full set correctly — in about three minutes.
Three steps. The only prerequisite is something that can send an HTTP header.
1. Get a key
- Ask for a key at pokemontcgapi.com/free-api-key. No card, no call.
- Copy the key from the dashboard. It is shown once — we store an Argon2 hash, not the key, so we cannot show it to you again.
- Put it in your environment as
PTCG_API_KEY.
Secret keys are server-side
A key starting ptcg_live_ belongs on a server. For browser code use a ptcg_pub_ key, which is catalogue-only and pinned to a referrer allow-list. See authentication.
2. Make a request
Search is the endpoint you will use most. This asks for the two most recent Charizard holo rares:
curl -s -G "https://api.pokemontcgapi.com/v1/cards" \
--data-urlencode 'q=name:charizard rarity:"rare holo"' \
--data-urlencode "orderBy=-release_date" \
--data-urlencode "limit=2" \
-H "X-Api-Key: $PTCG_API_KEY"Collections always come back in the same envelope:
{
"data": [ /* rows */ ],
"meta": { "limit": 2, "count": 2, "has_more": true },
"links": { "next": "https://api.pokemontcgapi.com/v1/cards?...&cursor=eyJrIjpb..." }
}3. Page a whole set
The only correct way to page is to follow links.next until it disappears. Do not rebuild the URL, do not add a page parameter — there is not one — and do not change orderBy mid-run.
const key = process.env.PTCG_API_KEY ?? "";
let next: string | null = "https://api.pokemontcgapi.com/v1/sets/obf/cards?limit=250";
const all: unknown[] = [];
while (next) {
const res = await fetch(next, { headers: { "X-Api-Key": key } });
if (!res.ok) throw new Error((await res.json()).error.code);
const page = await res.json();
all.push(...page.data);
next = page.links?.next ?? null;
}
// 230 on 2026-08-27, each id exactly once. obf sits just past the 250
// ceiling, so it is the smallest set that actually exercises the cursor.
console.log(all.length);What to read next
The query syntax page is the one that pays for itself: most of what people ask support is already expressible in q. After that, caching and ETags — a 304 costs no credits, so a well-behaved client is a cheap client.
What the trial gives you
Five requests per second, 800 credits granted once, and a daily cap of 200. The credits do not renew: they exist to answer "does this API have what I need", and most calls spend one of them. Rate limits has the cost of the ones that spend more.