OverwolfSpire Codex est désormais sur Overwolf. En savoir plus →

Slay the Spire 2 (STS2) Développeurs

Créez des outils, des bots et du contenu avec les données de Spire Codex. Tout est gratuit et ouvert.

Widget d'infobulles

Ajoutez des infobulles au survol façon Wowhead pour les cartes, reliques et potions sur n'importe quel site. Une balise script, zéro dépendance.

Installation

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

Syntaxe

[[Strike]]Infobulle de carte (type par défaut)
[[card:Bash]]Carte (explicite)
[[relic:Burning Blood]]Relique
[[potion:Fire Potion]]Potion
[[character:Ironclad]]Personnage
[[monster:Jaw Worm]]Monstre
[[power:Strength]]Pouvoir
[[event:Neow]]Événement
[[encounter:Lagavulin]]Rencontre
[[enchantment:Sharp]]Enchantement
[[keyword:Exhaust]]Mot-clé
[[orb:Lightning]]Orbe
[[affliction:Bound]]Affliction
[[achievement:Minimalist]]Succès

API JavaScript

SpireCodex.scan()Réanalyse la page pour de nouveaux motifs [[...]] (pour les SPA)
SpireCodex.scan(element)Analyse un élément DOM précis

Widget de journal des modifications

Intégrez un visualiseur de journal compact et interactif affichant l'historique des mises à jour de Spire Codex avec changement de version.

Installation

<div id="scx-changelog"></div>
<script src="https://spire-codex.com/widget/spire-codex-changelog.js"></script>
data-version="1.0.4"Affiche une version précise (par défaut : la dernière)

API REST

Base de données complète du jeu accessible via une API REST publique. Aucune authentification requise : le quota web par IP couvre la navigation et les appels occasionnels, et l'usage de l'API sans clé bénéficie du taux de base ci-dessous. Pour les scripts et outils, créez une clé API et envoyez-la dans l'en-tête X-API-Key. Créez-en une sur votre page de profil. Une clé regroupe vos requêtes par identité plutôt que par IP (stable entre réseaux, jamais partagée avec d'autres utilisateurs derrière le même NAT) et vous donne un suivi d'utilisation ; son plafond de palier s'applique par endpoint. Les réponses contiennent X-RateLimit-Remaining / X-RateLimit-Reset pour que vous puissiez espacer vos requêtes.

Limites de débit

Trafic du site300/minutepar IP
Sans clé API15/minute
Utilisateur enregistré60/minutecréez-en une sur votre profil
Académique100/minuteaccordé sur demande
Payant120/minutesoutiens

Tous les plafonds comptent par endpoint : le tableau est votre quota sur chaque route, pas un pool global. Quelques endpoints lourds ont leur propre budget qui s'applique à tout appelant, clé ou non (voir l'export de parties ci-dessous ; le ZIP de langue est à 10/heure). Surveillez X-RateLimit-Remaining et patientez en cas de 429 (Retry-After est renseigné).

Export de parties en masse

GET /api/exports/runs?limit=1000&start=2026-06-01T00:00:00Z

Diffuse les parties officielles en JSONL, une partie par ligne.

limit Borne la page ; une page pleine renvoie un curseur pour la suivante.
start / end Restreignent à une fenêtre semi-ouverte de date de soumission. Gardez-les constants pendant la pagination ; le curseur ne les intègre pas.

Cet endpoint dispose de son propre budget de 120 crédits par heure, partagé entre appelants avec et sans clé : une requête paginée coûte 1 crédit, une récupération sans limite en coûte 60. La synchronisation continue fonctionne donc mieux par récupérations paginées espacées d'environ 30 s ; en cas de 429, respectez Retry-After et reprenez avec le même curseur.

Besoin de tout le corpus ? Un appel sans paramètre redirige vers un fichier statique régénéré une fois par jour, /exports/runs-latest.jsonl.gz, avec la même forme de ligne ; /api/exports/runs/manifest indique quand il a été généré et combien de parties il contient. Chaque ligne contient player_token, un identifiant pseudonyme stable du compte ayant soumis la partie, null pour les parties anonymes.

