Download the data
The whole database is one file. Fetch it once, verify it, and query it locally.
The API is a set of static files on a CDN, so the newest verified release is the live data: there is nothing fresher to poll. For anything beyond a single lookup, download registry.json once, check its digest, and work from your copy. To learn when a new release exists, read versions.json (60-second cache; hourly is plenty, the data changes a few times a year). The per-object files are for one lookup at a time; please do not crawl them.
The current release
- Release
v3.4.0- Released
- 2026-09-22
- Schema
- 12
- Contents
- 6 sets · 1,100 cards · 3,088 printings · 1,129 history rows
- Size
- 6.5 MB as stored. The edge serves it compressed, so a download is roughly 450 KB.
- SHA-256
5af55b1dd26880eaebe2ae6d2b1004991dc374620140145a7fc859334df49e13
Every page on this site was built from that release, after the build verified this digest against versions.json. What you see here and what the API serves are one file.
The files
Each file is linked twice. The pinned address is under the release root and its bytes never change; cache it forever. The latest address is the /v3/ alias, which answers 302 to the same path under the newest verified v3 release, so a browser follows it and curl needs --location.
| File | What it is | Pinned | Latest |
|---|---|---|---|
registry.json | Everything: sets, cards, printings and the three histories, in one file. | v3.4.0 | v3 |
registry.json.sha256 | Its SHA-256, in sha256sum format. | v3.4.0 | v3 |
schema.json | The JSON Schema the file validates against. | v3.4.0 | v3 |
types.d.ts | TypeScript declarations generated from the schema. From v3.3.3 on. | v3.4.0 | v3 |
index.json | What the release contains and where each object lives. | v3.4.0 | v3 |
changes.json | What the release changed against the one before it, by id and field. From v3.3.2 on. | v3.4.0 | v3 |
index/cards.json | Compact card records, for search and filtering. | v3.4.0 | v3 |
index/printings.json | Compact printing records, with image_hash and image_status. | v3.4.0 | v3 |
index/slugs.json | Every slug ever issued, mapped to its printing_id. | v3.4.0 | v3 |
history/cards.json | Every recorded gameplay face of every card. | v3.4.0 | v3 |
Every release is also mirrored on GitHub: https://raw.githubusercontent.com/sadkinglabs/sorcery-registry/{tag}/export/registry.json, the same bytes and the same digest.
Fetch and verify
curl --fail --location \
--user-agent 'my-card-tool/1.0 ([email protected])' \
--output registry.json 'https://api.kairosarchive.net/v3/registry.json'
curl --fail --location --silent 'https://api.kairosarchive.net/v3/registry.json.sha256' | sha256sum --checkIdentify automated clients with a User-Agent naming your project and a contact; requests without one are refused. Releases and versioning has the same steps in Python, resolving the tag from versions.json first.
Typed records in TypeScript
Every release root carries types.d.ts, generated from schema.json at release time. One import gives you typed records, with every field's description as JSDoc, and nothing to install.
curl --fail --location -O 'https://api.kairosarchive.net/v3/types.d.ts'
curl --fail --location -O 'https://api.kairosarchive.net/v3/registry.json'// registry.ts - next to the two files above
import { readFile } from "node:fs/promises";
import type { Registry, Card } from "./types";
const registry: Registry = JSON.parse(await readFile("registry.json", "utf8"));
const bears: Card | undefined = registry.cards.find((c) => c.name === "Polar Bears");
console.log(bears?.codex_id, bears?.power);Run it with node registry.ts on Node 22.18 or newer, which strips the types itself. To type-check it, install the compiler and Node's own type definitions once, npm i -D typescript @types/node (the registry's types need nothing; these two are for tsc and for node:fs), then npx tsc --strict --noEmit --target es2022 --module esnext --moduleResolution bundler --types node registry.ts. In a browser or a Worker the same declarations apply to a fetch and need no Node types: await (await fetch(url)).json() as Registry, type-checked with --lib es2022,dom instead of --types node.
The file declares Registry, one interface per record (Card, Printing, RegistrySet, CardHistoryRow, NameHistoryRow, SlugHistoryRow, Header), the shared shapes Face, PrintingFace and ImageUrls, and the aliases CodexId, PrintingId, SetCode, IsoDate, Threshold and ImageStatus. Card and CardHistoryRow extend Face, so a function that takes a face reads either. The declarations describe; they do not validate: JSON.parse accepts any JSON, so check a file against the schema if it did not come from the API. Releases before v3.3.3 have no types.d.ts.
What is inside
registry.json holds a header and six arrays: sets, cards, printings, slug_history, name_history and card_history. Cards carry gameplay data and are keyed by codex_id; printings carry physical facts and are keyed by printing_id; the histories record every slug, name and gameplay face the registry has ever seen, each with the range of dates it was in force. Cards and printings and history and errata explain the fields; the schema is the contract.
Reference: registry API contract and published object definitions. Report a data or documentation issue.