Skip to content
pokemontcgapi.com
Documentation

List changes

An append-only feed of catalogue mutations, so a mirror can resync without refetching everything.

GET/v1/changes1 creditfree plan

Cache-Control: public, max-age=30

Objects returned

Written by database triggers, not by application code: nothing can mutate a row without appearing here, and ids are monotonic, so a single integer is a complete sync position. Each entry names the kind, the public entity_id, the op (INSERT, UPDATE, DELETE) and the version the row reached.

Follow links.next until meta.has_more is false, store meta.next_since, and poll. meta.watermark is the newest id in the feed and meta.behind how far your cursor is from it. meta.oldest_available matters on a first sync: if your stored position is older than it, the feed can no longer replay the gap and a full refetch is the honest answer.

Query parameters

Query parameters
NameTypeDefaultDescription
sinceinteger0The meta.next_since of your previous page. 0, or omitted, starts from the oldest entry still available.
kindstringComma-separated entity kinds: CARD, SET, SEALED, PRICE, IMAGE.
limitinteger50Rows per page, 1 to 250. Above 250 you get LIMIT_EXCEEDED — follow links.next instead of raising it.

Headers

Headers
NameTypeDefaultDescription
X-Api-Key requiredstringYour API key. Authorization: Bearer <key> is accepted as an alias.
If-None-MatchstringSend 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/changes" \
  --data-urlencode "limit=2" \
  -H "X-Api-Key: $PTCG_API_KEY"

Example response

200 OK · Cache-Control: public, max-age=30

response.json
{
  "data": [
    {
      "id": 1,
      "kind": "SET",
      "entity_id": "sv2a",
      "op": "INSERT",
      "version": 1,
      "changed_at": "2026-09-02T12:39:35.894Z"
    },
    {
      "id": 2,
      "kind": "SET",
      "entity_id": "svln",
      "op": "INSERT",
      "version": 1,
      "changed_at": "2026-09-02T12:39:35.894Z"
    }
  ],
  "meta": {
    "count": 2,
    "has_more": true,
    "next_since": 2,
    "watermark": 116242,
    "oldest_available": 1,
    "behind": 116240
  },
  "links": {
    "next": "https://api.pokemontcgapi.com/v1/changes?limit=2&since=2"
  }
}

Errors

Every error body carries error.code, error.message and error.request_id. Switch on the code, never on the message.

Errors returned by this endpoint
StatusCodeWhen
401MISSING_API_KEYNo X-Api-Key header and no bearer token on a route that requires one.
401INVALID_API_KEYThe key does not match any account.
400INVALID_PARAMETERA 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.
400LIMIT_EXCEEDEDlimit 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.

view this page as markdown