Un seul correctif ? /api/exports/runs?version=v0.111.0 redirige vers un fichier statique par version issu de la carte versions du manifeste, /exports/runs-v0.111.0.jsonl.gz ; combiné à limit et cursor, il parcourt un seul correctif par pages.

URL de base

https://spire-codex.com

Canal bêta (contenu non publié de la branche bêta Steam) : ajoutez ceci à n'importe quel endpoint d'entité : ?channel=beta. Version bêta actuelle : /api/beta/version. Diff complet par rapport à main : /api/beta/diff.

The community stats pages were reorganized: /community-stats, /leaderboards/metrics, /charts, and the /meta page now live under /stats, /leaderboards/elo is /top-players, and run submission moved to /runs/submit. Old URLs redirect.

Endpoints

Documentation interactive complète (générée automatiquement depuis le backend, toujours à jour) : /docs

Entités

GET/api/cardsToutes les cartes (filtres : color, type, rarity, keyword, tag, spawns, search)
GET/api/cards/{id}Une carte
GET/api/charactersTous les personnages
GET/api/characters/{id}Un personnage
GET/api/relicsToutes les reliques (filtres : rarity, pool, ancient, search)
GET/api/relics/{id}Une relique
GET/api/potionsToutes les potions (filtres : rarity, pool, search)
GET/api/potions/{id}Une potion
GET/api/monstersTous les monstres (filtres : type, search)
GET/api/monsters/{id}Un monstre
GET/api/powersTous les pouvoirs (filtres : type, stack_type, search)
GET/api/powers/{id}Un pouvoir
GET/api/eventsTous les événements (filtres : type, act, search)
GET/api/events/{id}Un événement
GET/api/encountersToutes les rencontres (filtres : room_type, act, search)
GET/api/encounters/{id}Une rencontre
GET/api/enchantmentsTous les enchantements
GET/api/enchantments/{id}Un enchantement
GET/api/keywordsMots-clés des cartes
GET/api/keywords/{id}Un mot-clé
GET/api/intentsTous les types d'intention
GET/api/intents/{id}Une intention
GET/api/orbsTous les types d'orbe
GET/api/orbs/{id}Un orbe
GET/api/afflictionsTypes d'affliction
GET/api/afflictions/{id}Une affliction
GET/api/modifiersModificateurs du mode personnalisé
GET/api/modifiers/{id}Un modificateur
GET/api/achievementsTous les succès
GET/api/achievements/{id}Un succès
GET/api/badgesTous les badges
GET/api/badges/{id}Un badge
GET/api/epochsToutes les époques
GET/api/epochs/{id}Une époque
GET/api/storiesToutes les histoires
GET/api/stories/{id}Une histoire
GET/api/actsTous les actes
GET/api/acts/{id}Un acte
GET/api/ascensionsTous les niveaux d'ascension
GET/api/ascensions/{id}Une ascension
GET/api/glossaryTous les termes du glossaire
GET/api/glossary/{id}Un terme

Agrégations et recherches

GET/api/statsNombre d'entités
GET/api/ancient-poolsTous les pools de reliques des anciens avec conditions
GET/api/ancient-pools/{id}Pools d'un ancien
GET/api/unlocksEntités déblocables regroupées par type avec le contexte d'époque
GET/api/history/{entity_type}/{entity_id}Historique des versions par entité d'après les journaux des modifications
GET/api/update-history/{entity_type}/{entity_id}Historique des mises à jour par patch du jeu pour chaque entité
GET/api/names/{entity_type}/{entity_id}Recherche du nom d'une entité dans toutes les langues
GET/api/searchRecherche unifiée du site sur les entités, entrées de référence, mécaniques, guides, actualités, pages et fichiers image, avec tolérance aux fautes de frappe (q, lang)
GET/api/search/semanticMeaning-based entity search, same item shape as /api/search (q, limit); empty when the feature is off
GET/api/merchant/configMerchant pricing config extracted from the game
GET/api/mechanics/constantsMechanics constants: room odds, gold ranges, ascension tuning
GET/api/mechanics/sectionsIndex of the mechanics pages
GET/api/mechanics/sections/{slug}One mechanics page as markdown with template tokens resolved
GET/api/changelogsTous les journaux des modifications
GET/api/changelogs/recent-additionsEntités les plus récentes affichées dans le bandeau de la page d'accueil
GET/api/changelogs/{tag}Un journal des modifications par tag (ex. v1.0.20)
GET/api/newsAnnonces Steam (copiées localement pour les conserver)
GET/api/news/{gid}Un article d'actualité avec corps assaini
GET/api/versionsVersions de données bêta disponibles pour le sélecteur de version
GET/api/news/codexSpire Codex site news, newest first
GET/api/news/codex/{slug}One site news entry
GET/api/announcementsActive site banner messages

