OverwolfSpire Codex теперь доступен в Overwolf. Подробнее →

Slay the Spire 2 (STS2) Разработчики

Создавайте инструменты, ботов и контент на данных Spire Codex. Всё бесплатно и открыто.

Виджет подсказок

Добавьте на любой сайт всплывающие подсказки в стиле Wowhead для карт, реликвий и зелий. Один тег script, ноль зависимостей.

Установка

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

Синтаксис

[[Strike]]Подсказка карты (тип по умолчанию)
[[card:Bash]]Карта (явно)
[[relic:Burning Blood]]Реликвия
[[potion:Fire Potion]]Зелье
[[character:Ironclad]]Персонаж
[[monster:Jaw Worm]]Монстр
[[power:Strength]]Сила
[[event:Neow]]Событие
[[encounter:Lagavulin]]Сражение
[[enchantment:Sharp]]Зачарование
[[keyword:Exhaust]]Ключевое слово
[[orb:Lightning]]Сфера
[[affliction:Bound]]Недуг
[[achievement:Minimalist]]Достижение

JavaScript API

SpireCodex.scan()Повторно сканирует страницу на новые шаблоны [[...]] (для SPA)
SpireCodex.scan(element)Сканирует конкретный элемент DOM

Виджет списка изменений

Встройте компактный интерактивный просмотрщик списка изменений с историей обновлений Spire Codex и переключением версий.

Установка

<div id="scx-changelog"></div>
<script src="https://spire-codex.com/widget/spire-codex-changelog.js"></script>
data-version="1.0.4"Показывает конкретную версию (по умолчанию: последняя)

REST API

Полная база данных игры доступна через публичный REST API. Аутентификация не нужна: лимит сайта на IP покрывает просмотр и редкие вызовы, а использование API без ключа получает базовый лимит ниже. Для скриптов и инструментов создайте ключ API и передавайте его в заголовке X-API-Key. Создайте его на странице профиля. Ключ группирует ваши запросы по учётной записи, а не по IP (стабильно между сетями, никогда не делится с другими пользователями за тем же NAT) и даёт учёт использования; лимит уровня применяется на каждый эндпоинт. Ответы содержат X-RateLimit-Remaining / X-RateLimit-Reset, чтобы вы могли регулировать частоту запросов.

Ограничения запросов

Трафик сайта300/minuteна IP
Без ключа API15/minute
Зарегистрированный пользователь60/minuteсоздайте в своём профиле
Академический100/minuteпо запросу
Платный120/minuteспонсоры

Все лимиты считаются на каждый эндпоинт: таблица — это ваша квота на каждый маршрут, а не общий пул. Несколько тяжёлых эндпоинтов имеют собственные бюджеты, которые действуют для всех вызывающих независимо от ключа (см. экспорт забегов ниже; языковой ZIP — 10 в час). Следите за X-RateLimit-Remaining и делайте паузу при 429 (задаётся Retry-After).

Массовый экспорт забегов

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

Передаёт официальные забеги в формате JSONL, по одному забегу на строку.

limit Ограничивает страницу; полная страница возвращает курсор для следующей.
start / end Ограничивают полуоткрытым окном по времени отправки. Держите их неизменными при пагинации; курсор их не содержит.

У этого эндпоинта собственный бюджет в 120 кредитов в час, общий для вызывающих с ключом и без: постраничный запрос стоит 1 кредит, неограниченная выгрузка (без limit) — 60. Поэтому постоянная синхронизация лучше всего работает постраничными запросами с интервалом ~30 с; при 429 соблюдайте Retry-After и продолжайте с тем же курсором.

Нужен весь корпус? Вызов без параметров перенаправляет на статический файл, пересобираемый раз в сутки, /exports/runs-latest.jsonl.gz, с тем же форматом строк; /api/exports/runs/manifest сообщает время генерации и число забегов. Каждая строка содержит player_token, стабильный псевдонимный идентификатор загрузившего аккаунта, null у анонимных забегов.

Нужен только один патч? /api/exports/runs?version=v0.111.0 перенаправляет на статический файл этой версии из карты versions манифеста, /exports/runs-v0.111.0.jsonl.gz; вместе с limit и cursor он вместо этого постранично выгружает один патч.

Базовый URL

https://spire-codex.com

Бета-канал (невыпущенный контент из бета-ветки Steam): добавьте это к любому эндпоинту сущностей: ?channel=beta. Текущая бета-версия: /api/beta/version. Полный список отличий от 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.

