Cards in a set
Every card in a set, in collection order, with correct paging past 250 rows.
/v1/sets/{code}/cards1 creditfree planCache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600
An unknown code returns 404 SET_NOT_FOUND, never an empty page. An empty page reads as "this set was emptied" and is the fastest way to get a wrong bug report written about you.
This is the endpoint where a missing sort tiebreaker does the most damage: a set over 250 cards spans several pages, and rows sharing a collector number would land in undefined order at every boundary. Here the sort is (number_sort, number, id) and id is never optional, so pagination never repeats or drops a row, at any page depth.
Path parameters
| Name | Type | Default | Description |
|---|---|---|---|
code required | string | — | Set code, slug or alternate id. |
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
q | string | — | Further Lucene filter, applied inside the set. |
orderBy | string | number | Defaults to collection order. Same keys as search cards. number sorts on the extracted numeric part first, so 1S lands next to 1 and not next to 100. |
select | string | — | Comma-separated card fields to return. id is always included. camelCase and snake_case both resolve, so nationalPokedexNumbers works and comes back as national_pokedex_numbers. An unknown name is INVALID_SELECT_FIELD, with the full list in details.valid_fields. |
include | string | — | Comma-separated relations to expand: prices, translations, images, set, artist. Each one is an extra join, so ask only for what you render. include=prices is how you get the per-source price breakdown. legalities is not an accepted value and is rejected with 400 INVALID_INCLUDE. |
lang | string | — | Locale for the card name: en, ja, fr, de, es, it — the six with translation rows in the catalogue. A card with no translation in the requested locale falls back to English rather than to null. |
limit | integer | 50 | Rows per page, 1 to 250. Above 250 you get LIMIT_EXCEEDED — follow links.next instead of raising it. |
cursor | string | — | Opaque keyset cursor from links.next. Never construct one; it carries the sort order it was issued for and is rejected if orderBy changes mid-run. |
Headers
| Name | Type | Default | Description |
|---|---|---|---|
X-Api-Key required | string | — | Your API key. Authorization: Bearer <key> is accepted as an alias. |
If-None-Match | string | — | Send back the ETag you stored. The API returns a strong ETag on every catalogue response, and a 304 is a header exchange: no body, no database row read. |
Example request
curl -s -G "https://api.pokemontcgapi.com/v1/sets/bs/cards" \
--data-urlencode "limit=2" \
--data-urlencode "select=id,name,number,rarity,index_eur" \
-H "X-Api-Key: $PTCG_API_KEY"Example response
200 OK · Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600
{
"data": [
{ "id": "bs-1", "name": "Alakazam", "number": "1", "rarity": "Rare Holo", "index_eur": 48.83 },
{ "id": "bs-1s", "name": "Alakazam (1st Edition Shadowless)", "number": "1S", "rarity": "Rare Holo", "index_eur": 49.30 }
],
"meta": { "limit": 2, "count": 2, "has_more": true },
"links": { "next": "https://api.pokemontcgapi.com/v1/sets/bs/cards?select=id%2Cname%2Cnumber%2Crarity%2Cindex_eur&limit=2&cursor=eyJrIjpbMSwiMVMiXSwiaWQ..." }
}Errors
Every error body carries error.code, error.message and error.request_id. Switch on the code, never on the message.
| Status | Code | When |
|---|---|---|
| 401 | MISSING_API_KEY | No X-Api-Key header and no bearer token on a route that requires one. |
| 401 | INVALID_API_KEY | The key does not match any account. |
| 404 | SET_NOT_FOUND | No set with that code, slug or alternate id. |
| 400 | INVALID_QUERY | The q parameter does not parse, or names a field that does not exist. |
| 400 | INVALID_CURSOR | The cursor is malformed, or was issued for a different orderBy than the one on this request. |
| 400 | INVALID_PARAMETER | A query parameter has the wrong type or an unsupported value — a non-integer limit, an unknown lang, an unknown region, a sort key that is not sortable. |
| 400 | LIMIT_EXCEEDED | limit is above 250, or a batch request carries more than 100 ids. |
The full taxonomy, with what to do about each code, is on the errors page.
Print variants are separate rows with their own ids and their own prices — bs-1 and bs-1s above are the same Alakazam in two printings, and each carries its own index_eur. That is why a set can hold more rows than its printed_total.