Languages

GET/api/languagesAvailable languages with display names
GET/api/translationsTranslation maps for filter values and UI strings (lang)
GET/api/localizationsThe game's own localization tables as ICU MessageFormat, all of them or the ones named in ?tables= (max 50; unknown names are 404)
GET/api/localizations/tablesNames of the available localization tables
GET/api/localizations/{table}One localization table

Communauté et soumissions

GET/api/guidesTous les guides (filtres : category, difficulty, tag, search)
GET/api/guides/{slug}Un guide avec le markdown rendu
POST/api/guidesSoumettre un guide (webhook Discord, à débit limité)
POST/api/runsSubmit a run for community stats and leaderboards. The run is attached to an account only with Authorization: Bearer <jwt>; a bare steam_id is kept as a hint
POST/api/runs/claimAttach the signed-in account to previously-submitted anonymous runs by hash
GET/api/runs/listParcourir les parties soumises avec filtres et pagination (dont ascension_min/ascension_max et winrate_min/winrate_max selon le taux de victoire du contributeur, les tranches de contenu) Chaque ligne contient player_token, un identifiant pseudonyme stable du compte ayant soumis la partie, null pour les parties anonymes. total_is_lower_bound is true when the exact count ran out of time and total is a capped lower bound.
GET/api/runs/leaderboardRun leaderboards (fastest, highest_ascension); filter by character, players, game_mode, ascension_min, winrate_min (the content brackets), build_id
GET/api/runs/shared/{run_hash}Une partie soumise par son hash (à débit limité)
GET/api/runs/statsStatistiques communautaires agrégées (filtrer par character, ascension, username)
GET/api/runs/community-statsThe /stats hub dataset: event decision splits, deadliest encounters, win rates by ascension/character, records. Takes the same bracket keys as the metrics tables; an unknown bracket returns HTTP 400
GET/api/charts/metaRegistre des graphiques pour l'explorateur /charts : graphiques disponibles, filtres, découpages et statistiques de parties
GET/api/charts/{chart}One pre-aggregated chart (filter: players, ascension, game_mode, username, split, bracket=a10|wr30|wr50|wr75, build_id, plus per-chart params). A saved chart id from the chart builder returns that saved chart instead
POST/api/chartsSave a chart spec to your profile (bearer token, 100 per account)
PATCH/api/charts/{id}Update the title, visibility or spec of your own saved chart; DELETE removes it
GET/api/charts/mineYour saved charts, newest first (bearer token)
GET/api/charts/publicNewest public saved charts (limit)
GET/api/tierlists/shared/{share_id}Public read-only view of a shared tier list
GET/api/beta/diffCe que la bêta actuelle ajoute, modifie et retire par type d'entité ; alimente chaque étiquette BETA
GET/api/beta/versionLa version bêta actuelle
GET/api/runs/scores/{type}Codex Score + Codex Elo per entity (cards/relics/potions); ?bracket= grades within a run bracket (a10|wr30|wr50|wr75, a game version, or any metrics bracket; unknown is HTTP 400) (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-rankGraine + classement global pour une graine (?seed=&steam_id=) ; les champs de rang sont null sans partie gagnée
POST/api/auth/steam/ticketÉchanger un ticket d'authentification web Steamworks contre le JWT du site (connexion silencieuse en jeu) ; 503 tant que le serveur n'a pas de clé Steam
GET/api/runs/metrics/{type}Dense metrics table for cards/relics/potions, one row per entity: Codex Score, win_rate with a Wilson 95% win_rate_ci, hold_rate, lift and lift_n over the floor-adjusted expectation (null under 20 seats), Codex Elo and pick_rate from free choice screens for cards and relics, a wax block on relics (Toy Box copies split out), and used/use_rate on potions. Counts are per seat, so a 4P run is four seats; the response carries total_runs, total_seats, total_wins and data_through. ?bracket=all|solo|2p|3p|4p|a10|daily|custom|wr30|wr50|wr75 or a composite like solo:standard; ?character= switches to that character's slice (rows gain per-character Elo and Pick%). An unknown bracket returns HTTP 400
GET/api/runs/metrics/shopsShop shelf table, one row per card, relic or potion: seen, bought, buy_rate, and the buyers' win_rate, win_rate_ci and lift. Same bracket keys as the other metrics tables
GET/api/runs/metrics/eventsEvent option table: chosen, share of that event's choices, win_rate, win_rate_ci and lift. Same bracket keys as the other metrics tables
GET/api/runs/metrics/campfiresRest-site choice table (rest, smith, and the rest) with a localized name per ?lang=: chosen, share, low_hp_share, win_rate, win_rate_ci and lift. Same bracket keys as the other metrics tables
GET/api/runs/versionsIdentifiants de build du jeu distincts ayant des parties soumises
GET/api/runs/leaderboard/rank/{run_hash}Rank of one winning run within its ladder (category)
GET/api/leaderboards/eloTop players by Codex Elo over solo A10 standard runs, refreshed nightly; powers /top-players (limit, min_runs)
GET/api/runs/stats/{type}/{id}Community stats for one card, relic or potion, with per-bracket and per-character splits
GET/api/runs/stats/{type}/{id}/historyDaily Codex Score and Elo history for one entity (bracket=all|a10|wr30|wr50|wr75)
GET/api/runs/top/{type}/{character}Most-picked entities of a type for one character (limit)
GET/api/runs/encounter-statsPer-encounter appearances, fatal rate, avg damage and turns, per character too (act, room_type, multiplayer, bracket, build_id, encounter, page, limit)
GET/api/runs/encounter-seriesThe given encounters (max 20) rolled up per bracket and per recent game version
GET/api/runs/pulseCommunity run and win totals plus data_through
GET/api/runs/snapshot-statusWhether the stats are loaded or rebuilding
GET/api/runs/{run_hash}/similarNearest winning solo decks to a run and what they took that it didn't
GET/api/runs/archetypesCommunity deck archetypes, clustered nightly
GET/api/runs/encounter-buildsWhich archetypes die to an encounter and which walk past it (encounter)
GET/api/runs/deck-advisorWhat the winning decks nearest a partial deck carry that it doesn't yet (character, cards, relics)
GET/api/runs/pick-coachNearest archetypes for a partial deck and a score per offered card (character, cards, relics, offer, target)
GET/api/pairings/{item_type}/{item_id}Cards, relics and potions that show up in the same runs as this item
GET/api/draft-recs/{item_type}/{item_id}Cards players most often draft when they already hold this item
POST/api/draft-adviceRank the offered cards for the current deck
GET/api/replaysRuns with a replay to watch; same filters and row shape as /api/runs/list plus replay_url
GET/api/replays/summaryHow many replays are watchable, overall and per character
GET/api/runs/{run_hash}/replayThe stored replay journal as gzip; POST uploads one for a run you own, DELETE removes it
GET/api/players/{username}/insightsOne player's public insights with community comparison; 404 for unknown or private profiles
GET/api/players/{username}/statsStatistiques propres d'un joueur sur les cartes, reliques, potions, événements, boutiques et feux de camp avec Lift personnel ; mêmes filtres et confidentialité que insights
GET/api/presence/activeLive runs from the in-game mod, deepest first
GET/api/presence/{steam_id}One player's live run; 404 when they aren't in one
GET/api/thanksGitHub contributors, special thanks, and public supporters
GET/api/mod/latestLatest mod build and the game version it was verified against
GET/api/rate-limitsThe public rate-limit tiers
POST/api/feedbackEnvoyer un retour (webhook Discord)

Téléchargements en masse

GET/api/exports/runsFlux JSONL des parties officielles (pagination limit/start/end/cursor ; budget propre de 120 crédits par heure, voir Export de parties en masse ci-dessus)
GET/api/exports/runs/manifestWhen the daily full run dump was generated and how many runs it holds
GET/api/exports/{lang}ZIP de tous les JSON d'entités pour une langue (10/heure)
GET/api/imagesCatégories de la galerie d'images
GET/api/images/searchRechercher des images par nom de fichier
GET/api/images/game/{version}/{category}/browseNavigation paginée dans les dossiers d'un dump complet d'assets (path, offset, limit)
GET/api/images/game/{version}/{category}/downloadZIP des fichiers d'un dossier du dump (path ; plafonné à 2000 fichiers)

Multilingue

Ajoutez ce paramètre de requête à n'importe quel endpoint : ?lang=jpn. 15 langues prises en charge :

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

Démarrage rapide

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

Sprite de mini-carte

Reproduisez la miniature de carte du jeu (utilisée sur les écrans Historique des parties / Game Over) dans n'importe quel projet web. Six calques PNG composés avec mask-image en CSS, sans canvas, sans WebGL, juste des sprites teintés. Les couleurs viennent directement du code décompilé du jeu : NTinyCard, CardPoolModel.DeckEntryCardColor.

Aperçu

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

Fichiers de sprites

Les 10 PNG sont servis avec CORS activé, placez l'URL de base devant chaque nom de fichier. Chaque sprite fait 128×128, RGBA, blanc sur transparent (conçu pour être teinté en 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

Couleurs de pool (dos de carte)

Source : CardPoolModel.DeckEntryCardColor. Faites-les correspondre au champ color renvoyé par /api/cards.

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

Couleurs de rareté (bannière)

Source : NTinyCard.GetBannerColor. Faites-les correspondre au champ rarity.

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

Recette HTML + CSS minimale

Nom de fichier du portrait : attack = Cartes d'Attaque, power = Cartes de Pouvoir, skill = tout le reste (Compétence, Statut, Malédiction, …)

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

Composant React

Version React prête à l'emploi. 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" />

Images de cartes complètes

Chaque carte de /api/cards inclut deux URL prêtes à l'emploi de la carte complète rendue par le jeu (cadre, illustration, bannière et texte, exactement comme en jeu). Les cartes des anciens sont des webp animés.

  • image_url_card — La carte de base. null pour la seule carte sans rendu (mad_science) ; utilisez alors image_url (l'illustration du portrait) en repli.
  • image_url_card_upg — La carte améliorée. null quand la carte n'a pas d'amélioration.
// 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"
}

Les rendus localisés se trouvent dans un sous-dossier de langue, par exemple : cards-full/stable/jpn/bash.webp. Les 15 langues sont disponibles.

Rendus de cartes enchantées

Chaque carte est aussi rendue avec chaque enchantement qu'elle peut légalement recevoir, exactement comme l'aperçu d'enchantement en jeu la dessine (badge, valeur et texte ajouté). Les URL suivent un seul modèle :

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}: identifiants en minuscules issus de /api/enchantments et /api/cards (ex. sharp, corrupted, sown).
  • Seules les combinaisons valides de carte et d'enchantement existent (l'export utilise les règles d'applicabilité du jeu), une combinaison invalide renvoie donc 404. Les champs card_type / applicable_to de /api/enchantments décrivent quelles cartes sont éligibles.
  • Des variantes de base et améliorée existent pour chaque combinaison, dans les 14 langues, avec le texte d'enchantement entièrement localisé.

Exports de données

Téléchargez toutes les données du jeu en une seule archive ZIP. Chaque archive contient des fichiers JSON pour chaque type d'entité (cartes, reliques, monstres, pouvoirs et plus).

Télécharger les données en anglais (ZIP)

15 langues disponibles. Exemples de téléchargements : Japonais, Coréen, Chinois, Français, Allemand

Documentation interactive de l'API

Documentation Swagger/OpenAPI complète avec fonction d'essai.

Ouvrir la documentation de l'API →

Open source

Spire Codex est open source. Le pipeline d'extraction des données, l'API et le frontend sont tous disponibles sur GitHub.

Voir sur GitHub →