Эндпоинты

Полная интерактивная документация (генерируется из бэкенда автоматически, всегда актуальна): /docs

Сущности

GET/api/cardsВсе карты (фильтры: color, type, rarity, keyword, tag, spawns, search)
GET/api/cards/{id}Одна карта
GET/api/charactersВсе персонажи
GET/api/characters/{id}Один персонаж
GET/api/relicsВсе реликвии (фильтры: rarity, pool, ancient, search)
GET/api/relics/{id}Одна реликвия
GET/api/potionsВсе зелья (фильтры: rarity, pool, search)
GET/api/potions/{id}Одно зелье
GET/api/monstersВсе монстры (фильтры: type, search)
GET/api/monsters/{id}Один монстр
GET/api/powersВсе способности (фильтры: type, stack_type, search)
GET/api/powers/{id}Одна способность
GET/api/eventsВсе события (фильтры: type, act, search)
GET/api/events/{id}Одно событие
GET/api/encountersВсе столкновения (фильтры: room_type, act, search)
GET/api/encounters/{id}Одно столкновение
GET/api/enchantmentsВсе зачарования
GET/api/enchantments/{id}Одно зачарование
GET/api/keywordsКлючевые слова карт
GET/api/keywords/{id}Одно ключевое слово
GET/api/intentsВсе типы намерений
GET/api/intents/{id}Одно намерение
GET/api/orbsВсе типы сфер
GET/api/orbs/{id}Одна сфера
GET/api/afflictionsТипы недугов
GET/api/afflictions/{id}Один недуг
GET/api/modifiersМодификаторы пользовательского режима
GET/api/modifiers/{id}Один модификатор
GET/api/achievementsВсе достижения
GET/api/achievements/{id}Одно достижение
GET/api/badgesВсе значки
GET/api/badges/{id}Один значок
GET/api/epochsВсе эпохи
GET/api/epochs/{id}Одна эпоха
GET/api/storiesВсе истории
GET/api/stories/{id}Одна история
GET/api/actsВсе акты
GET/api/acts/{id}Один акт
GET/api/ascensionsВсе уровни восхождения
GET/api/ascensions/{id}Один уровень восхождения
GET/api/glossaryВсе термины глоссария
GET/api/glossary/{id}Один термин

Агрегации и поиск

GET/api/statsКоличество сущностей
GET/api/ancient-poolsВсе пулы реликвий древних с условиями
GET/api/ancient-pools/{id}Пулы одного древнего
GET/api/unlocksОткрываемые сущности, сгруппированные по типу, с контекстом эпохи
GET/api/history/{entity_type}/{entity_id}История версий по каждой сущности из списков изменений
GET/api/update-history/{entity_type}/{entity_id}История изменений сущности по патчам игры
GET/api/names/{entity_type}/{entity_id}Поиск названия сущности на всех языках
GET/api/searchЕдиный поиск по сайту: сущности, справочник, механики, гайды, новости, страницы и файлы изображений, с учётом опечаток (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/changelogsВсе списки изменений
GET/api/changelogs/recent-additionsНовейшие сущности для ленты на главной странице
GET/api/changelogs/{tag}Один список изменений по тегу (например, v1.0.20)
GET/api/newsАнонсы Steam (зеркалируются локально для сохранности)
GET/api/news/{gid}Одна новость с очищенным текстом
GET/api/versionsДоступные версии бета-данных для выбора версии
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

Сообщество и отправки

GET/api/guidesВсе гайды (фильтры: category, difficulty, tag, search)
GET/api/guides/{slug}Один гайд с отрендеренным markdown
POST/api/guidesОтправить гайд (вебхук Discord, с ограничением частоты)
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/listПросмотр отправленных забегов с фильтрами и пагинацией (включая ascension_min/ascension_max и winrate_min/winrate_max по винрейту отправителя, так называемые группы контента) Каждая строка содержит player_token, стабильный псевдонимный идентификатор загрузившего аккаунта, null у анонимных забегов. 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}Один отправленный забег по хэшу (с ограничением частоты)
GET/api/runs/statsСводная статистика сообщества (фильтры 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/metaРеестр графиков для обозревателя /charts: доступные графики, фильтры, разбивки и статистика забегов
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/diffЧто текущая бета добавляет, меняет и убирает по типам сущностей; основа для каждой метки BETA
GET/api/beta/versionТекущая бета-версия
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-rankСид + общее положение для одного сида (?seed=&steam_id=); поля ранга равны null без победного забега
POST/api/auth/steam/ticketОбменять веб-билет аутентификации Steamworks на JWT сайта (тихий вход из игры); 503, пока у сервера нет ключа 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/versionsУникальные ID сборок игры, у которых есть отправленные забеги
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}/statsСобственная статистика игрока по картам, реликвиям, зельям, событиям, магазинам и кострам с личным Lift; те же фильтры и приватность, что у 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/feedbackОтправить отзыв (вебхук Discord)

