TCG Card API v0.4.9

🤖 Machines and AIs: this whole page, as OpenAPI 3.1 — /v1/openapi.json. Point a code generator, an LLM, or an API client at it; it is generated from the same definition as this page.

Get a token

Subscribe, pay, and your token is minted on the spot — shown once on the redemption page. Cancel any time; the token stops when the subscription does.

Starter
$4.99/mo
2,500 requests/mo
Subscribe
Pro
$14.99/mo
10,000 requests/mo
Subscribe
Unlimited
$39.99/mo
unlimited requests, 300/min burst
Subscribe

Just trying it out? The free tier (1,000 requests/mo) is a support email away — no card needed. Images never count against any plan.

Card data for the Pokémon Trading Card Game — sets, cards, printings, images-by-address — served fast from SQLite.

Authentication

Every endpoint except /v1/health, /v1/openapi.json and /docs requires a token: Authorization: Bearer ptcg_live_… (or X-API-Key: ptcg_live_… for clients that cannot set Authorization).

Costs and quotas

Requests are weighted against a monthly allowance: a card or set lookup costs 1, the scanner index 5, the bulk catalog.db download 100. The manifest (/v1/catalog.json), /v1/me, /v1/languages and all images cost 0 — poll for updates and hotlink pictures freely, forever. A 304 Not Modified on catalog.db is also free. Every plan additionally has a per-minute burst cap.

Every response carries X-Quota-Limit, X-Quota-Used, X-Quota-Remaining, X-Quota-Resets and X-Quota-Period headers, so a client sees the wall before hitting it.

The cheap pattern for apps

Pull /v1/catalog.db once (cost 100), serve lookups from your own copy, poll /v1/catalog.json (free) for version changes, and send If-None-Match when re-pulling — unchanged means a free 304.


Independent fan project. Not produced by, endorsed by, or affiliated with Nintendo, Creatures Inc., GAME FREAK inc., or The Pokémon Company. Card facts are used descriptively to identify cards; no card artwork is sold.

GET /v1/health freeno token

Liveness, version, and cluster view

The one truly open endpoint — monitors should not need a key to ask "alive?".

200 Node identity, running service version, catalog version, and (when clustered) what each peer last reported.
{
  "ok": true,
  "catalog": true,
  "node": "east",
  "service": "0.4.9",
  "version": 12,
  "sourceConfigured": true,
  "auth": true,
  "checkedAt": "2026-08-09T12:00:00.000Z"
}

GET /v1/me free

Who this token is, and how much it has left

200 The token’s plan and this month’s spend, summed across all nodes.
{
  "node": "east",
  "name": "My app",
  "plan": "free",
  "monthlyLimit": 1000,
  "burstLimit": 60,
  "period": "2026-08",
  "used": 42,
  "remaining": 958,
  "resetsAt": "2026-09-01T00:00:00.000Z",
  "created": "2026-08-09T00:00:00.000Z"
}
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/catalog.json free

The catalog manifest — poll this to know when to update

200 Version and counts of the published catalog. Costs nothing — poll freely.
{
  "version": 12,
  "cards": 19000,
  "sets": 160,
  "printings": 31000,
  "contentHash": "ab12…",
  "fetchedAt": "2026-08-09T12:00:00.000Z",
  "checkedAt": "2026-08-09T12:05:00.000Z"
}
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/catalog.db cost 100

The whole catalog, as one SQLite file

Byte-for-byte the published master (tables: sets, cards, printings, meta). Send If-None-Match with the last ETag — an unchanged catalog answers 304 at cost 0.

200 The SQLite database (application/octet-stream), with an ETag.
304 You already have it. Free.
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/languages free

Which languages are published

200 Language codes with data.
{
  "languages": [
    "en",
    "ja"
  ]
}
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/sets cost 1

Every set, in release order

Parameter
lang (query)optionalLanguage code (en, ja, de, …). Defaults to en. /v1/languages lists what is published.
200 Set summaries.
{
  "language": "en",
  "sets": [
    {
      "id": "base1",
      "name": "Base Set",
      "releaseDate": "1999-01-09",
      "logo": "https://…/en/images/base1/logo.png",
      "cardCount": {
        "official": 102,
        "total": 102
      }
    }
  ]
}
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/sets/{id} cost 1

One set, with every card and printing in it

Parameter
id (path)required
lang (query)optionalLanguage code (en, ja, de, …). Defaults to en. /v1/languages lists what is published.
200 The set summary plus its full card list.
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
404 Set not found.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/cards cost 1

Search cards

Parameter
lang (query)optionalLanguage code (en, ja, de, …). Defaults to en. /v1/languages lists what is published.
name (query)optionalSubstring match on the card name.
set (query)optionalRestrict to one set id.
rarity (query)optionalExact rarity.
type (query)optionalExact type (Fire, Water, …).
page (query)optional
perPage (query)optional
200 Paged results; each card also carries setName.
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/cards/{id} cost 1

One card, with its printings

Parameter
id (path)required
lang (query)optionalLanguage code (en, ja, de, …). Defaults to en. /v1/languages lists what is published.
200 The card.
{
  "id": "base1-4",
  "setId": "base1",
  "number": "4",
  "name": "Charizard",
  "rarity": "Rare Holo",
  "category": "Pokemon",
  "dex": [
    6
  ],
  "types": [
    "Fire"
  ],
  "hp": 120,
  "illustrator": "Mitsuhiro Arita",
  "variants": [
    "holo",
    "firstEdition"
  ],
  "images": {
    "low": "https://…/low.webp",
    "high": "https://…/high.webp"
  },
  "printings": []
}
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
404 Card not found.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/scan-index cost 5

Perceptual-hash fingerprints for on-device card scanning

Parameter
lang (query)optionalLanguage code (en, ja, de, …). Defaults to en. /v1/languages lists what is published.
200 The algorithm name and one fingerprint row per card: [cardId, hash].
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
404 No index published for that language.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.

GET /v1/images/{key} free

A card image, by address — answers with a redirect

Always cost 0, by standing policy — images are never metered or sold. The answer is a 302 to where the bytes live; this API never serves image bytes itself.

Parameter
key (path)required
302 Redirect to the image.
400 Not an image path.
401 No token, or an unrecognised one. Send Authorization: Bearer <token> (or X-API-Key).
402 Monthly allowance spent. X-Quota-Resets says when it refills; nothing is charged for refused requests.
403 The token has been revoked.
429 Burst cap exceeded (per-minute). Retry-After is set, in seconds.