OverwolfSpire Codex is now on Overwolf. Learn more

Developers

Build tools, bots, and content with Spire Codex data. Everything is free and open.

Tooltip Widget

Add Wowhead-style hoverable tooltips for cards, relics, and potions to any website. One script tag, zero dependencies.

Installation

<script src="https://spire-codex.com/widget/spire-codex-tooltip.js"></script>

Syntax

[[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]]Achievement

JavaScript API

SpireCodex.scan()Re-scan the page for new [[...]] patterns (for SPAs)
SpireCodex.scan(element)Scan a specific DOM element

Changelog Widget

Embed a compact, interactive changelog viewer showing Spire Codex update history with version switching.

Installation

<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)

REST API

Full game database accessible via a public REST API. No authentication required for casual use (rate limited per IP). For scripts and tools, create an API key on your profile page and send it as the X-API-Key header to get your own dedicated rate limit (counted per endpoint) instead of sharing the per-IP cap. Responses carry X-RateLimit-Remaining / X-RateLimit-Reset so you can pace requests.

Rate limits

No key300/minuteper IP
General15/minuteany issued key
Registered60/minutecreate one on your profile
Academia100/minutegranted on request
Paid120/minutesupporters

All caps count per endpoint. Watch X-RateLimit-Remaining and back off on 429 (Retry-After is set).

Base URL

https://spire-codex.com

Beta channel (unreleased content from the Steam beta branch): add ?channel=beta to any entity endpoint. The current beta version is at /api/beta/version and the full diff against main at /api/beta/diff.

Endpoints

Full interactive docs at /docs (auto-generated from the backend, always current).

Entities

GET/api/cardsAll cards (filter: color, type, rarity, keyword, tag, spawns, search)
GET/api/cards/{id}Single card
GET/api/charactersAll characters
GET/api/characters/{id}Single character
GET/api/relicsAll relics (filter: rarity, pool, ancient, search)
GET/api/relics/{id}Single relic
GET/api/potionsAll potions (filter: rarity, pool, search)
GET/api/potions/{id}Single potion
GET/api/monstersAll monsters (filter: type, search)
GET/api/monsters/{id}Single monster
GET/api/powersAll powers (filter: type, stack_type, search)
GET/api/powers/{id}Single power
GET/api/eventsAll events (filter: type, act, search)
GET/api/events/{id}Single event
GET/api/encountersAll encounters (filter: room_type, act, search)
GET/api/encounters/{id}Single encounter
GET/api/enchantmentsAll enchantments
GET/api/enchantments/{id}Single enchantment
GET/api/keywordsCard keywords
GET/api/keywords/{id}Single keyword
GET/api/intentsAll intent types
GET/api/intents/{id}Single intent
GET/api/orbsAll orb types
GET/api/orbs/{id}Single orb
GET/api/afflictionsAffliction types
GET/api/afflictions/{id}Single affliction
GET/api/modifiersCustom mode modifiers
GET/api/modifiers/{id}Single modifier
GET/api/achievementsAll achievements
GET/api/achievements/{id}Single achievement
GET/api/badgesAll badges
GET/api/badges/{id}Single badge
GET/api/epochsAll epochs
GET/api/epochs/{id}Single epoch
GET/api/storiesAll stories
GET/api/stories/{id}Single story
GET/api/actsAll acts
GET/api/acts/{id}Single act
GET/api/ascensionsAll ascension levels
GET/api/ascensions/{id}Single ascension
GET/api/glossaryAll glossary terms
GET/api/glossary/{id}Single term

Aggregations & Lookups

GET/api/statsEntity counts
GET/api/ancient-poolsAll ancient relic pools with conditions
GET/api/ancient-pools/{id}Pools for a single ancient
GET/api/unlocksUnlockable entities grouped by type with epoch context
GET/api/history/{entity_type}/{entity_id}Per-entity version history from changelogs
GET/api/update-history/{entity_type}/{entity_id}Per-entity game-patch update history
GET/api/names/{entity_type}/{entity_id}Cross-language name lookup for an entity
GET/api/searchUnified site search across entities, reference entries, mechanics, guides, and news (q, lang)
GET/api/changelogsAll changelogs
GET/api/changelogs/recent-additionsNewest entities surfaced for the homepage band
GET/api/changelogs/{tag}Single changelog by tag (e.g. v1.0.20)
GET/api/newsSteam announcements (mirrored locally for permanence)
GET/api/news/{gid}Single news article with sanitized body
GET/api/versionsAvailable beta data versions for the version picker

Community & Submissions

