Get a set
One set by code, slug or alternate id.
GET
/v1/sets/{code}1 creditfree planCache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600
id on a set object is the code, not an internal UUID. Set ids are short strings like bs and sv3 — human-readable, guessable, and the form most catalogues already store — so exposing a UUID here would make every id you already hold useless.
Path parameters
| Name | Type | Default | Description |
|---|---|---|---|
code required | string | — | Set code (bs), slug (base) or alternate id (base1). All three resolve, because whatever you have stored is one of them and you should not have to work out which. |
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 "https://api.pokemontcgapi.com/v1/sets/bs" \
-H "X-Api-Key: $PTCG_API_KEY"Example response
200 OK · Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600
response.json
{
"id": "bs",
"code": "bs",
"slug": "base",
"legacy_id": "base1",
"name": "Base",
"series": "Base",
"region": "WEST",
"release_date": "1999-01-09",
"total": 134,
"printed_total": 102,
"ptcgo_code": "BS",
"symbol_url": null,
"logo_url": "https://media.rarebit.app/sets/BASE/logo-normal.webp",
"updated_at": "2026-08-26T17:47:39.900Z"
}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. |
The full taxonomy, with what to do about each code, is on the errors page.