Developers

The ISO card archive API

Everything the archive knows — cards, sets, years, aggregated prices, images — is readable over a free JSON API. No key, no signup: every endpoint under /public is anonymous by design.

Endpoints

EndpointWhat it returns
GET /public/productsBrowse the catalog — page/cursor pagination, q search, category + price filters.
GET /public/products/{id}One product: identity, prices (raw + graded), description, set link, image.
GET /public/categories/{token}A category hub: sample products, sellers, child nodes.
GET /public/categories/{token}/nodes/{slug}A set/node detail with its linked products (paginated).
GET /public/catalog/yearsEvery catalog year with counts.
GET /public/catalog/years/{year}Products of one year (paginated).
GET /public/catalog/setsEvery set node across categories.
GET /public/images/{key}Stable image URL — 302s to a fresh signed image; cache the /public/images URL, not the target.
GET /public/sitemap/countsSitemap-scale inventory: per-section entry totals.
GET /public/sitemap/{section}Stable-ordered enumeration chunks (page, limit ≤ 20000).

Catalog endpoints answer 404 while their section of the site is dark (feature-flagged) — the contract below still holds when they relight.

Identifier schema

Product responses carry a flat, stable identity block:

FieldMeaning
nameCanonical card/product name (e.g. "Charizard").
setSet name (e.g. "Base Set"); node_slug/node_name link the set page.
yearRelease year as an integer.
card_numberPrinted card number (e.g. "4/102").
categoryTop-level category token (e.g. "pokemon", "sports_card").
graderGrading house key — closed set: PSA, BGS, CGC, SGC.
gradeGrade label under a grader (e.g. "10", "9.5").
variantPrinting/variant qualifier (e.g. "holo").

Pagination

  • List endpoints take page (1-based) and limit; browse also supports an opaque cursor for stable deep paging.
  • Sitemap enumeration chunks take page (0-based) and limit (clamped to 20,000) in a stable primary-key order — the same page always yields the same rows.

Price conventions

  • price is a display string ("$1,234.50") for humans; price_amount is the bare decimal ("1234.50") with currency as an ISO code — always compute on price_amount.
  • graded_prices nests grader → grade → price entries, each with its own price_amount/currency and an as_of date where the source provides one.
  • Prices are labeled by kind: marketplace asking medians are asks, not sales; provider market prices and recorded sale comps are labeled by source. We aggregate — we do not invent.

Rate limits

  • General /public endpoints: 120 requests/minute per IP.
  • /public/images/*: 600 requests/minute per IP (its own bucket, so image-heavy pages don't starve data calls).
  • Over the limit → 429 with a Retry-After header. Honor it.

Stability promise

/public is v1, additive-only. Fields are never renamed or removed and response shapes never break; new fields and endpoints may appear at any time. Build against what's documented here and your integration keeps working.

Who runs this? About ISO — the archive, the company, and how we source prices and descriptions.