GET/api/guidesAll guides (filter: category, difficulty, tag, search)
GET/api/guides/{slug}Single guide with rendered markdown
POST/api/guidesSubmit a guide (Discord webhook, rate-limited)
POST/api/runsSubmit a run for community stats and leaderboards
POST/api/runs/claimAttach a username to previously-submitted runs by hash
GET/api/runs/listBrowse submitted runs with filters and pagination (incl. ascension_min/ascension_max and winrate_min/winrate_max by submitter win rate — the content brackets)
GET/api/runs/leaderboardRun leaderboards (fastest, highest_ascension); filter by character, players, game_mode, ascension_min, winrate_min (the content brackets)
GET/api/runs/shared/{run_hash}Single submitted run by hash (rate-limited)
GET/api/runs/statsAggregate community stats (filter by character, ascension, username)
GET/api/runs/community-statsFun community datasets: event decision splits, deadliest encounters, win rates by ascension/character, records
GET/api/charts/metaChart registry for the /charts explorer: available charts, filters, splits, and run stats
GET/api/charts/{chart}One pre-aggregated chart (filter: players, ascension, game_mode, username, split, bracket=a10|wr30|wr50|wr75 on frame charts, plus per-chart params)
GET/api/beta/diffWhat the current beta adds, changes, and removes per entity type; powers every BETA label
GET/api/beta/versionThe current beta version
GET/api/runs/scores/{type}Codex Score + Codex Elo per entity (cards/relics/potions); ?bracket=a10|wr30|wr50|wr75 grades within a content bracket (the in-game mod sends the same via ?stat_filter=a10|a10_wr30|a10_wr50|a10_wr75); relics accept ?act=1|2|3 to rank by acquisition act; ?character= switches to that character's slice (entries gain a scope field)
GET/api/runs/leaderboard/seed-rankSeed + global standing for one seed (?seed=&steam_id=); rank fields are null without a winning run
POST/api/auth/steam/ticketExchange a Steamworks web auth ticket for the site JWT (in-game silent sign-in); 503 until the server has a Steam key
GET/api/runs/metrics/{type}Dense metrics table: Codex Score, Codex Elo, win rate, pick rate, per-act splits; ?bracket=all|solo|2p|3p|4p|a10|daily|custom|wr30|wr50|wr75 (the content brackets)
GET/api/runs/versionsDistinct game build IDs that have submitted runs
POST/api/feedbackSubmit feedback (Discord webhook)

Bulk Downloads

GET/api/exports/{lang}ZIP of all entity JSON for one language
GET/api/imagesImage gallery categories
GET/api/images/searchSearch images by filename
GET/api/images/game/{version}/{category}/browsePaged folder browsing of a full asset dump (path, offset, limit)
GET/api/images/game/{version}/{category}/downloadZIP of one dump folder's files (path; capped at 2000 files)

Multi-Language

Add ?lang=jpn to any endpoint. 15 languages supported:

eng, deu, esp, fra, ita, jpn, kor, pol, ptb, rus, spa, tha, tur, zhs, zht

Quick Start

cURL

curl https://spire-codex.com/api/cards?color=ironclad&rarity=Rare

Python

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));

Tiny Card Sprite

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 NTinyCard and CardPoolModel.DeckEntryCardColor.

Preview

Ironclad / Attack / Common
Silent / Skill / Uncommon
Defect / Power / Rare
Necrobinder / Skill / Rare
Regent / Attack / Uncommon
Curse
Event
Quest

Sprite assets

All 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 rarity

Pool (card back) colors

From CardPoolModel.DeckEntryCardColor. Match these against the color field returned by /api/cards.

ironclad#D62000
silent#5EBD00
defect#3EB3ED
necrobinder#CD4EED
regent#E36600
colorless#A3A3A3
event#A3A3A3
curse#585B61
quest#24476A
status#FFFFFF
token#FFFFFF

Rarity (banner) colors

From NTinyCard.GetBannerColor. Match against rarity.

Basic#9C9C9C
Starter#9C9C9C
Common#9C9C9C
Uncommon#64FFFF
Rare#FFDA36
Curse#E669FF
Event#13BE1A
Ancient#13BE1A
Quest#F46836
Status#9C9C9C
Token#9C9C9C

Minimal HTML + CSS recipe

Portrait filename: attack for Attack cards, power for Power cards, skill for 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>

React component

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" />

Full card images

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, e.g. cards-full/stable/jpn/bash.webp. All 15 languages are available.

Enchanted card renders

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} and {card} are lowercase ids from /api/enchantments and /api/cards (e.g. sharp, corrupted, sown).
  • Only valid card and enchantment combinations exist (the export uses the game's own applicability rules), so an invalid combo is a 404. The card_type / applicable_to fields on /api/enchantments describe which cards qualify.
  • Base and upgraded variants exist for every combo, in all 14 languages, with the enchantment text fully localized.

Data Exports

Download all game data as a single ZIP archive. Each archive contains JSON files for every entity type (cards, relics, monsters, powers, and more).

Download English Data (ZIP)

15 languages available. Example downloads: Japanese, Korean, Chinese, French, German

Interactive API Docs

Full Swagger/OpenAPI documentation with try-it-out functionality.

Open API Docs →

Open Source

Spire Codex is open source. The data extraction pipeline, API, and frontend are all available on GitHub.

View on GitHub →