Массовая загрузка

GET/api/exports/runsJSONL-поток официальных забегов (пагинация limit/start/end/cursor; собственный бюджет 120 кредитов в час, см. массовый экспорт выше)
GET/api/exports/runs/manifestWhen the daily full run dump was generated and how many runs it holds
GET/api/exports/{lang}ZIP со всеми JSON сущностей для одного языка (10 в час)
GET/api/imagesКатегории галереи изображений
GET/api/images/searchПоиск изображений по имени файла
GET/api/images/game/{version}/{category}/browseПостраничный просмотр папок полного дампа ассетов (path, offset, limit)
GET/api/images/game/{version}/{category}/downloadZIP файлов одной папки дампа (path; не более 2000 файлов)

Многоязычность

Добавьте этот параметр запроса к любому эндпоинту: ?lang=jpn. Поддерживается 15 языков:

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

Мини-спрайт карты

Воспроизведите игровую миниатюру карты (используется на экранах истории забегов и Game Over) в любом веб-проекте. Шесть слоёв PNG, собранных через CSS mask-image, без canvas и WebGL, только тонированные спрайты. Цвета взяты напрямую из декомпилированного кода игры: NTinyCard, CardPoolModel.DeckEntryCardColor.

Предпросмотр

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

Спрайты

Все 10 PNG отдаются с включённым CORS, подставьте базовый URL перед каждым именем файла. Каждый спрайт 128×128, RGBA, белый на прозрачном (предназначен для тонирования через 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

Цвета пула (рубашка карты)

Источник: CardPoolModel.DeckEntryCardColor. Сопоставьте их с полем color, которое возвращает /api/cards.

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

Цвета редкости (баннер)

Источник: NTinyCard.GetBannerColor. Сопоставьте с полем rarity.

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

Минимальный рецепт на HTML + CSS

Имя файла портрета: attack = Карты атаки, power = Карты способностей, skill = всё остальное (навык, статус, проклятие, …)

<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-компонент

Готовая React-версия. Исходник: 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" />

Полные изображения карт

Каждая карта из /api/cards содержит два готовых URL полной карты, отрендеренной игрой (рамка, арт, баннер и текст, ровно как в игре). Карты древних — анимированные webp.

  • image_url_card — Базовая карта. null для единственной карты без рендера (mad_science); там используйте image_url (арт портрета).
  • image_url_card_upg — Улучшенная карта. null, если у карты нет улучшения.
// 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"
}

Локализованные рендеры лежат в подпапке языка, например: cards-full/stable/jpn/bash.webp. Доступны все 15 языков.

Рендеры зачарованных карт

Каждая карта также отрендерена с каждым зачарованием, которое она может законно получить, ровно так, как рисует внутриигровой предпросмотр зачарования (значок, значение и добавленный текст). URL следуют одному шаблону:

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}: идентификаторы в нижнем регистре из /api/enchantments и /api/cards (например, sharp, corrupted, sown).
  • Существуют только допустимые сочетания карты и зачарования (экспорт использует правила применимости самой игры), поэтому недопустимое сочетание даёт 404. Поля card_type / applicable_to в /api/enchantments описывают, какие карты подходят.
  • Для каждого сочетания есть базовый и улучшенный варианты на всех 14 языках с полностью локализованным текстом зачарования.

Экспорт данных

Скачайте все данные игры одним ZIP-архивом. Каждый архив содержит JSON-файлы для каждого типа сущностей (карты, реликвии, монстры, способности и другое).

Интерактивная документация API

Полная документация Swagger/OpenAPI с возможностью попробовать запросы.

Открыть документацию API →

Открытый исходный код

Spire Codex имеет открытый исходный код. Пайплайн извлечения данных, API и фронтенд доступны на GitHub.

Открыть на GitHub →