Trust
Changelog
What shipped, on what day, and what we took back. Corrections are listed with the same weight as features: an API you are about to depend on is worth more if you can see where it was wrong.
Last entry · 6 entries · Atom feed
Cards carry their game text
attacks, abilities, weaknesses, resistances, subtypes, retreat_cost, converted_retreat_cost, rules, flavor_text, evolves_from and evolves_to carry rows for the first time. On 27 August we published that these keys existed and were empty, and positioned the catalogue accordingly; that is no longer the shape of the data. The Base Set Charizard answers with Energy Burn and Fire Spin.
The text is English, so it lands on the 20,725 Western printings and not on the Japanese and Chinese ones, which are the larger half of the catalogue. Counted whole rather than sampled, on 3 September: attacks on 17,207 cards — 33% of the catalogue, 83% of the Western part — subtypes on 20,082, types on 22,363, national_pokedex_numbers on 21,738, weaknesses on 16,124, flavor_text on 10,284, abilities on 4,042, rules on 2,951. Every field publishes its own rate on the card object page, because a share of the whole catalogue and a share of the cards a field can apply to are different claims.
A null attacks now means we do not hold the text for that printing, never that the card has no attack. legalities and level are still empty for every card, and deck legality remains a question this API cannot answer.
The text comes from the TCGdex open database, MIT licensed, matched onto cards our own catalogue already carried; the attribution page carries their copyright notice. No price figure comes from them. 20,330 cards changed in one pass, so a mirror following GET /v1/changes saw a single large batch that day rather than a drift.
New plan ceilings, and the market data moves to Growth
The monthly ceilings come down to the shape of the market: Developer answers 50,000 credits a month, Growth 200,000, Professional 500,000. The trial is unchanged at 800 credits granted once. Rate limits, concurrency and key counts are untouched — what changed is the monthly total, which on the old scale was large enough that no plan could be told apart from another.
The line between the plans is now drawn in one place rather than spread thinly. Every plan keeps the whole catalogue: every card, every set, every image, names in six languages, search, the changes feed and today’s price. What starts at Growth is the market depth — graded quotes by company and score, the complete price series, the movers feed, and recognising a card from a photograph.
POST /v1/vision/identify is the endpoint affected most, and it now answers 403 with the code PLAN_REQUIRED below Growth, with details.min_plan naming the plan it needs. The check runs before the upload is read, so a client on the wrong plan finds out in one round trip instead of after sending ten megabytes. GET /v1/prices/movers moves from Developer to Growth in the same release.
If you are on Developer today: graded rows, the movers feed and price history beyond 30 days stop appearing in your responses. Nothing errors — the rows are simply not there — so if your product requires them, the upgrade is a single change of plan and takes effect within a minute. GET /v1/billing/plans and GET /v1/me both carry a new vision boolean so you can check entitlement in code rather than by trying a call.
Sealed products, the price routes and the change feed are live
GET /v1/sealed, GET /v1/sealed/{id} and GET /v1/sealed/{id}/prices serve 2,088 sealed products — booster boxes, elite trainer boxes, tins, blisters, collections and eighteen other kinds — with names in six locales, images, the set they belong to, and price observations that reach back to November 2024. The id of a sealed product is its sku. GET /v1/status now reports sealed: 2,088 where it reported 0; the 237 products of other card games that share the source catalogue are filtered out.
The price routes documented as planned on 2026-08-27 answer today: GET /v1/cards/{id}/prices, /prices/history, /prices/stats, GET /v1/prices/current for up to 50 cards, GET /v1/prices/movers from the Developer plan up, and GET /v1/prices/sources with the allow-list in the open. The composite index series starts on 2026-09-02, so stats and movers fill in from that day; marketplace observations run from 2026-07-28.
GET /v1/changes is live: an append-only feed written by database triggers, with monotonic ids, meta.watermark and meta.oldest_available. GET /v1/series lists the seventeen blocks. GET /v1/reference replaces the four vocabulary lists that were documented and never routed by this service.
Cardmarket is served: the CARDMARKET source — lowest price, 1/7/30-day averages and trend, in six printing languages, with history back to November 2024 — joins the allow-list with the same 24-hour delay as the other marketplace sources, on cards and on sealed products alike. Price rows carry the amount under the key amount, and name their source as CARDMARKET, TCGPLAYER, PRICECHARTING, COMMUNITY or PTCG_INDEX. The TCGplayer rows answer to the shorter code TCGPLAYER from today, and carry the provenance string "TCGplayer"; the longer code they used until this release is still accepted as a ?source= filter, so an existing query keeps working. The documentation used an older key and older source names; every sample on the site was regenerated from live responses.
The catalogue moved to a single Postgres cluster shared with its source database, and the API now serves from that cluster directly. Email verification for trial accounts is live: verifying raises the trial quota from the unverified allowance to 800 credits and makes the key recoverable from the address.
The site now claims only what the API answers
Nine endpoint families were documented here as available and are not routed by the running service: the two card price sub-resources, the change feed, bulk export, the reference lists, the series index, the price collections, account usage and image recognition. They are marked planned everywhere they appear. They stay on the plan; none of them answers a request today.
The second response shape published under a /v2 prefix has been withdrawn from the documentation. The service answers on one prefix, /v1. Describing a second envelope was describing something that does not exist, which is worse than describing nothing.
Catalogue figures were re-measured against GET /v1/status before publishing: 615 sets, 52,337 cards, 0 sealed products. Every count on the site now names the endpoint it was read from and the day it was read.
Availability and latency percentages were removed rather than restated. We run no external probe that produces them, and a figure with no measurement behind it is worth less to you than no figure at all. They come back when a probe exists and publishes its own history.
The catalogue is now described by what it holds. Game text — attacks, abilities, subtypes, weaknesses, resistances, retreat cost, flavour text — exists as keys on the card object and is empty across the catalogue: measured over 500 cards drawn from five Western sets it came back 0% populated, while types and national Pokedex numbers appeared on roughly half of the Scarlet & Violet cards in that sample and on none of the older ones. The site no longer implies otherwise. What is positioned instead is what is actually there: the catalogue, six locales, three print regions, images, artist credits, and prices that carry their own provenance.
The catalogue moved to a dedicated host, and grew to 615 sets
The API moved onto dedicated hardware and now reads its catalogue from a replica kept in step by a nightly sync. GET /v1/status reports both ingest jobs — the price refresh and the catalogue sync — with the timestamp of their last success and its age in hours, so the freshness of what you are reading is one request away instead of a claim on a marketing page.
The catalogue went from the 203 sets published at launch to 615 sets and 52,337 cards. By print region that is 176 Western sets, 379 Japanese and 60 Simplified Chinese.
The span of the catalogue is thirty years of print. The oldest set carried is Expansion Pack, released 1996-10-20 in Japan; the newest already in the database is 30th Celebration, dated 2026-09-16.
First public release
/v1 opens: cards, sets, artists, rarities, types and supertypes, over a single envelope of {data, meta, links}. Collections page with an opaque keyset cursor, and every sort ends on id as a tiebreaker, so paging never repeats a row and never drops one.
Failures are one shape — {error: {code, message, details, request_id}} — with a stable code per condition, so a client can branch on the code instead of matching the message. Every response carries a strong ETag and an x-request-id.
Card records carry names in six locales (en, ja, fr, de, es, it) with set code, series, rarity, hp, artist credit and images. Ids are stable, and each card also keeps a legacy_id, the older-style identifier for the same card: GET /v1/cards/base1-4 resolves to the card whose id is bs-4 and whose legacy_id is base1-4, so an existing lookup table keeps working.
Prices arrive on a card through ?include=prices. Every row states its own source, variant, basis, price, currency, locale, condition, printing, grading, capture date, sample size and provenance string, and the card carries a composite index_eur alongside last_price_at.
The set index on this site is generated from the live catalogue — 203 sets at that point — and the price methodology and attribution pages went out the same day as the endpoints, because a price you cannot trace is a price you cannot build a business on.
How this page is kept
Entries record changes we can point at: a commit, or a response you can fetch yourself. Nothing is announced here before it answers a request, and a figure published in an entry names the endpoint it was read from. The same list is served as an Atom feed at /changelog.xml, so a release does not have to be discovered by revisiting a page.