Spire Codex is now on Overwolf. Get the in-game overlay with live card lookups and one-click run uploads. Learn more →Build tools, bots, and content with Spire Codex data. Everything is free and open.
Add Wowhead-style hoverable tooltips for cards, relics, and potions to any website. One script tag, zero dependencies.
<script src="https://spire-codex.com/widget/spire-codex-tooltip.js"></script>[[Strike]]Card tooltip (default type)[[card:Bash]]Card (explicit)[[relic:Burning Blood]]Relic[[potion:Fire Potion]]Potion[[character:Ironclad]]Character[[monster:Jaw Worm]]Monster[[power:Strength]]Power[[event:Neow]]Event[[encounter:Lagavulin]]Encounter[[enchantment:Sharp]]Enchantment[[keyword:Exhaust]]Keyword[[orb:Lightning]]Orb[[affliction:Bound]]Affliction[[achievement:Minimalist]]AchievementSpireCodex.scan()Re-scan the page for new [[...]] patterns (for SPAs)SpireCodex.scan(element)Scan a specific DOM elementEmbed a compact, interactive changelog viewer showing Spire Codex update history with version switching.
<div id="scx-changelog"></div>
<script src="https://spire-codex.com/widget/spire-codex-changelog.js"></script>data-version="1.0.4"Show a specific version (default: latest)Full game database accessible via a public REST API. No authentication required: the per-IP website allowance covers browsing and casual calls, and keyless API usage gets the base rate below. For scripts and tools, create an API key and send it as the X-API-Key header. A key buckets your requests by identity instead of IP (stable across networks, never shared with other users behind the same NAT) and gives you usage tracking; its tier cap applies per endpoint. Responses carry X-RateLimit-Remaining / X-RateLimit-Reset so you can pace requests.
| Website Traffic | 300/minute | per IP |
| No API key | 15/minute | |
| Registered User | 60/minute | create one on your profile |
| Academia | 100/minute | granted on request |
| Paid | 120/minute | supporters |
All caps count per endpoint: the table is your allowance on each route, not a global pool. A few heavy endpoints carry their own budgets that apply to every caller regardless of key (see the run export below; the language ZIP is 10/hour). Watch X-RateLimit-Remaining and back off on 429 (Retry-After is set).
Reproduce the game's in-run card thumbnail (used on the Run History / Game Over screens) in any web project. Six PNG layers composited with CSS mask-image, no canvas, no WebGL, just tinted sprites. Colors come straight from the decompiled game code: NTinyCard, CardPoolModel.DeckEntryCardColor.



Ironclad / Attack / Common

Download all game data as a single ZIP archive. Each archive contains JSON files for every entity type (cards, relics, monsters, powers, and more).
Full Swagger/OpenAPI documentation with try-it-out functionality.
Open API Docs →Spire Codex is open source. The data extraction pipeline, API, and frontend are all available on GitHub.
View on GitHub →GET /api/exports/runs?limit=1000&start=2026-06-01T00:00:00ZStreams official runs as JSONL, one run per line.
limit Bounds the page; a full page returns a cursor for the next one.start / end Restrict to a half-open submitted-at window. Keep them constant while paging; the cursor does not embed them.This endpoint has its own budget of 120 credits per hour, shared by keyed and anonymous callers alike: a paginated request costs 1 credit, an unbounded pull (no limit) costs 60. Sustained syncing therefore works best as paginated pulls spaced ~30s apart; on 429, honor Retry-After and resume with the same cursor.
Need the whole corpus? A call with no parameters redirects to a static file rebuilt once a day, /exports/runs-latest.jsonl.gz, with the same line shape; /api/exports/runs/manifest reports when it was generated and how many runs it holds. Each line carries player_token, a stable pseudonymous id for the submitting account, null on anonymous runs.
https://spire-codex.comBeta channel (unreleased content from the Steam beta branch): add this to any entity endpoint: ?channel=beta. Current beta version: /api/beta/version. Full diff against main: /api/beta/diff.
Full interactive docs (auto-generated from the backend, always current): /docs
Add this query parameter to any endpoint: ?lang=jpn. 15 languages supported:
eng, deu, esp, fra, ita, jpn, kor, pol, ptb, rus, spa, tha, tur, zhs, zht
cURL
curl https://spire-codex.com/api/cards?color=ironclad&rarity=RarePython
import requests
cards = requests.get("https://spire-codex.com/api/cards", params={"color": "ironclad"}).json()
for card in cards:
print(f"{card['name']} - {card['type']} ({card['rarity']})")JavaScript
const res = await fetch("https://spire-codex.com/api/relics?pool=ironclad");
const relics = await res.json();
console.log(relics.map(r => r.name));




