{"openapi":"3.1.0","info":{"title":"Spire Codex API","description":"Comprehensive API for Slay the Spire 2 game data — cards, characters, relics, monsters, potions, powers, enchantments, encounters, events, epochs, keywords, orbs, afflictions, modifiers, achievements, and more.","version":"1.0.0"},"paths":{"/api/cards":{"get":{"tags":["Cards"],"summary":"Get Cards","operationId":"get_cards_api_cards_get","parameters":[{"name":"color","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by character color (ironclad, silent, defect, necrobinder, regent, colorless)","title":"Color"},"description":"Filter by character color (ironclad, silent, defect, necrobinder, regent, colorless)"},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by card type (Attack, Skill, Power, Status, Curse)","title":"Type"},"description":"Filter by card type (Attack, Skill, Power, Status, Curse)"},{"name":"rarity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by rarity (Basic, Common, Uncommon, Rare, Ancient)","title":"Rarity"},"description":"Filter by rarity (Basic, Common, Uncommon, Rare, Ancient)"},{"name":"keyword","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by keyword (Exhaust, Innate, Ethereal, Retain, Unplayable, Sly, Eternal)","title":"Keyword"},"description":"Filter by keyword (Exhaust, Innate, Ethereal, Retain, Unplayable, Sly, Eternal)"},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by tag (Strike, Defend, Minion, etc.)","title":"Tag"},"description":"Filter by tag (Strike, Defend, Minion, etc.)"},{"name":"spawns","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only cards that create or reference this card id (e.g. SOUL lists every Soul generator)","title":"Spawns"},"description":"Only cards that create or reference this card id (e.g. SOUL lists every Soul generator)"},{"name":"cost","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by cost: energy as 0, 1, 2, 3, 4plus, or x; star cost (Regent) as star1, star2, star3, star4plus, or starx","title":"Cost"},"description":"Filter by cost: energy as 0, 1, 2, 3, 4plus, or x; star cost (Regent) as star1, star2, star3, star4plus, or starx"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Card"},"title":"Response Get Cards Api Cards Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cards/{card_id}":{"get":{"tags":["Cards"],"summary":"Get Card","operationId":"get_card_api_cards__card_id__get","parameters":[{"name":"card_id","in":"path","required":true,"schema":{"type":"string","title":"Card Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Card"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search/semantic":{"get":{"tags":["Search","Search"],"summary":"Semantic Search Route","description":"Meaning-based entity search over Workers AI embeddings. Returns the\nsame item shape as /api/search; empty when the feature is unavailable\n(no vectors built or no Workers AI token).","operationId":"semantic_search_route_api_search_semantic_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":120,"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":8,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Semantic Search Route Api Search Semantic Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search":{"get":{"tags":["Search","Search"],"summary":"Global Search","description":"Search every entity type, reference entry, mechanics page, guide,\nand news article in one pass. Returns up to a few items per category;\nempty categories are omitted.","operationId":"global_search_api_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":80,"title":"Q"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Global Search Api Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/characters":{"get":{"tags":["Characters"],"summary":"Get Characters","operationId":"get_characters_api_characters_get","parameters":[{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Character"},"title":"Response Get Characters Api Characters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/characters/{character_id}":{"get":{"tags":["Characters"],"summary":"Get Character","operationId":"get_character_api_characters__character_id__get","parameters":[{"name":"character_id","in":"path","required":true,"schema":{"type":"string","title":"Character Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Character"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/relics":{"get":{"tags":["Relics"],"summary":"Get Relics","operationId":"get_relics_api_relics_get","parameters":[{"name":"rarity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by rarity (Starter, Common, Uncommon, Rare, Shop, Event, Ancient)","title":"Rarity"},"description":"Filter by rarity (Starter, Common, Uncommon, Rare, Shop, Event, Ancient)"},{"name":"pool","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by character pool (ironclad, silent, defect, necrobinder, regent, shared)","title":"Pool"},"description":"Filter by character pool (ironclad, silent, defect, necrobinder, regent, shared)"},{"name":"ancient","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to one ancient's relic pool (neow, tezcatara, pael, orobas, darv, nonupeipe, tanx, vakuu)","title":"Ancient"},"description":"Filter to one ancient's relic pool (neow, tezcatara, pael, orobas, darv, nonupeipe, tanx, vakuu)"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Relic"},"title":"Response Get Relics Api Relics Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/relics/{relic_id}":{"get":{"tags":["Relics"],"summary":"Get Relic","operationId":"get_relic_api_relics__relic_id__get","parameters":[{"name":"relic_id","in":"path","required":true,"schema":{"type":"string","title":"Relic Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Relic"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/monsters":{"get":{"tags":["Monsters"],"summary":"Get Monsters","operationId":"get_monsters_api_monsters_get","parameters":[{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by type (Normal, Elite, Boss)","title":"Type"},"description":"Filter by type (Normal, Elite, Boss)"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Monster"},"title":"Response Get Monsters Api Monsters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/monsters/{monster_id}":{"get":{"tags":["Monsters"],"summary":"Get Monster","operationId":"get_monster_api_monsters__monster_id__get","parameters":[{"name":"monster_id","in":"path","required":true,"schema":{"type":"string","title":"Monster Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Monster"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/potions":{"get":{"tags":["Potions"],"summary":"Get Potions","operationId":"get_potions_api_potions_get","parameters":[{"name":"rarity","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by rarity","title":"Rarity"},"description":"Filter by rarity"},{"name":"pool","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by character pool","title":"Pool"},"description":"Filter by character pool"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Potion"},"title":"Response Get Potions Api Potions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/potions/{potion_id}":{"get":{"tags":["Potions"],"summary":"Get Potion","operationId":"get_potion_api_potions__potion_id__get","parameters":[{"name":"potion_id","in":"path","required":true,"schema":{"type":"string","title":"Potion Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Potion"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/enchantments":{"get":{"tags":["Enchantments"],"summary":"Get Enchantments","operationId":"get_enchantments_api_enchantments_get","parameters":[{"name":"card_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by card type restriction (Attack, Skill, Power)","title":"Card Type"},"description":"Filter by card type restriction (Attack, Skill, Power)"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Enchantment"},"title":"Response Get Enchantments Api Enchantments Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/enchantments/{enchantment_id}":{"get":{"tags":["Enchantments"],"summary":"Get Enchantment","operationId":"get_enchantment_api_enchantments__enchantment_id__get","parameters":[{"name":"enchantment_id","in":"path","required":true,"schema":{"type":"string","title":"Enchantment Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Enchantment"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/encounters":{"get":{"tags":["Encounters"],"summary":"Get Encounters","operationId":"get_encounters_api_encounters_get","parameters":[{"name":"room_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by room type (Monster, Elite, Boss)","title":"Room Type"},"description":"Filter by room type (Monster, Elite, Boss)"},{"name":"act","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by act name","title":"Act"},"description":"Filter by act name"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Encounter"},"title":"Response Get Encounters Api Encounters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/encounters/{encounter_id}":{"get":{"tags":["Encounters"],"summary":"Get Encounter","operationId":"get_encounter_api_encounters__encounter_id__get","parameters":[{"name":"encounter_id","in":"path","required":true,"schema":{"type":"string","title":"Encounter Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Encounter"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/events":{"get":{"tags":["Events"],"summary":"Get Events","operationId":"get_events_api_events_get","parameters":[{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by type (Event, Ancient, Shared)","title":"Type"},"description":"Filter by type (Event, Ancient, Shared)"},{"name":"act","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by act name","title":"Act"},"description":"Filter by act name"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Event"},"title":"Response Get Events Api Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/events/{event_id}":{"get":{"tags":["Events"],"summary":"Get Event","operationId":"get_event_api_events__event_id__get","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","title":"Event Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/powers":{"get":{"tags":["Powers"],"summary":"Get Powers","operationId":"get_powers_api_powers_get","parameters":[{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by type (Buff/Debuff)","title":"Type"},"description":"Filter by type (Buff/Debuff)"},{"name":"stack_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by stack type (Counter/Single/None)","title":"Stack Type"},"description":"Filter by stack type (Counter/Single/None)"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name or description","title":"Search"},"description":"Search by name or description"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Power"},"title":"Response Get Powers Api Powers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/powers/{power_id}":{"get":{"tags":["Powers"],"summary":"Get Power","operationId":"get_power_api_powers__power_id__get","parameters":[{"name":"power_id","in":"path","required":true,"schema":{"type":"string","title":"Power Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Power"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keywords":{"get":{"tags":["Keywords"],"summary":"Get Keywords","operationId":"get_keywords_api_keywords_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Keyword"},"title":"Response Get Keywords Api Keywords Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/keywords/{keyword_id}":{"get":{"tags":["Keywords"],"summary":"Get Keyword","operationId":"get_keyword_api_keywords__keyword_id__get","parameters":[{"name":"keyword_id","in":"path","required":true,"schema":{"type":"string","title":"Keyword Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Keyword"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/intents":{"get":{"tags":["Intents"],"summary":"Get Intents","operationId":"get_intents_api_intents_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Intent"},"title":"Response Get Intents Api Intents Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/intents/{intent_id}":{"get":{"tags":["Intents"],"summary":"Get Intent","operationId":"get_intent_api_intents__intent_id__get","parameters":[{"name":"intent_id","in":"path","required":true,"schema":{"type":"string","title":"Intent Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Intent"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orbs":{"get":{"tags":["Orbs"],"summary":"Get Orbs","operationId":"get_orbs_api_orbs_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Orb"},"title":"Response Get Orbs Api Orbs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/orbs/{orb_id}":{"get":{"tags":["Orbs"],"summary":"Get Orb","operationId":"get_orb_api_orbs__orb_id__get","parameters":[{"name":"orb_id","in":"path","required":true,"schema":{"type":"string","title":"Orb Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Orb"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/afflictions":{"get":{"tags":["Afflictions"],"summary":"Get Afflictions","operationId":"get_afflictions_api_afflictions_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Affliction"},"title":"Response Get Afflictions Api Afflictions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/afflictions/{affliction_id}":{"get":{"tags":["Afflictions"],"summary":"Get Affliction","operationId":"get_affliction_api_afflictions__affliction_id__get","parameters":[{"name":"affliction_id","in":"path","required":true,"schema":{"type":"string","title":"Affliction Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Affliction"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/modifiers":{"get":{"tags":["Modifiers"],"summary":"Get Modifiers","operationId":"get_modifiers_api_modifiers_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Modifier"},"title":"Response Get Modifiers Api Modifiers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/modifiers/{modifier_id}":{"get":{"tags":["Modifiers"],"summary":"Get Modifier","operationId":"get_modifier_api_modifiers__modifier_id__get","parameters":[{"name":"modifier_id","in":"path","required":true,"schema":{"type":"string","title":"Modifier Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Modifier"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/achievements":{"get":{"tags":["Achievements"],"summary":"Get Achievements","operationId":"get_achievements_api_achievements_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Achievement"},"title":"Response Get Achievements Api Achievements Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/achievements/{achievement_id}":{"get":{"tags":["Achievements"],"summary":"Get Achievement","operationId":"get_achievement_api_achievements__achievement_id__get","parameters":[{"name":"achievement_id","in":"path","required":true,"schema":{"type":"string","title":"Achievement Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Achievement"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/badges":{"get":{"tags":["Badges"],"summary":"Get Badges","operationId":"get_badges_api_badges_get","parameters":[{"name":"tiered","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Tiered"}},{"name":"multiplayer_only","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Multiplayer Only"}},{"name":"requires_win","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Requires Win"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Badge"},"title":"Response Get Badges Api Badges Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/badges/{badge_id}":{"get":{"tags":["Badges"],"summary":"Get Badge","operationId":"get_badge_api_badges__badge_id__get","parameters":[{"name":"badge_id","in":"path","required":true,"schema":{"type":"string","title":"Badge Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Badge"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/epochs":{"get":{"tags":["Epochs"],"summary":"Get Epochs","operationId":"get_epochs_api_epochs_get","parameters":[{"name":"story","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by story ID","title":"Story"},"description":"Filter by story ID"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by title, description, or unlock text","title":"Search"},"description":"Search by title, description, or unlock text"},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Epoch"},"title":"Response Get Epochs Api Epochs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/epochs/{epoch_id}":{"get":{"tags":["Epochs"],"summary":"Get Epoch","operationId":"get_epoch_api_epochs__epoch_id__get","parameters":[{"name":"epoch_id","in":"path","required":true,"schema":{"type":"string","title":"Epoch Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Epoch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stories":{"get":{"tags":["Stories"],"summary":"Get Stories","operationId":"get_stories_api_stories_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Story"},"title":"Response Get Stories Api Stories Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stories/{story_id}":{"get":{"tags":["Stories"],"summary":"Get Story","operationId":"get_story_api_stories__story_id__get","parameters":[{"name":"story_id","in":"path","required":true,"schema":{"type":"string","title":"Story Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Story"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/images/search":{"get":{"tags":["Images","Images"],"summary":"Search Images","description":"Filename substring search across every image category.\n\nUsed by the global search modal so queries like \"doormaker\" surface image\nresults alongside entity pages. Matches every whitespace-separated token in\n`search` against the basename (extension stripped, case-insensitive).\n\nResults prefer the PNG sibling of any asset if one exists on disk — our\nanimated webp exports (monsters, spine renders) can render garbled when\nopened directly, so search results route users to the static PNG instead.\nFalls back to the gallery-preferred extension when no PNG is available.\nCapped at `limit` (max 50).","operationId":"search_images_api_images_search_get","parameters":[{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/images/beta/versions":{"get":{"tags":["Images","Images"],"summary":"Beta Versions","description":"List the beta versions available under static/images/beta/.\n\nUsed by the /images version selector. `latest` is the symlink target.","operationId":"beta_versions_api_images_beta_versions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/images":{"get":{"tags":["Images","Images"],"summary":"List Image Categories","description":"Return all image categories with their contents.\n\nThe gallery listing dedupes `foo.png` + `foo.webp` to a single entry\n(prefers webp) so the UI isn't noisy. The `formats` field still reflects\nevery extension on disk so the download split-button can offer PNG-only\nzips.\n\n`version=v0.106.0` scopes the `beta-*` categories to that ingest;\nomit to use whatever `beta/latest` points at.\n\nWhen `version=main`, the `beta-*` categories are skipped entirely —\nthey'd duplicate the stable categories (Cards, Monsters, etc.) that\nalready render from the same on-disk tree, making the page's total\ncounts misleading.","operationId":"list_image_categories_api_images_get","parameters":[{"name":"version","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/images/{category}/download":{"get":{"tags":["Images","Images"],"summary":"Download Category Zip","description":"Download all images in a category as a zip file.\n\nOptional `?format=` query param filters to a single extension (e.g. `png`,\n`webp`, `gif`). Omit to include every file in the category. For beta\ncategories, `?version=v0.106.0` selects which patch's images to bundle.","operationId":"download_category_zip_api_images__category__download_get","parameters":[{"name":"category","in":"path","required":true,"schema":{"type":"string","title":"Category"}},{"name":"format","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Format"}},{"name":"version","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/changelogs":{"get":{"tags":["Changelogs","Changelogs"],"summary":"List Changelogs","description":"Return all changelogs (summary only, no category details).","operationId":"list_changelogs_api_changelogs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/changelogs/recent-additions":{"get":{"tags":["Changelogs","Changelogs"],"summary":"Recent Additions","description":"Return the most recent entity additions, scanning newest changelogs first.\n\n- entity_type: optional filter (e.g. \"cards\", \"relics\") — if omitted, returns a\n  dict keyed by entity type.\n- limit: max items to return per entity type.\n- max_versions: stop scanning after this many changelogs (safety cap).\n- max_age_days: only surface items from changelogs dated within this many\n  days from today (default 7). Pass 0 to disable the time filter.\n\nEach item is enriched with `version`, `version_tag`, and `version_date` so the\nUI can render a \"Added in vX.Y.Z\" badge.","operationId":"recent_additions_api_changelogs_recent_additions_get","parameters":[{"name":"entity_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":12,"title":"Limit"}},{"name":"max_versions","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Max Versions"}},{"name":"max_age_days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Max Age Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/changelogs/{tag}":{"get":{"tags":["Changelogs","Changelogs"],"summary":"Get Changelog","description":"Return full changelog for a specific tag (e.g. '1.0.3').","operationId":"get_changelog_api_changelogs__tag__get","parameters":[{"name":"tag","in":"path","required":true,"schema":{"type":"string","title":"Tag"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/acts":{"get":{"tags":["Acts"],"summary":"Get Acts","operationId":"get_acts_api_acts_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Act"},"title":"Response Get Acts Api Acts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/acts/{act_id}":{"get":{"tags":["Acts"],"summary":"Get Act","operationId":"get_act_api_acts__act_id__get","parameters":[{"name":"act_id","in":"path","required":true,"schema":{"type":"string","title":"Act Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Act"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ascensions":{"get":{"tags":["Ascensions"],"summary":"Get Ascensions","operationId":"get_ascensions_api_ascensions_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Ascension"},"title":"Response Get Ascensions Api Ascensions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ascensions/{ascension_id}":{"get":{"tags":["Ascensions"],"summary":"Get Ascension","operationId":"get_ascension_api_ascensions__ascension_id__get","parameters":[{"name":"ascension_id","in":"path","required":true,"schema":{"type":"string","title":"Ascension Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ascension"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/names/{entity_type}/{entity_id}":{"get":{"summary":"Get Localized Names","description":"Return {lang_code: display_name} for an entity across all languages.","operationId":"get_localized_names_api_names__entity_type___entity_id__get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}},{"name":"entity_id","in":"path","required":true,"schema":{"type":"string","title":"Entity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Get Localized Names Api Names  Entity Type   Entity Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/exports/runs":{"get":{"tags":["Exports"],"summary":"Export Runs","description":"Bulk export of submitted runs as gzipped JSONL.\n\nEach line is the full raw game JSON as submitted by the client,\nincluding players, map_point_history, acts, deck, relics, and\ncard_choices. Only runs with official characters are included.\n\nRuns are ordered by ``(submitted_at, _id)``. With no params the response\nis the full corpus (unchanged behaviour). To pull it in reliable chunks:\n\n* ``limit=N`` bounds the page to N runs. When more runs follow, the\n  response carries an ``X-Next-Cursor`` header; pass it back as\n  ``cursor=`` to fetch the next page. The ascending order means runs\n  submitted *during* a long bootstrap sort after the cursor, so a\n  forward pager never misses them.\n* ``start`` / ``end`` restrict to a half-open ``[start, end)``\n  submitted_at window (e.g. an incremental \"everything since my last\n  sync\"). Combine with ``limit`` to also bound each page.\n\nConsumer notes:\n\n* Terminate a paged walk on the **absence of ``X-Next-Cursor``**, never on\n  \"fewer lines than ``limit``\": a page is ``limit`` *runs*, but the streamed\n  line count can differ (missing/unreadable run files are skipped, and a\n  multiplayer run emits one raw line per player).\n* The cursor does **not** embed the window, so keep ``start`` / ``end``\n  constant across a paged sequence.\n* ``start`` / ``end`` filter on ``submitted_at``, so they exclude legacy\n  runs that have no ``submitted_at``. Omit both to receive the whole corpus.\n* ``X-Next-Cursor`` is in the CORS ``Access-Control-Expose-Headers`` list,\n  so browser clients can read it too; non-browser clients never needed it.","operationId":"export_runs_api_exports_runs_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":50000,"minimum":1},{"type":"null"}],"description":"Max runs in this page. Omit for the full (unbounded) export.","title":"Limit"},"description":"Max runs in this page. Omit for the full (unbounded) export."},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Inclusive lower bound on submitted_at (ISO-8601).","title":"Start"},"description":"Inclusive lower bound on submitted_at (ISO-8601)."},{"name":"end","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Exclusive upper bound on submitted_at (ISO-8601).","title":"End"},"description":"Exclusive upper bound on submitted_at (ISO-8601)."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque keyset token from a prior page's X-Next-Cursor header.","title":"Cursor"},"description":"Opaque keyset token from a prior page's X-Next-Cursor header."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/exports/{lang}":{"get":{"tags":["Exports"],"summary":"Export Language","operationId":"export_language_api_exports__lang__get","parameters":[{"name":"lang","in":"path","required":true,"schema":{"type":"string","title":"Lang"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/history/{entity_type}/{entity_id}":{"get":{"tags":["Entity History","Entity History"],"summary":"Get Entity History","description":"Return version history entries for a specific entity across all changelogs.\n\nScans every changelog's categories for added/removed/changed entries matching\nthe given entity_type (e.g. 'cards') and entity_id (e.g. 'BASH'). Match is\ncase-insensitive on both — entity_type comes lowercased from the URL while\nchangelog ids are upper-snake (e.g. 'DOORMAKER').","operationId":"get_entity_history_api_history__entity_type___entity_id__get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}},{"name":"entity_id","in":"path","required":true,"schema":{"type":"string","title":"Entity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ancient-pools":{"get":{"tags":["Ancient Pools","Ancient Pools"],"summary":"List Ancient Pools","description":"Return all ancient relic pools.","operationId":"list_ancient_pools_api_ancient_pools_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/ancient-pools/{ancient_id}":{"get":{"tags":["Ancient Pools","Ancient Pools"],"summary":"Get Ancient Pool","description":"Return relic pools for a specific ancient.","operationId":"get_ancient_pool_api_ancient_pools__ancient_id__get","parameters":[{"name":"ancient_id","in":"path","required":true,"schema":{"type":"string","title":"Ancient Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs":{"post":{"tags":["Runs","Runs"],"summary":"Submit Run Endpoint","description":"Submit a run for community stats. Paste the .run file JSON content. Optional ?username= param.\n\nPass ?steam_id=<SteamID64> (the overlay / Compendium send the signed-in\nplayer's Steam ID) and/or ?discord_id=<id> to tag the run with its owner\nso it links to their account on sign-in without a manual claim.\n\nRate limit: 3000/hour (~50/min sustained, with room for burst). The\nearlier 600/hour ceiling was sized for \"a few hundred backlog runs\non first install\" but silently capped users with larger histories\n— a Discord report of someone with 1000+ saved runs would have\ndropped 400 of them at 600/hour. Each submission is ~10ms backend\nwork (Mongo insert + JSON file write + metrics bump) and duplicate\ndetection short-circuits at ~3ms via the run_hash UNIQUE\nconstraint, so actual write load is bounded by *distinct* runs per\nuploader, not raw submission count. Easy to lower again if scraper\nabuse shows up in\n`spire_codex_api_errors_total{status_code=\"429\"}` against this\nendpoint.","operationId":"submit_run_endpoint_api_runs_post","parameters":[{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}},{"name":"steam_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Steam Id"}},{"name":"discord_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Discord Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/claim":{"post":{"tags":["Runs","Runs"],"summary":"Claim Runs Endpoint","description":"Attach a username to previously-submitted runs by hash.\n\nBody: `{ \"username\": \"name\", \"hashes\": [\"abc123...\", ...] }`\n\nOnly rows with a NULL/empty username are updated — existing\nclaims are never overwritten. Intended for the Spire Compendium\ndesktop app: after Steam sign-in, the client computes hashes\nfor every local run and claims the ones it already uploaded\nanonymously.","operationId":"claim_runs_endpoint_api_runs_claim_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/runs/list":{"get":{"tags":["Runs","Runs"],"summary":"List Runs","description":"List submitted runs with optional filters, sorting, and pagination.\n\n`winrate_min` / `winrate_max` filter runs by their submitter's overall\nwin rate percentage; only users with at least 5 submitted runs qualify,\nand anonymous runs never match.\n\n`shop` matches runs that bought the item (card, relic, or potion) at a\nshop; comma-separated ids AND together like `card`/`relic`. Mongo only —\nthe dev SQLite fallback ignores it, like the card/relic filters.","operationId":"list_runs_api_runs_list_get","parameters":[{"name":"character","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"}},{"name":"win","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Win"}},{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}},{"name":"winrate_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100,"minimum":0},{"type":"null"}],"title":"Winrate Min"}},{"name":"winrate_max","in":"query","required":false,"schema":{"anyOf":[{"type":"number","maximum":100,"minimum":0},{"type":"null"}],"title":"Winrate Max"}},{"name":"seed","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seed"}},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort"}},{"name":"build_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Build Id"}},{"name":"players","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Players"}},{"name":"game_mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Game Mode"}},{"name":"ascension","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ascension"}},{"name":"ascension_min","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ascension Min"}},{"name":"ascension_max","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ascension Max"}},{"name":"build_ids","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Build Ids"}},{"name":"card","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Card"}},{"name":"relic","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relic"}},{"name":"shop","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop"}},{"name":"today","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Today"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/leaderboard":{"get":{"tags":["Runs","Runs"],"summary":"Get Leaderboard","description":"Leaderboard for winning runs.\n\nCategories: `fastest`, `highest_ascension`.\n`ascension_min`: only runs at this ascension or higher (e.g. 10 for the\nA10 fastest-wins board); without it the board spans every ascension, so a\nlow-ascension speedrun can outrank an A10 win.\n`players`: `single` (player_count == 1) or `multi` (player_count > 1).\n`game_mode`: `standard`, `daily`, or `custom`. Custom runs ride on\ncustom seeds so their times aren't comparable to the standard\nladder; the frontend defaults to `standard` and exposes mode\nexplicitly so users can opt into the other pools.\nSingle-player and multiplayer runs aren't directly comparable, so the\nfrontend reads them as disjoint pools.","operationId":"get_leaderboard_api_runs_leaderboard_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"type":"string","default":"fastest","title":"Category"}},{"name":"character","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"}},{"name":"players","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Players"}},{"name":"game_mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Game Mode"}},{"name":"today","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Today"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"ascension_min","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ascension Min"}},{"name":"winrate_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Winrate Min"}},{"name":"build_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Build Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/leaderboard/seed-rank":{"get":{"tags":["Runs","Runs"],"summary":"Get Seed Rank","description":"Seed + global standing for the in-game mod (F9 panel, post-run card).\n\nPool = completed runs sharing the seed; ranking = winning runs by run_time,\ncross-character. `seed_rank`/`global_rank`/`percentile` are null when the\ncaller has no winning run in that pool (the mod hides those lines).","operationId":"get_seed_rank_api_runs_leaderboard_seed_rank_get","parameters":[{"name":"seed","in":"query","required":true,"schema":{"type":"string","title":"Seed"}},{"name":"steam_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Steam Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/leaderboard/rank/{run_hash}":{"get":{"tags":["Runs","Runs"],"summary":"Get Run Rank","description":"Rank of a single winning run within its character's leaderboard.\n\nOrdering matches `/leaderboard`:\n- `fastest`: `run_time ASC` — rank = (wins by char with run_time < this) + 1\n- `highest_ascension`: `ascension DESC, run_time ASC` — rank = (wins by char\n  with higher ascension, or same ascension and faster) + 1\n\nReturns `{\"rank\": None}` for losses, missing hashes, or abandoned runs so\nthe caller can render \"DNF\" / \"—\" uniformly.","operationId":"get_run_rank_api_runs_leaderboard_rank__run_hash__get","parameters":[{"name":"run_hash","in":"path","required":true,"schema":{"type":"string","title":"Run Hash"}},{"name":"category","in":"query","required":false,"schema":{"type":"string","default":"fastest","title":"Category"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/encounter-stats":{"get":{"tags":["Runs","Runs"],"summary":"Get Encounter Stats Endpoint","description":"Per-encounter combat stats over submitted runs.\n\nServed from the precomputed run-entity-stats snapshot (built in the\nsame all-runs walk as the entity / community / charts stats), so this\nis an O(rows) slice rather than a per-request walk over every run's\n`map_point_history`. Counts official runs only — Ascension 11+ and\nnon-official-character (modded) runs are excluded at snapshot build\ntime, matching the rest of the stats.\n\nQuery params:\n  * `act` — comma-separated list of acts to include (e.g. `1,2`).\n    Omit for all.\n  * `room_type` — comma-separated list of room types\n    (`monster,elite,boss`). Omit for all.\n  * `multiplayer` — `only` returns multiplayer-only runs,\n    `exclude` removes multiplayer runs, omit for both.\n  * `page` (default 1) + `limit` (default 50, max 200) — pagination\n    applied after grouping, sorted by sample size descending.\n  * `bracket` — content bracket: `a10`, `wr30`, `wr50`, `wr75`\n    (A10-gated win-rate tiers). Omit for all runs.\n\nEach row contains the encounter's total appearances, fatal count,\navg damage taken, avg turns, plus a `characters` array with the\nsame fields scoped per character. Returns `{encounters, page,\nlimit, total, has_next}`. Served from the in-memory snapshot, which\nis built on both the Mongo and SQLite paths.","operationId":"get_encounter_stats_endpoint_api_runs_encounter_stats_get","parameters":[{"name":"act","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Act"}},{"name":"room_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Room Type"}},{"name":"multiplayer","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Multiplayer"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"bracket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bracket"}},{"name":"build_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Build Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/versions":{"get":{"tags":["Runs","Runs"],"summary":"Get Run Versions","description":"Return distinct build_id values from submitted runs.\n\n`stat_versions` is the subset (newest first) the stats snapshot carries a\nper-version encounter slice for — the options the stats-page version\ndropdown should offer, since only these have version-filtered data.","operationId":"get_run_versions_api_runs_versions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/runs/shared/{run_hash}":{"get":{"tags":["Runs","Runs"],"summary":"Get Shared Run","description":"Retrieve a shared run by its hash, merged with DB-side username.\n\nThe on-disk run JSON is the immutable client-submitted blob — it does\nnot contain the submitter's username, since users may attach a name\nAFTER submitting via /api/runs/claim. The username lives in the\nSQLite runs row. Without merging, /shared dropped usernames entirely\neven though /api/runs/list happily reported them.","operationId":"get_shared_run_api_runs_shared__run_hash__get","parameters":[{"name":"run_hash","in":"path","required":true,"schema":{"type":"string","title":"Run Hash"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/stats/{entity_type}/{entity_id}":{"get":{"tags":["Runs","Runs"],"summary":"Get Entity Run Stats","operationId":"get_entity_run_stats_api_runs_stats__entity_type___entity_id__get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}},{"name":"entity_id","in":"path","required":true,"schema":{"type":"string","title":"Entity Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/stats/{entity_type}/{entity_id}/history":{"get":{"tags":["Runs","Runs"],"summary":"Get Entity Metric History Endpoint","description":"Daily Codex Score + Elo history for one entity, for the trend charts.\nEmpty until the archive accumulates (it only grows going forward).","operationId":"get_entity_metric_history_endpoint_api_runs_stats__entity_type___entity_id__history_get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}},{"name":"entity_id","in":"path","required":true,"schema":{"type":"string","title":"Entity Id"}},{"name":"bracket","in":"query","required":false,"schema":{"type":"string","default":"all","title":"Bracket"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/scores/{entity_type}":{"get":{"tags":["Runs","Runs"],"summary":"Get Entity Scores","description":"All Codex Scores for one entity type, keyed by ID.\n\nEach entry carries the 0-100 Codex Score plus picks/wins/win_rate, and\nfor cards the Codex Elo (null for entities without one). Cards that are\nnever a reward pick (curses, statuses, events, tokens, starters) are\nexcluded. With `act` set (relics only), stats cover only pickups made\nduring that act, graded against that act's baseline. Used by list pages\nto render the score column / sort by tier without N round-trips to\n/stats/{type}/{id}. Cached at the same TTL as the per-entity stats since\nboth derive from the same walk.\n\n`character` (e.g. NECROBINDER) switches each entry to that character's\nslice when its sample is big enough, falling back to global otherwise;\nentries then carry `scope: \"character\" | \"global\"`. Used by the in-game\nmod for deck-context scoring. Without it the shape is unchanged.","operationId":"get_entity_scores_api_runs_scores__entity_type__get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}},{"name":"character","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"}},{"name":"act","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":3,"minimum":1},{"type":"null"}],"description":"Relics only: restrict to pickups made during this act (3 includes later acts). Scores are graded against a per-act baseline so survivorship into later acts doesn't inflate them.","title":"Act"},"description":"Relics only: restrict to pickups made during this act (3 includes later acts). Scores are graded against a per-act baseline so survivorship into later acts doesn't inflate them."},{"name":"bracket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Content bracket: grade scores within one run bracket instead of all runs. a10 = Ascension 10; wr30/wr50/wr75 = A10 runs from players above that overall win rate; also a game version (v0.108.0) or a key:version composite (a10:v0.108.0). Does not combine with act or character.","title":"Bracket"},"description":"Content bracket: grade scores within one run bracket instead of all runs. a10 = Ascension 10; wr30/wr50/wr75 = A10 runs from players above that overall win rate; also a game version (v0.108.0) or a key:version composite (a10:v0.108.0). Does not combine with act or character."},{"name":"stat_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Alias for bracket using the in-game mod's bracket names: a10, a10_wr30, a10_wr50, a10_wr75 (map to a10/wr30/wr50/wr75). 'all' is the default and need not be sent. Takes precedence over bracket.","title":"Stat Filter"},"description":"Alias for bracket using the in-game mod's bracket names: a10, a10_wr30, a10_wr50, a10_wr75 (map to a10/wr30/wr50/wr75). 'all' is the default and need not be sent. Takes precedence over bracket."},{"name":"cohort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Deprecated alias for `bracket` (the param was renamed).","title":"Cohort"},"description":"Deprecated alias for `bracket` (the param was renamed)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/snapshot-status":{"get":{"tags":["Runs","Runs"],"summary":"Runs Snapshot Status","description":"Whether the stats snapshot is loaded, rebuilding after a deploy, or\nserving a previous version while the current one builds. Lets the UI\nshow \"stats are rebuilding\" instead of rendering empty charts as if the\ndata were gone.","operationId":"runs_snapshot_status_api_runs_snapshot_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/runs/pulse":{"get":{"tags":["Runs","Runs"],"summary":"Runs Pulse","description":"Live community totals: the snapshot baseline plus the hot overlay's\ncounters, which update within milliseconds of each accepted upload.\n5s shared cache so the edge absorbs all polling.","operationId":"runs_pulse_api_runs_pulse_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/runs/community-stats":{"get":{"tags":["Runs","Runs"],"summary":"Community Stats","description":"Community / fun stats for the /community-stats page: per-event player\ndecision breakdowns, deadliest encounters/events, headline totals by\nascension and character, and a few records and quirks. Official game\ncontent only (modded entities are filtered out). Built in the same walk\nas the Codex Score cache, so this is an in-memory read.\n\n`bracket` slices to a content bracket (`a10`, `wr30`, `wr50`, `wr75`);\nomit for all runs.","operationId":"community_stats_api_runs_community_stats_get","parameters":[{"name":"bracket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bracket"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/me/picks":{"get":{"tags":["Runs","Runs"],"summary":"My Picks","description":"The signed-in player's own pick rates across decision surfaces (card\nrewards + ancient 3-relic offers for now). Scoped to the JWT's verified\nsteam_id; never accepts an arbitrary steam_id param (self-only).","operationId":"my_picks_api_runs_me_picks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/runs/metrics/{entity_type}":{"get":{"tags":["Runs","Runs"],"summary":"Get Entity Metrics","description":"Dense metrics table for one entity type, powers /leaderboards/metrics.\n\nEach row carries the win-outcome metrics (Codex Score, Win%) AND the\nrevealed-preference metrics (Codex Elo, Pick%, per-act pick splits) plus\nraw counts. Served from the same pre-built snapshot as /scores, so it's\none in-memory pass with no per-request aggregation; the client sorts\nand filters the whole table locally. Cards carry Elo/Pick%; relics and\npotions only the win-outcome columns (rewards don't offer them this way).\n\n`bracket` slices to a pre-built run bracket: `all` (default), `solo`,\n`2p`, `3p`, `4p`, `a10` (ascension 10), `daily`, `custom`, plus the\nwin-rate skill tiers `wr30`/`wr50`/`wr75`. Every bracket is materialized\nin the same snapshot, so this stays a single cached read. `cohort` is a\ndeprecated alias for `bracket` (the param was renamed).\n\n`character` (e.g. IRONCLAD) combines with any bracket, including the\nplayer x skill composites: `?bracket=solo:a10&character=IRONCLAD` is\nIronclad's solo A10 table. Character rows carry Score and Win% only.","operationId":"get_entity_metrics_api_runs_metrics__entity_type__get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}},{"name":"bracket","in":"query","required":false,"schema":{"type":"string","default":"all","title":"Bracket"}},{"name":"character","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"}},{"name":"cohort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cohort"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/top/{entity_type}/{character}":{"get":{"tags":["Runs","Runs"],"summary":"Get Top For Character","description":"Most-picked entities of a type for one character, ranked by picks.\n\nPowers the \"Top 5 picked\" sections on character pages. Returns a\nlist of {entity_id, picks, wins, win_rate, score}; empty while the\nsnapshot is cold or the character has no runs yet.","operationId":"get_top_for_character_api_runs_top__entity_type___character__get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}},{"name":"character","in":"path","required":true,"schema":{"type":"string","title":"Character"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":5,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/runs/stats":{"get":{"tags":["Runs","Runs"],"summary":"Get Community Stats","description":"Get aggregated run stats. Community-wide by default; pass\n`username` to narrow to a single uploader.\n\nRead path:\n  0. Redis (60s TTL, cluster-wide).\n  1. Try the materialized stats_summary collection (sub-ms).\n  2. If the filter combo isn't in the hot list / hasn't been\n     materialized yet, fall through to a process-local TTL cache.\n  3. On cache miss, run the live aggregation (slow, ~5-10s).","operationId":"get_community_stats_api_runs_stats_get","parameters":[{"name":"character","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"}},{"name":"win","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Win"}},{"name":"ascension","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ascension"}},{"name":"game_mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Game Mode"}},{"name":"players","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Players"}},{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pairings/{item_type}/{item_id}":{"get":{"tags":["Pairings"],"summary":"Get Item Pairings","description":"Which cards / relics / potions show up in the same runs as this item.\n\nEach partner carries `co` (co-occurrence count), both confidence directions\n— `conf` (of the runs with THIS item, the fraction that also run the partner)\nand `conf_rev` (the reverse, of the partner's runs the fraction that also run\nthis item) — `npmi` (symmetric synergy, >0 = played together more than\nchance), and `winrate` (the pair's win rate). Cards/relics are ranked by\nNPMI; potions are ranked by frequency and are \"commonly seen with\", not a\nsynergy claim. Returns an empty `partners` map until the build job has run.","operationId":"get_item_pairings_api_pairings__item_type___item_id__get","parameters":[{"name":"item_type","in":"path","required":true,"schema":{"type":"string","title":"Item Type"}},{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","default":"eng","title":"Lang"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-recs/{item_type}/{item_id}":{"get":{"tags":["Draft"],"summary":"Get Recs","description":"Given a card/relic you already have, the cards players most often draft\nwhen offered them, ranked by lift over each card's baseline take-rate. Each\nentry carries `pref` (take-rate given this context), `pref_base` (the card's\noverall take-rate), `lift`, `offers` (sample size), and `winrate`. Empty\n`recommends` until the build job has run.","operationId":"get_recs_api_draft_recs__item_type___item_id__get","parameters":[{"name":"item_type","in":"path","required":true,"schema":{"type":"string","title":"Item Type"}},{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","default":"eng","title":"Lang"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-advice":{"post":{"tags":["Draft"],"summary":"Draft Advice","description":"Rank the offered cards for the current deck. Each offered card starts at\nits baseline take-rate and is nudged by the lift of every held item that\nlists it (per-term clamped, naive-Bayes-style), so the result reflects what\nplayers who reached this state actually pick. Returns ranked cards with a\nscore, the baseline, and the held items driving each one (`reasons`).","operationId":"draft_advice_api_draft_advice_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftAdviceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/charts/meta":{"get":{"tags":["Charts"],"summary":"Charts Meta","description":"Everything the explorer UI needs to draw its controls, including the\nevent list (events actually present in the data) for the outcome chart.","operationId":"charts_meta_api_charts_meta_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/charts/{chart_key}":{"get":{"tags":["Charts"],"summary":"Get Chart","description":"One pre-aggregated chart. See /api/charts/meta for the available\ncharts, their filters, splits, and the run stats usable for stat/x/y.","operationId":"get_chart_api_charts__chart_key__get","parameters":[{"name":"chart_key","in":"path","required":true,"schema":{"type":"string","title":"Chart Key"}},{"name":"players","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4,"minimum":1},{"type":"null"}],"description":"Player count filter","title":"Players"},"description":"Player count filter"},{"name":"ascension","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":10,"minimum":0},{"type":"null"}],"description":"Exact ascension (A10 is the cap)","title":"Ascension"},"description":"Exact ascension (A10 is the cap)"},{"name":"game_mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"standard | daily | custom (omit for all)","title":"Game Mode"},"description":"standard | daily | custom (omit for all)"},{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"description":"One submitter's runs","title":"Username"},"description":"One submitter's runs"},{"name":"split","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Series split: character | players | outcome | ascension","title":"Split"},"description":"Series split: character | players | outcome | ascension"},{"name":"stat","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Run stat for stat-driven charts","title":"Stat"},"description":"Run stat for stat-driven charts"},{"name":"x","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"X stat for the scatter","title":"X"},"description":"X stat for the scatter"},{"name":"y","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Y stat for the scatter","title":"Y"},"description":"Y stat for the scatter"},{"name":"encounter","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"Encounter id","title":"Encounter"},"description":"Encounter id"},{"name":"event","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"Event id","title":"Event"},"description":"Event id"},{"name":"etype","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"cards | relics | potions","title":"Etype"},"description":"cards | relics | potions"},{"name":"entity","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"description":"Entity id","title":"Entity"},"description":"Entity id"},{"name":"bracket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Content bracket: a10 | wr30 | wr50 | wr75","title":"Bracket"},"description":"Content bracket: a10 | wr30 | wr50 | wr75"},{"name":"build_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"description":"Game version (e.g. v0.107.1); combines with every other filter","title":"Build Id"},"description":"Game version (e.g. v0.107.1); combines with every other filter"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/beta/diff":{"get":{"tags":["Beta"],"summary":"Beta Diff","description":"What the current beta adds, changes, and removes, per entity type.\n\nShape: {beta_version, types: {cards: {added: [ids], changed: {id:\n[fields]}, removed: [ids]}, ...}}. Comparison runs on English catalogs\nwith presentation-only fields excluded. This is the single source for\nevery BETA badge and changed-in-beta cross-link on the site.","operationId":"beta_diff_api_beta_diff_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/beta/version":{"get":{"tags":["Beta"],"summary":"Beta Version","description":"The current beta version (from the data-beta latest pointer).","operationId":"beta_version_api_beta_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/rate-limits":{"get":{"tags":["API Keys"],"summary":"Rate Limits Info","description":"The public rate-limit tiers. Browse = un-keyed traffic (per IP); keyed\ntiers apply per ``X-API-Key``. All caps count per endpoint. Endpoint clamps\nand the kill switch are operator details and not exposed here.","operationId":"rate_limits_info_api_rate_limits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/glossary":{"get":{"tags":["Glossary"],"summary":"Get Glossary","operationId":"get_glossary_api_glossary_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GlossaryTerm"},"title":"Response Get Glossary Api Glossary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/glossary/{term_id}":{"get":{"tags":["Glossary"],"summary":"Get Glossary Term","operationId":"get_glossary_term_api_glossary__term_id__get","parameters":[{"name":"term_id","in":"path","required":true,"schema":{"type":"string","title":"Term Id"}},{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GlossaryTerm"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/guides":{"get":{"tags":["Guides"],"summary":"Get Guides","operationId":"get_guides_api_guides_get","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"}},{"name":"difficulty","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Difficulty"}},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GuideSummary"},"title":"Response Get Guides Api Guides Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Guides"],"summary":"Submit Guide","operationId":"submit_guide_api_guides_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuideSubmission"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/guides/{slug}":{"get":{"tags":["Guides"],"summary":"Get Guide","operationId":"get_guide_api_guides__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Guide"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/versions":{"get":{"tags":["Versions"],"summary":"List Versions","description":"Return available data versions (e.g. v0.102.0, v0.103.0).","operationId":"list_versions_api_versions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/unlocks":{"get":{"tags":["Unlocks"],"summary":"Get Unlocks","description":"Return all unlockable entities grouped by type, with epoch context.","operationId":"get_unlocks_api_unlocks_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/news":{"get":{"tags":["News"],"summary":"List News","description":"List archived Steam news entries, newest first.\n\nFilters:\n  - `feed_type`: 1 = Steam community announcement, 0 = external (PCGamesN, etc.)\n  - `feedname`: exact feed name (e.g. `steam_community_announcements`)\n  - `tag`: matches if the tag list includes this string (e.g. `patchnotes`)\n  - `since`: Unix epoch seconds — only return entries with `date >= since`\n  - `search`: case-insensitive substring match on the title\n  - `limit` / `offset`: paginate (max limit 200)","operationId":"list_news_api_news_get","parameters":[{"name":"feed_type","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Feed Type"}},{"name":"feedname","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Feedname"}},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Since"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List News Api News Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/news/{gid}":{"get":{"tags":["News"],"summary":"Get News Item","description":"Return a single archived news entry by Steam `gid`.\n\nReturns the full body including raw `contents` (Steam's HTML/BBCode\nblob — clients are responsible for sanitization at render time).","operationId":"get_news_item_api_news__gid__get","parameters":[{"name":"gid","in":"path","required":true,"schema":{"type":"string","title":"Gid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get News Item Api News  Gid  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/merchant/config":{"get":{"tags":["Merchant","Merchant"],"summary":"Get Merchant Config","description":"Return the parsed merchant pricing config — card / potion / relic\ncost tiers with min/max ranges, removal formula, and Fake-Merchant\nflat price. 404 if the file isn't present (parser hasn't run).","operationId":"get_merchant_config_api_merchant_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Merchant Config Api Merchant Config Get"}}}}}}},"/api/mechanics/constants":{"get":{"tags":["Mechanics","Mechanics"],"summary":"Get Mechanics Constants","description":"Return parsed mechanics constants — card-rarity / potion / unknown\nroom probabilities, encounter gold ranges, ascension levels, combat\nmultipliers, and AscensionHelper tuning numbers. 404 when the file\nisn't present (parser hasn't run).","operationId":"get_mechanics_constants_api_mechanics_constants_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Mechanics Constants Api Mechanics Constants Get"}}}}}}},"/api/mechanics/sections":{"get":{"tags":["Mechanics","Mechanics"],"summary":"List Mechanic Sections","description":"Index of all mechanics pages — `{slug, title, description, category, order}`.\n\nSorted by frontmatter `order` then slug; the overlay can group on\n`category` (\"mechanics\" | \"secrets\") to mirror the website's split.","operationId":"list_mechanic_sections_api_mechanics_sections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Mechanic Sections Api Mechanics Sections Get"}}}}}}},"/api/mechanics/sections/{slug}":{"get":{"tags":["Mechanics","Mechanics"],"summary":"Get Mechanic Section","description":"One mechanics page as markdown.\n\n`body_markdown` has all `{{constants...}}` and `{{table:...}}` tokens\nalready resolved, so the overlay only needs a markdown renderer to\ndisplay it — no need to fan out to `/api/characters` or\n`/api/monsters` separately.","operationId":"get_mechanic_section_api_mechanics_sections__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Mechanic Section Api Mechanics Sections  Slug  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tierlists":{"get":{"tags":["Tier Lists"],"summary":"List My Tierlists","description":"All tier lists owned by the signed-in user, newest first.","operationId":"list_my_tierlists_api_tierlists_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["Tier Lists"],"summary":"Create Tierlist","description":"Save a new tier list to the signed-in user's account.","operationId":"create_tierlist_api_tierlists_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TierListCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tierlists/shared/{share_id}":{"get":{"tags":["Tier Lists"],"summary":"Get Shared Tierlist","description":"Public read-only view by share handle. No auth required.","operationId":"get_shared_tierlist_api_tierlists_shared__share_id__get","parameters":[{"name":"share_id","in":"path","required":true,"schema":{"type":"string","title":"Share Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tierlists/{tierlist_id}":{"get":{"tags":["Tier Lists"],"summary":"Get My Tierlist","description":"Owner-scoped fetch for the editor.","operationId":"get_my_tierlist_api_tierlists__tierlist_id__get","parameters":[{"name":"tierlist_id","in":"path","required":true,"schema":{"type":"string","title":"Tierlist Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Tier Lists"],"summary":"Update My Tierlist","operationId":"update_my_tierlist_api_tierlists__tierlist_id__patch","parameters":[{"name":"tierlist_id","in":"path","required":true,"schema":{"type":"string","title":"Tierlist Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TierListUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Tier Lists"],"summary":"Delete My Tierlist","operationId":"delete_my_tierlist_api_tierlists__tierlist_id__delete","parameters":[{"name":"tierlist_id","in":"path","required":true,"schema":{"type":"string","title":"Tierlist Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mod/latest":{"get":{"tags":["Mod"],"summary":"Latest Mod Version","description":"Latest published mod build + the newest game version it was verified against.\n\nThe in-game mod compares these against its own version and the running game build,\nand shows an \"update available\" or \"untested game build\" line in its overlay. Values\ncome from env vars so they can be bumped after a game patch without a code change\n(restart the backend to pick them up).","operationId":"latest_mod_version_api_mod_latest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/presence":{"post":{"tags":["Presence"],"summary":"Post Presence","operationId":"post_presence_api_presence_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/presence/active":{"get":{"tags":["Presence"],"summary":"Get Active","operationId":"get_active_api_presence_active_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/presence/{steam_id}":{"get":{"tags":["Presence"],"summary":"Get Player","operationId":"get_player_api_presence__steam_id__get","parameters":[{"name":"steam_id","in":"path","required":true,"schema":{"type":"string","title":"Steam Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/announcements":{"get":{"tags":["Announcements"],"summary":"Active Announcements","description":"The active banner messages, newest first. `message` may contain\ninline [label](/href) links the frontend renders as real links.","operationId":"active_announcements_api_announcements_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/languages":{"get":{"tags":["Languages"],"summary":"Languages","description":"Get list of available languages.","operationId":"languages_api_languages_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/translations":{"get":{"tags":["Languages"],"summary":"Translations","description":"Get translation maps for the given language (section titles, descriptions, character names, filter labels).","operationId":"translations_api_translations_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stats":{"get":{"tags":["Stats"],"summary":"Stats","description":"Get total counts of all game entities.","operationId":"stats_api_stats_get","parameters":[{"name":"lang","in":"query","required":false,"schema":{"type":"string","description":"Language code. One of the 15 supported codes; unknown values fall back to English.","enum":["deu","eng","esp","fra","ita","jpn","kor","pol","ptb","rus","spa","tha","tur","zhs","zht"],"default":"eng","title":"Lang"},"description":"Language code. One of the 15 supported codes; unknown values fall back to English."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["Health"],"summary":"Health","description":"Health check — verifies the API is running and data is accessible.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"tags":["Root"],"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"Achievement":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"character":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"},"threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Threshold"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"}},"type":"object","required":["id","name","description"],"title":"Achievement"},"Act":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"num_rooms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Num Rooms"},"bosses":{"items":{"type":"string"},"type":"array","title":"Bosses"},"ancients":{"items":{"type":"string"},"type":"array","title":"Ancients"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"encounters":{"items":{"type":"string"},"type":"array","title":"Encounters"}},"type":"object","required":["id","name","bosses","ancients","events","encounters"],"title":"Act"},"Affliction":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"extra_card_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extra Card Text"},"is_stackable":{"type":"boolean","title":"Is Stackable","default":false}},"type":"object","required":["id","name","description"],"title":"Affliction"},"Ascension":{"properties":{"id":{"type":"string","title":"Id"},"level":{"type":"integer","title":"Level"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"}},"type":"object","required":["id","level","name","description"],"title":"Ascension"},"AttackPattern":{"properties":{"type":{"type":"string","title":"Type"},"initial_move":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Initial Move"},"states":{"items":{"$ref":"#/components/schemas/AttackPatternState"},"type":"array","title":"States"},"description":{"type":"string","title":"Description"}},"type":"object","required":["type","states","description"],"title":"AttackPattern"},"AttackPatternBranch":{"properties":{"move_id":{"type":"string","title":"Move Id"},"weight":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Weight"},"repeat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repeat"},"max_times":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Times"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"}},"type":"object","required":["move_id"],"title":"AttackPatternBranch"},"AttackPatternState":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"move_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Move Id"},"must_perform_once":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Must Perform Once"},"next":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next"},"branches":{"anyOf":[{"items":{"$ref":"#/components/schemas/AttackPatternBranch"},"type":"array"},{"type":"null"}],"title":"Branches"}},"type":"object","required":["id","type"],"title":"AttackPatternState"},"Badge":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"tiered":{"type":"boolean","title":"Tiered"},"tiers":{"items":{"$ref":"#/components/schemas/BadgeTier"},"type":"array","title":"Tiers"},"requires_win":{"type":"boolean","title":"Requires Win"},"multiplayer_only":{"type":"boolean","title":"Multiplayer Only"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["id","name","description","tiered","tiers","requires_win","multiplayer_only"],"title":"Badge"},"BadgeTier":{"properties":{"rarity":{"type":"string","title":"Rarity"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"}},"type":"object","required":["rarity","title","description"],"title":"BadgeTier"},"Card":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"description_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description Raw"},"cost":{"type":"integer","title":"Cost"},"is_x_cost":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is X Cost"},"is_x_star_cost":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is X Star Cost"},"star_cost":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Star Cost"},"type":{"type":"string","title":"Type"},"type_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type Key"},"rarity":{"type":"string","title":"Rarity"},"rarity_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rarity Key"},"target":{"type":"string","title":"Target"},"color":{"type":"string","title":"Color"},"damage":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Damage"},"block":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Block"},"hit_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hit Count"},"powers_applied":{"anyOf":[{"items":{"$ref":"#/components/schemas/PowerApplied"},"type":"array"},{"type":"null"}],"title":"Powers Applied"},"cards_draw":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cards Draw"},"energy_gain":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Energy Gain"},"hp_loss":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hp Loss"},"keywords":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Keywords"},"keywords_key":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Keywords Key"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"spawns_cards":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Spawns Cards"},"vars":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"number"}]},"type":"object"},{"type":"null"}],"title":"Vars"},"upgrade":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Upgrade"},"upgrade_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Upgrade Description"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"beta_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Beta Image Url"},"type_variants":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/CardTypeVariant"},"type":"object"},{"type":"null"}],"title":"Type Variants"},"can_be_generated_in_combat":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Can Be Generated In Combat"},"compendium_order":{"type":"integer","title":"Compendium Order","default":0},"sources":{"anyOf":[{"items":{"$ref":"#/components/schemas/CardSource"},"type":"array"},{"type":"null"}],"title":"Sources"},"trivia":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trivia"},"image_url_card":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url Card","description":"Full game-rendered card image (frame + art + text; animated for\nancients). `null` when there's no render (mad_science).","readOnly":true},"image_url_card_upg":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url Card Upg","description":"Full game-rendered image of the upgraded card. `null` when the card\nhas no upgrade.","readOnly":true}},"type":"object","required":["id","name","description","cost","type","rarity","target","color","image_url_card","image_url_card_upg"],"title":"Card"},"CardRiderEffect":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"}},"type":"object","required":["id","name","description"],"title":"CardRiderEffect"},"CardSource":{"properties":{"type":{"type":"string","title":"Type"},"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["type","id","name"],"title":"CardSource","description":"Where a card comes from in combat, e.g. a monster that generates it."},"CardTypeVariant":{"properties":{"type":{"type":"string","title":"Type"},"description":{"type":"string","title":"Description"},"damage":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Damage"},"block":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Block"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"riders":{"anyOf":[{"items":{"$ref":"#/components/schemas/CardRiderEffect"},"type":"array"},{"type":"null"}],"title":"Riders"}},"type":"object","required":["type","description"],"title":"CardTypeVariant"},"Character":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"starting_hp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Starting Hp"},"starting_gold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Starting Gold"},"max_energy":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Energy"},"orb_slots":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Orb Slots"},"starting_deck":{"items":{"type":"string"},"type":"array","title":"Starting Deck"},"starting_relics":{"items":{"type":"string"},"type":"array","title":"Starting Relics"},"unlocks_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unlocks After"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"dialogue_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dialogue Color"},"quotes":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Quotes"},"dialogues":{"anyOf":[{"items":{"$ref":"#/components/schemas/CharacterDialogue"},"type":"array"},{"type":"null"}],"title":"Dialogues"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["id","name","description","starting_deck","starting_relics"],"title":"Character"},"CharacterDialogue":{"properties":{"ancient":{"type":"string","title":"Ancient"},"ancient_name":{"type":"string","title":"Ancient Name"},"lines":{"items":{"$ref":"#/components/schemas/CharacterDialogueLine"},"type":"array","title":"Lines"}},"type":"object","required":["ancient","ancient_name","lines"],"title":"CharacterDialogue"},"CharacterDialogueLine":{"properties":{"order":{"type":"integer","title":"Order"},"speaker":{"type":"string","title":"Speaker"},"text":{"type":"string","title":"Text"}},"type":"object","required":["order","speaker","text"],"title":"CharacterDialogueLine"},"DialogueLine":{"properties":{"order":{"type":"string","title":"Order"},"speaker":{"type":"string","title":"Speaker"},"text":{"type":"string","title":"Text"}},"type":"object","required":["order","speaker","text"],"title":"DialogueLine"},"DraftAdviceRequest":{"properties":{"deck":{"items":{"type":"string"},"type":"array","title":"Deck","description":"Items already held, as \"cards:ID\" / \"relics:ID\" (bare ids default to a card)."},"offered":{"items":{"type":"string"},"type":"array","title":"Offered","description":"Card ids currently offered in the reward."},"lang":{"type":"string","title":"Lang","default":"eng"}},"type":"object","title":"DraftAdviceRequest"},"Enchantment":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"description_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description Raw"},"extra_card_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extra Card Text"},"card_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Card Type"},"applicable_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Applicable To"},"is_stackable":{"type":"boolean","title":"Is Stackable","default":false},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["id","name","description"],"title":"Enchantment"},"Encounter":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"room_type":{"type":"string","title":"Room Type"},"is_weak":{"type":"boolean","title":"Is Weak","default":false},"act":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Act"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"monsters":{"anyOf":[{"items":{"$ref":"#/components/schemas/EncounterMonster"},"type":"array"},{"type":"null"}],"title":"Monsters"},"loss_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Loss Text"}},"type":"object","required":["id","name","room_type"],"title":"Encounter"},"EncounterMonster":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"EncounterMonster"},"EntityRef":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"EntityRef","description":"Minimal cross-entity link: just enough to render a named list item."},"Epoch":{"properties":{"id":{"type":"string","title":"Id"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"era":{"type":"string","title":"Era"},"era_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Era Name"},"era_year":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Era Year"},"era_position":{"type":"integer","title":"Era Position"},"sort_order":{"type":"integer","title":"Sort Order"},"story_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Story Id"},"unlock_info":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unlock Info"},"unlock_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unlock Text"},"unlocks_cards":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Unlocks Cards"},"unlocks_relics":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Unlocks Relics"},"unlocks_potions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Unlocks Potions"},"expands_timeline":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Expands Timeline"}},"type":"object","required":["id","title","era","era_position","sort_order"],"title":"Epoch"},"Event":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type"},"act":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Act"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"preconditions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Preconditions"},"options":{"anyOf":[{"items":{"$ref":"#/components/schemas/EventOption"},"type":"array"},{"type":"null"}],"title":"Options"},"pages":{"anyOf":[{"items":{"$ref":"#/components/schemas/EventPage"},"type":"array"},{"type":"null"}],"title":"Pages"},"epithet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Epithet"},"dialogue":{"anyOf":[{"additionalProperties":{"items":{"$ref":"#/components/schemas/DialogueLine"},"type":"array"},"type":"object"},{"type":"null"}],"title":"Dialogue"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"relics":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Relics"}},"type":"object","required":["id","name","type"],"title":"Event"},"EventOption":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"}},"type":"object","required":["id","title","description"],"title":"EventOption"},"EventPage":{"properties":{"id":{"type":"string","title":"Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"options":{"anyOf":[{"items":{"$ref":"#/components/schemas/EventOption"},"type":"array"},{"type":"null"}],"title":"Options"}},"type":"object","required":["id"],"title":"EventPage"},"GlossaryTerm":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"category":{"type":"string","title":"Category"}},"type":"object","required":["id","name","description","category"],"title":"GlossaryTerm"},"Guide":{"properties":{"id":{"type":"string","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"author":{"type":"string","title":"Author"},"date":{"type":"string","title":"Date"},"updated":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated"},"category":{"type":"string","title":"Category"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"summary":{"type":"string","title":"Summary"},"difficulty":{"type":"string","title":"Difficulty"},"character":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"bluesky":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bluesky"},"twitter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Twitter"},"twitch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Twitch"},"content":{"type":"string","title":"Content"}},"type":"object","required":["id","slug","title","author","date","category","tags","summary","difficulty","content"],"title":"Guide"},"GuideSubmission":{"properties":{"title":{"type":"string","title":"Title"},"author_name":{"type":"string","title":"Author Name"},"contact":{"type":"string","title":"Contact"},"category":{"type":"string","title":"Category"},"difficulty":{"type":"string","title":"Difficulty"},"character":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"},"tags":{"type":"string","title":"Tags"},"summary":{"type":"string","title":"Summary"},"content":{"type":"string","title":"Content"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"bluesky":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bluesky"},"twitter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Twitter"},"twitch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Twitch"}},"type":"object","required":["title","author_name","contact","category","difficulty","tags","summary","content"],"title":"GuideSubmission"},"GuideSummary":{"properties":{"id":{"type":"string","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"author":{"type":"string","title":"Author"},"date":{"type":"string","title":"Date"},"updated":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated"},"category":{"type":"string","title":"Category"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"summary":{"type":"string","title":"Summary"},"difficulty":{"type":"string","title":"Difficulty"},"character":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Character"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"bluesky":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bluesky"},"twitter":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Twitter"},"twitch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Twitch"}},"type":"object","required":["id","slug","title","author","date","category","tags","summary","difficulty"],"title":"GuideSummary"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Intent":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["id","name","description"],"title":"Intent"},"Keyword":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"}},"type":"object","required":["id","name","description"],"title":"Keyword"},"MerchantPrice":{"properties":{"base":{"type":"integer","title":"Base"},"min":{"type":"integer","title":"Min"},"max":{"type":"integer","title":"Max"}},"type":"object","required":["base","min","max"],"title":"MerchantPrice"},"Modifier":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"}},"type":"object","required":["id","name","description"],"title":"Modifier"},"Monster":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type"},"min_hp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Hp"},"max_hp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Hp"},"min_hp_ascension":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Hp Ascension"},"max_hp_ascension":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Hp Ascension"},"moves":{"anyOf":[{"items":{"$ref":"#/components/schemas/MonsterMove"},"type":"array"},{"type":"null"}],"title":"Moves"},"damage_values":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/MonsterDamage"},"type":"object"},{"type":"null"}],"title":"Damage Values"},"block_values":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Block Values"},"encounters":{"anyOf":[{"items":{"$ref":"#/components/schemas/MonsterEncounter"},"type":"array"},{"type":"null"}],"title":"Encounters"},"innate_powers":{"anyOf":[{"items":{"$ref":"#/components/schemas/MonsterInnatePower"},"type":"array"},{"type":"null"}],"title":"Innate Powers"},"attack_pattern":{"anyOf":[{"$ref":"#/components/schemas/AttackPattern"},{"type":"null"}]},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"beta_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Beta Image Url"}},"type":"object","required":["id","name","type"],"title":"Monster"},"MonsterDamage":{"properties":{"normal":{"type":"integer","title":"Normal"},"ascension":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ascension"},"hit_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hit Count"}},"type":"object","required":["normal"],"title":"MonsterDamage"},"MonsterEncounter":{"properties":{"encounter_id":{"type":"string","title":"Encounter Id"},"encounter_name":{"type":"string","title":"Encounter Name"},"room_type":{"type":"string","title":"Room Type"},"act":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Act"},"is_weak":{"type":"boolean","title":"Is Weak","default":false}},"type":"object","required":["encounter_id","encounter_name","room_type"],"title":"MonsterEncounter"},"MonsterInnatePower":{"properties":{"power_id":{"type":"string","title":"Power Id"},"amount":{"type":"integer","title":"Amount"},"amount_ascension":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount Ascension"}},"type":"object","required":["power_id","amount"],"title":"MonsterInnatePower"},"MonsterMove":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent"},"damage":{"anyOf":[{"$ref":"#/components/schemas/MonsterMoveDamage"},{"type":"null"}]},"block":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Block"},"heal":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heal"},"powers":{"anyOf":[{"items":{"$ref":"#/components/schemas/MonsterMovePower"},"type":"array"},{"type":"null"}],"title":"Powers"}},"type":"object","required":["id","name"],"title":"MonsterMove"},"MonsterMoveDamage":{"properties":{"normal":{"type":"integer","title":"Normal"},"ascension":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ascension"},"hit_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hit Count"}},"type":"object","required":["normal"],"title":"MonsterMoveDamage"},"MonsterMovePower":{"properties":{"power_id":{"type":"string","title":"Power Id"},"target":{"type":"string","title":"Target"},"amount":{"type":"integer","title":"Amount"}},"type":"object","required":["power_id","target","amount"],"title":"MonsterMovePower"},"Orb":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"description_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description Raw"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"channeled_by_cards":{"anyOf":[{"items":{"$ref":"#/components/schemas/EntityRef"},"type":"array"},{"type":"null"}],"title":"Channeled By Cards"},"channeled_by_relics":{"anyOf":[{"items":{"$ref":"#/components/schemas/EntityRef"},"type":"array"},{"type":"null"}],"title":"Channeled By Relics"}},"type":"object","required":["id","name","description"],"title":"Orb"},"Potion":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"description_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description Raw"},"rarity":{"type":"string","title":"Rarity"},"rarity_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rarity Key"},"pool":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pool"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"compendium_order":{"type":"integer","title":"Compendium Order","default":0}},"type":"object","required":["id","name","description","rarity"],"title":"Potion"},"Power":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"description_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description Raw"},"type":{"type":"string","title":"Type"},"stack_type":{"type":"string","title":"Stack Type"},"allow_negative":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Negative"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["id","name","description","type","stack_type"],"title":"Power"},"PowerApplied":{"properties":{"power":{"type":"string","title":"Power"},"power_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Power Key"},"amount":{"type":"integer","title":"Amount"}},"type":"object","required":["power","amount"],"title":"PowerApplied"},"Relic":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"description_raw":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description Raw"},"flavor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flavor"},"rarity":{"type":"string","title":"Rarity"},"rarity_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rarity Key"},"pool":{"type":"string","title":"Pool"},"merchant_price":{"anyOf":[{"$ref":"#/components/schemas/MerchantPrice"},{"type":"null"}]},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"image_variants":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Image Variants"},"name_variants":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Name Variants"},"notes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Notes"},"compendium_order":{"type":"integer","title":"Compendium Order","default":0}},"type":"object","required":["id","name","description","rarity","pool"],"title":"Relic"},"Story":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"epochs":{"items":{"type":"string"},"type":"array","title":"Epochs"}},"type":"object","required":["id","name","epochs"],"title":"Story"},"Tier":{"properties":{"id":{"type":"string","maxLength":40,"minLength":1,"title":"Id"},"label":{"type":"string","maxLength":24,"minLength":0,"title":"Label"},"color":{"type":"string","maxLength":32,"minLength":1,"title":"Color"},"items":{"items":{"type":"string"},"type":"array","title":"Items"}},"type":"object","required":["id","label","color"],"title":"Tier"},"TierListCreate":{"properties":{"title":{"type":"string","maxLength":100,"minLength":1,"title":"Title"},"entity_type":{"type":"string","title":"Entity Type"},"tiers":{"items":{"$ref":"#/components/schemas/Tier"},"type":"array","title":"Tiers"},"unranked":{"items":{"type":"string"},"type":"array","title":"Unranked"},"comments":{"additionalProperties":{"type":"string"},"type":"object","title":"Comments"}},"type":"object","required":["title","entity_type"],"title":"TierListCreate"},"TierListUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Title"},"tiers":{"anyOf":[{"items":{"$ref":"#/components/schemas/Tier"},"type":"array"},{"type":"null"}],"title":"Tiers"},"unranked":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Unranked"},"comments":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Comments"},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image"}},"type":"object","title":"TierListUpdate"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}