Defect / Power / Rare


Necrobinder / Skill / Rare


Regent / Attack / Uncommon


Curse


Event


QuestAll 10 PNGs are served with CORS enabled, drop the base URL in front of each filename. Each sprite is 128×128, RGBA, white-on-transparent (meant to be tinted via CSS).
https://spire-codex.com/static/images/ui/run_history_card/
card_back.png ← tinted by pool
desc_box.png ← dark description area (render at 25% opacity)
attack_portrait.png ← portrait per card type
attack_portrait_shadow.png
skill_portrait.png
skill_portrait_shadow.png
power_portrait.png
power_portrait_shadow.png
banner_shadow.png ← render at 60% opacity
banner.png ← tinted by raritySource: CardPoolModel.DeckEntryCardColor. Match these against the color field returned by /api/cards.
Source: NTinyCard.GetBannerColor. Match against the rarity field.
Portrait filename: attack = Attack cards, power = Power cards, skill = everything else (Skill, Status, Curse, …)
<div class="tiny-card" style="
--back: #D62000; /* pool color, Ironclad */
--banner: #FFDA36; /* rarity color, Rare */
position: relative;
width: 64px;
height: 64px;
">
<!-- 1. card back, tinted by pool -->
<div class="layer" style="
background-color: var(--back);
mask: url(https://spire-codex.com/static/images/ui/run_history_card/card_back.png) center/contain no-repeat;
-webkit-mask: url(https://spire-codex.com/static/images/ui/run_history_card/card_back.png) center/contain no-repeat;
"></div>
<!-- 2. description box -->
<img class="layer" src="https://spire-codex.com/static/images/ui/run_history_card/desc_box.png" style="opacity:.25">
<!-- 3. portrait shadow + portrait (attack/skill/power) -->
<img class="layer" src="https://spire-codex.com/static/images/ui/run_history_card/attack_portrait_shadow.png">
<img class="layer" src="https://spire-codex.com/static/images/ui/run_history_card/attack_portrait.png"
style="filter: brightness(.95) sepia(.15)">
<!-- 4. banner shadow + banner tinted by rarity -->
<img class="layer" src="https://spire-codex.com/static/images/ui/run_history_card/banner_shadow.png" style="opacity:.6">
<div class="layer" style="
background-color: var(--banner);
mask: url(https://spire-codex.com/static/images/ui/run_history_card/banner.png) center/contain no-repeat;
-webkit-mask: url(https://spire-codex.com/static/images/ui/run_history_card/banner.png) center/contain no-repeat;
"></div>
</div>
<style>
.tiny-card .layer {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: contain;
}
</style>Drop-in React version. Source: TinyCard.tsx
import TinyCard from "./TinyCard";
// Feed in the three fields from /api/cards:
<TinyCard color="ironclad" type="Attack" rarity="Rare" className="w-16 h-16" />Every card from /api/cards includes two ready-to-use URLs for the full game-rendered card (frame, art, banner, and text, exactly as it looks in-game). Ancient cards are animated webps.
image_url_card — The base card. null for the one card with no render (mad_science); fall back to image_url (the portrait art) there.image_url_card_upg — The upgraded card. null when the card has no upgrade.// e.g. /api/cards/bash
{
"id": "BASH",
"image_url": "/static/images/cards/bash.webp", // portrait art
"image_url_card": "https://cdn.spire-codex.com/cards-full/stable/bash.webp",
"image_url_card_upg": "https://cdn.spire-codex.com/cards-full/stable/bash_upg.webp"
}Localized renders live under a language subfolder, for example: cards-full/stable/jpn/bash.webp. All 15 languages are available.
Every card is also rendered with each enchantment it can legally take, exactly as the in-game enchant preview draws it (badge, amount, and added card text). The URLs follow one pattern:
https://cdn.spire-codex.com/cards-full/stable/ench/{enchantment}/{card}.webp // English, base
https://cdn.spire-codex.com/cards-full/stable/ench/{enchantment}/{card}_upg.webp // English, upgraded
https://cdn.spire-codex.com/cards-full/stable/{lang}/ench/{enchantment}/{card}.webp // localized
// e.g. Anger with Corrupted, in Japanese:
https://cdn.spire-codex.com/cards-full/stable/jpn/ench/corrupted/anger.webp{enchantment} / {card}: lowercase ids from /api/enchantments and /api/cards (e.g. sharp, corrupted, sown).