{"openapi": "3.1.0", "x-build": "1.60.1.70630", "x-read": "2026-10-27", "info": {"title": "Forever News data API", "version": "1", "summary": "Everything Forever News reads from the files of World of Warcraft: Forever, read-only.", "description": "Licensed under CC BY 4.0: free to use and share, as long as you credit Forever News with a link to https://wowforever.news. The licence covers Forever News's compilation and classification. World of Warcraft names and texts belong to Blizzard Entertainment.", "license": {"name": "CC BY 4.0", "url": "https://creativecommons.org/licenses/by/4.0/"}}, "servers": [{"url": "https://wowforever.news"}], "paths": {"/api/v1": {"get": {"summary": "What this is: the build, the counts, the addresses, the filters with their allowed values, what each field means, the notes.", "parameters": [], "responses": {"200": {"description": "The index.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"name": {"type": "string"}, "version": {"type": "integer"}, "build": {"type": "string"}, "read": {"type": "string"}, "license": {"type": "string"}, "license_url": {"type": "string"}, "license_covers": {"type": "string"}, "terms": {"type": "string"}, "credit": {"type": "string"}, "product": {"type": "string"}, "build_name": {"type": "string"}, "counts": {"type": "object"}, "internal": {"type": "object"}, "changes_recorded": {"type": "integer"}, "limits": {"type": "object"}, "addresses": {"type": "array"}, "about": {"type": "object"}, "filters": {"type": "object"}, "fields": {"type": "object"}, "notes": {"type": "array"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/talents": {"get": {"summary": "The talents, a page at a time.", "parameters": [{"name": "class", "in": "query", "schema": {"type": "string", "enum": ["druid", "hunter", "mage", "paladin", "priest", "rogue", "shaman", "warlock", "warrior"]}}, {"name": "origin", "in": "query", "schema": {"type": "string", "enum": ["classic", "sod", "forever"]}}, {"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 60}, "description": "part of a name: 60 characters at most, none of them a control character"}, {"name": "internal", "in": "query", "schema": {"type": "string", "enum": ["false", "true"]}, "description": "true to include Blizzard's own working records"}, {"name": "sort", "in": "query", "schema": {"type": "string", "enum": ["tree", "name"], "default": "tree"}, "description": "name, the order every listing but the talents comes in; talents come by tree (class, then the tree as the game orders its tabs, then row, then column) unless name is asked for; items also level or -level (highest first)"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}, "description": "1 to 100, 50 when left out"}, {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000000, "default": 0}, "description": "records to skip"}, {"name": "tree", "in": "query", "schema": {"type": "string", "enum": ["Affliction", "Arcane", "Arms", "Assassination", "Balance", "Beast Mastery", "Combat", "Demonology", "Destruction", "Discipline", "Elemental", "Enhancement", "Feral Combat", "Fire", "Frost", "Fury", "Holy", "Marksmanship", "Protection", "Restoration", "Retribution", "Shadow", "Subtlety", "Survival"]}}], "responses": {"200": {"description": "A page of records.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "total": {"type": "integer", "description": "How many records answer the question."}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "next": {"type": ["string", "null"], "description": "The address of the next page of the same question; null after the last."}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/talent"}}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/talents/{id}": {"get": {"summary": "One of the talents.", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}, "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}], "responses": {"200": {"description": "The record.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "result": {"$ref": "#/components/schemas/talent"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "404": {"$ref": "#/components/responses/404"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/spells": {"get": {"summary": "The spells, a page at a time.", "parameters": [{"name": "class", "in": "query", "schema": {"type": "string", "enum": ["druid", "hunter", "mage", "paladin", "priest", "rogue", "shaman", "warlock", "warrior"]}}, {"name": "origin", "in": "query", "schema": {"type": "string", "enum": ["classic", "later", "sod", "forever"]}}, {"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 60}, "description": "part of a name: 60 characters at most, none of them a control character"}, {"name": "internal", "in": "query", "schema": {"type": "string", "enum": ["false", "true"]}, "description": "true to include Blizzard's own working records"}, {"name": "sort", "in": "query", "schema": {"type": "string", "enum": ["name"], "default": "name"}, "description": "name, the order every listing but the talents comes in; talents come by tree (class, then the tree as the game orders its tabs, then row, then column) unless name is asked for; items also level or -level (highest first)"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}, "description": "1 to 100, 50 when left out"}, {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000000, "default": 0}, "description": "records to skip"}], "responses": {"200": {"description": "A page of records.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "total": {"type": "integer", "description": "How many records answer the question."}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "next": {"type": ["string", "null"], "description": "The address of the next page of the same question; null after the last."}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/spell"}}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/spells/{id}": {"get": {"summary": "One of the spells.", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}, "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}], "responses": {"200": {"description": "The record.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "result": {"$ref": "#/components/schemas/spell"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "404": {"$ref": "#/components/responses/404"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/racials": {"get": {"summary": "The racials, a page at a time.", "parameters": [{"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 60}, "description": "part of a name: 60 characters at most, none of them a control character"}, {"name": "internal", "in": "query", "schema": {"type": "string", "enum": ["false", "true"]}, "description": "true to include Blizzard's own working records"}, {"name": "sort", "in": "query", "schema": {"type": "string", "enum": ["name"], "default": "name"}, "description": "name, the order every listing but the talents comes in; talents come by tree (class, then the tree as the game orders its tabs, then row, then column) unless name is asked for; items also level or -level (highest first)"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}, "description": "1 to 100, 50 when left out"}, {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000000, "default": 0}, "description": "records to skip"}, {"name": "race", "in": "query", "schema": {"type": "string", "enum": ["Dwarf", "Gnome", "High Order Skyborne", "Human", "Night Elf", "Orc", "Tauren", "Troll", "Undead", "Windshaper Skyborne"]}}], "responses": {"200": {"description": "A page of records.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "total": {"type": "integer", "description": "How many records answer the question."}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "next": {"type": ["string", "null"], "description": "The address of the next page of the same question; null after the last."}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/racial"}}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/racials/{id}": {"get": {"summary": "One of the racials.", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}, "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}], "responses": {"200": {"description": "The record.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "result": {"$ref": "#/components/schemas/racial"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "404": {"$ref": "#/components/responses/404"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/items": {"get": {"summary": "The items, a page at a time.", "parameters": [{"name": "class", "in": "query", "schema": {"type": "string", "enum": ["druid", "hunter", "mage", "paladin", "priest", "rogue", "shaman", "warlock", "warrior"]}}, {"name": "origin", "in": "query", "schema": {"type": "string", "enum": ["classic", "later", "sod", "forever"]}}, {"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 60}, "description": "part of a name: 60 characters at most, none of them a control character"}, {"name": "internal", "in": "query", "schema": {"type": "string", "enum": ["false", "true"]}, "description": "true to include Blizzard's own working records"}, {"name": "sort", "in": "query", "schema": {"type": "string", "enum": ["name", "level", "-level"], "default": "name"}, "description": "name, the order every listing but the talents comes in; talents come by tree (class, then the tree as the game orders its tabs, then row, then column) unless name is asked for; items also level or -level (highest first)"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}, "description": "1 to 100, 50 when left out"}, {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000000, "default": 0}, "description": "records to skip"}, {"name": "slot", "in": "query", "schema": {"type": "string", "enum": ["Ammo", "Back", "Bag", "Chest", "Feet", "Finger", "Hands", "Head", "Held In Off-hand", "Legs", "Main Hand", "Neck", "Off Hand", "One-Hand", "Ranged", "Relic", "Shield", "Shirt", "Shoulder", "Tabard", "Thrown", "Trinket", "Two-Hand", "Waist", "Wrist"]}}, {"name": "quality", "in": "query", "schema": {"type": "string", "enum": ["Artifact", "Common", "Epic", "Heirloom", "Legendary", "Poor", "Rare", "Uncommon"]}}, {"name": "type", "in": "query", "schema": {"type": "string", "enum": ["Armor / Cloth", "Armor / Cosmetic", "Armor / Idol", "Armor / Leather", "Armor / Libram", "Armor / Mail", "Armor / Miscellaneous", "Armor / Plate", "Armor / Shield", "Armor / Totem", "Consumable / Bandages", "Consumable / Device", "Consumable / Elixirs", "Consumable / Explosives", "Consumable / Flasks", "Consumable / Food & Drink", "Consumable / Other", "Consumable / Permanent", "Consumable / Potions", "Consumable / Scrolls", "Consumable / Temporary", "Container / Bag", "Container / Enchanting Bag", "Container / Herb Bag", "Container / Leatherworking Bag", "Container / Mining Bag", "Container / Reagent Bag", "Container / Soul Bag", "Key / Key", "Miscellaneous / Holiday", "Miscellaneous / Junk", "Miscellaneous / Mount", "Miscellaneous / Other", "Miscellaneous / Pet", "Miscellaneous / Reagent", "Projectile / Arrow", "Projectile / Bullet", "Quest / Quest", "Quiver / Ammo Pouch", "Quiver / Quiver", "Reagent / Reagent", "Recipe / Alchemy", "Recipe / Blacksmithing", "Recipe / Book", "Recipe / Cooking", "Recipe / Enchanting", "Recipe / Engineering", "Recipe / First Aid", "Recipe / Fishing", "Recipe / Leatherworking", "Recipe / Tailoring", "Trade Goods / Cloth", "Trade Goods / Cooking", "Trade Goods / Elemental", "Trade Goods / Enchanting", "Trade Goods / Explosives (OBSOLETE)", "Trade Goods / Herb", "Trade Goods / Leather", "Trade Goods / Metal & Stone", "Trade Goods / Other", "Trade Goods / Parts", "Trade Goods / Trade Goods (OBSOLETE)", "Weapon / Axe", "Weapon / Bow", "Weapon / Crossbow", "Weapon / Dagger", "Weapon / Fishing Pole", "Weapon / Fist Weapon", "Weapon / Gun", "Weapon / Mace", "Weapon / Miscellaneous", "Weapon / Polearm", "Weapon / Staff", "Weapon / Sword", "Weapon / Thrown", "Weapon / Wand", "WoW Token"]}}, {"name": "min_level", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000}, "description": "lowest item level"}, {"name": "max_level", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000}, "description": "highest item level"}], "responses": {"200": {"description": "A page of records.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "total": {"type": "integer", "description": "How many records answer the question."}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "next": {"type": ["string", "null"], "description": "The address of the next page of the same question; null after the last."}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/item"}}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/items/{id}": {"get": {"summary": "One of the items.", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}, "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}], "responses": {"200": {"description": "The record.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "result": {"$ref": "#/components/schemas/item"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "404": {"$ref": "#/components/responses/404"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/zones": {"get": {"summary": "The zones, a page at a time.", "parameters": [{"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 60}, "description": "part of a name: 60 characters at most, none of them a control character"}, {"name": "internal", "in": "query", "schema": {"type": "string", "enum": ["false", "true"]}, "description": "true to include Blizzard's own working records"}, {"name": "sort", "in": "query", "schema": {"type": "string", "enum": ["name"], "default": "name"}, "description": "name, the order every listing but the talents comes in; talents come by tree (class, then the tree as the game orders its tabs, then row, then column) unless name is asked for; items also level or -level (highest first)"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}, "description": "1 to 100, 50 when left out"}, {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000000, "default": 0}, "description": "records to skip"}, {"name": "map", "in": "query", "schema": {"type": "string", "enum": ["Ahn'Qiraj Temple", "Alliance PVP Barracks", "Alterac Valley", "Arathi Basin", "Azshara Crater", "Battle for Gilneas", "Blackfathom Deeps", "Blackrock Depths", "Blackrock Spire", "Blackwing Lair", "Burning of Andorhal", "Caverns of Time", "City of Dalaran", "Darkspear Islands", "Deadmines", "Deadwind Pass", "Deeprun Tram", "Demon Fall Canyon", "Dire Maul", "Eastern Kingdoms", "Emerald Dream", "Excavation Site: Wetlands", "Gnomeregan", "Horde PVP Barracks", "Hyjal Crater", "Kalimdor", "Karazhan Crypts", "Manor Mistmantle", "Maraudon", "Molten Core", "Naxxramas", "Nightmare Grove", "Ragefire Chasm", "Razorfen Downs", "Razorfen Kraul", "Ruins of Ahn'Qiraj", "Ruins of Lordaeron", "Scarlet Enclave", "Scarlet Monastery", "Scholomance", "Shadow Hold", "Shadowfang Keep", "Starfall Barrow Den", "Storm Cliffs", "Stormwind Stockade", "Stratholme", "Sunken Temple", "The Crystal Vale", "The Hall of Thanes", "The Scarab Dais", "The Tainted Scar", "Uldaman", "Wailing Caverns", "Warsong Gulch", "Warsong Gulch (Winter)", "Zephras Isle", "Zul'Farrak", "Zul'Gurub"]}}], "responses": {"200": {"description": "A page of records.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "total": {"type": "integer", "description": "How many records answer the question."}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "next": {"type": ["string", "null"], "description": "The address of the next page of the same question; null after the last."}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/zone"}}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/zones/{id}": {"get": {"summary": "One of the zones.", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}, "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}], "responses": {"200": {"description": "The record.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "result": {"$ref": "#/components/schemas/zone"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "404": {"$ref": "#/components/responses/404"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/achievements": {"get": {"summary": "The achievements, a page at a time.", "parameters": [{"name": "q", "in": "query", "schema": {"type": "string", "maxLength": 60}, "description": "part of a name: 60 characters at most, none of them a control character"}, {"name": "internal", "in": "query", "schema": {"type": "string", "enum": ["false", "true"]}, "description": "true to include Blizzard's own working records"}, {"name": "sort", "in": "query", "schema": {"type": "string", "enum": ["category", "name"], "default": "category"}, "description": "name, the order every listing but the talents comes in; talents come by tree (class, then the tree as the game orders its tabs, then row, then column) unless name is asked for; items also level or -level (highest first)"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}, "description": "1 to 100, 50 when left out"}, {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000000, "default": 0}, "description": "records to skip"}, {"name": "category", "in": "query", "schema": {"type": "string", "enum": ["Adventure", "Alchemy", "Battlegrounds", "Blacksmithing", "Boss Kills", "Character", "Combat", "Consumables", "Creatures", "Deaths", "Do Not Display", "Druid", "Dungeons", "Dungeons & Raids", "Dungeons and Raids", "Eastern Kingdoms", "Enchanting", "Engineering", "Explorer", "Gear", "Honorable Kills", "Hunter", "Kalimdor", "Killing Blows", "Kills", "Leatherworking", "Mage", "Paladin", "Player vs. Player", "Priest", "Professions", "Quests", "Raids", "Ranks", "Reputation", "Reputations", "Resurrection", "Rogue", "Season Journey", "Secondary Skills", "Shaman", "Skills", "Social", "Statistics", "Tailoring", "Tier 1 Gear", "Travel", "Warlock", "Warrior", "Wealth", "World"]}}], "responses": {"200": {"description": "A page of records.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "total": {"type": "integer", "description": "How many records answer the question."}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "next": {"type": ["string", "null"], "description": "The address of the next page of the same question; null after the last."}, "results": {"type": "array", "items": {"$ref": "#/components/schemas/achievement"}}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/achievements/{id}": {"get": {"summary": "One of the achievements.", "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}, "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}], "responses": {"200": {"description": "The record.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "result": {"$ref": "#/components/schemas/achievement"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "404": {"$ref": "#/components/responses/404"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/changes": {"get": {"summary": "What differed between two builds of WoW Forever, newest first.", "parameters": [{"name": "kind", "in": "query", "schema": {"type": "string", "enum": ["talent", "spell", "racial", "item", "zone", "achievement"]}}, {"name": "build", "in": "query", "schema": {"type": "string"}, "description": "the build a change was first seen in"}, {"name": "limit", "in": "query", "schema": {"type": "integer", "minimum": 1, "maximum": 100, "default": 50}, "description": "1 to 100, 50 when left out"}, {"name": "offset", "in": "query", "schema": {"type": "integer", "minimum": 0, "maximum": 1000000, "default": 0}, "description": "records to skip"}], "responses": {"200": {"description": "A page of changes.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "total": {"type": "integer", "description": "How many records answer the question."}, "limit": {"type": "integer"}, "offset": {"type": "integer"}, "next": {"type": ["string", "null"], "description": "The address of the next page of the same question; null after the last."}, "results": {"type": "array", "items": {"type": "object", "properties": {"seen": {"type": "string"}, "build_from": {"type": "string"}, "build_to": {"type": "string"}, "kind": {"type": "string", "enum": ["talent", "spell", "racial", "item", "zone", "achievement"]}, "id": {"type": "string"}, "name": {"type": "string"}, "what": {"type": "string", "enum": ["added", "removed", "changed"]}, "before": {"description": "The record as it was; null when it was added.", "oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/talent"}, {"$ref": "#/components/schemas/spell"}, {"$ref": "#/components/schemas/racial"}, {"$ref": "#/components/schemas/item"}, {"$ref": "#/components/schemas/zone"}, {"$ref": "#/components/schemas/achievement"}]}, "after": {"description": "The record as it is; null when it was removed.", "oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/talent"}, {"$ref": "#/components/schemas/spell"}, {"$ref": "#/components/schemas/racial"}, {"$ref": "#/components/schemas/item"}, {"$ref": "#/components/schemas/zone"}, {"$ref": "#/components/schemas/achievement"}]}}}}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/raid-buffs": {"get": {"summary": "The buffs and debuffs a class, a spec or a hunter's pet brings to a raid: how far each reaches, whom it helps, what it does not stack with, and the game records it rests on. Written by hand, each with its source and how sure it is.", "parameters": [], "responses": {"200": {"description": "What we know.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string"}, "read": {"type": "string"}, "license": {"type": "string"}, "terms": {"type": "string"}, "knowledge": {"type": "string", "description": "The version of what is written here: the day it last changed. It changes when we change it, not with the build."}, "checked_against": {"type": "string", "description": "The build every piece was last checked against (being_checked says what changed since)."}, "about": {"type": "string"}, "taken_over": {"type": "string", "description": "Where it was first written, and what was changed when we took it over."}, "buffs": {"type": "array", "description": "Every buff, debuff and raid tool, in a fixed order: one is only ever added at the end, so a place in the list keeps its meaning.", "items": {"type": "object", "properties": {"id": {"description": "Never changes and is never given to another buff: saved plans and share links hold it."}, "order": {"description": "Where a raid leader sees it among buffs of equal standing, 1 first: the order Guilds Forever's planner showed until 19 October 2026, kept when it switched to this API. A planner sorts by it once; the place in buffs stays fixed."}, "name": {"description": "What it is called in a raid. A name several spells share says so (Demoralizing Shout or Roar); cast_as names each."}, "label": {"description": "A short name, for a small tile."}, "icon": {"description": "The game's name of its icon; the picture is at /icons/<icon>.png."}, "kind": {"description": "buff (on players), debuff (on the enemy) or utility (summons, a battle resurrection, a cast on one ally)."}, "scope": {"description": "raid: one caster covers the whole raid; party: the caster's own party."}, "from": {"description": "Who brings it, as class:spec (druid:feral_tank), with * for every spec of the class. The class and spec ids are Guilds Forever's planner's."}, "record": {"description": "The address of the record whose tooltip stands for it: the highest rank of its spell, or a talent's record when the buff is the talent's own and no spell of it is trained higher (Leader of the Pack)."}, "rests_on": {"description": "The addresses of every record what is written here rests on: when the game changes one, this buff is to be checked again."}, "talents": {"description": "The addresses of the talents any one of which gives it: a player's own talents count before a guess from the spec. [] when no talent is needed."}, "cast_as": {"description": "When the name is shared, what each provider casts, keyed as in from: its name, its own icon (null when it is the buff's) and its record (null when it is a choice of several, as Fire, Frost or Shadow). {} otherwise."}, "hunter_pet": {"description": "A hunter brings it only with this pet out (an id of hunter_pets); null otherwise."}, "helps": {"description": "Whom it feeds, of melee, ranged, caster, healer and tank. null when it helps everyone."}, "mana_only": {"description": "true when it does nothing for a player without mana."}, "wants": {"description": "For a party buff, the kinds of player a party needs it for, of the same five; [] for nobody unless asked. null when not said."}, "not_with": {"description": "The ids of other buffs it does not stack with inside one party."}, "seat": {"description": "One for each player of the class: group (curse or judge) and order. Each further warlock (or paladin, for judgements) brings the next in the order. null otherwise."}, "slot": {"description": "What a player gives up for it when only one of a kind runs at a time: aura (a paladin's one aura), or earth, fire, water or air (a shaman's one totem of each element). null otherwise."}, "must": {"description": "true when a raid should have it: counted as missing when nobody brings it."}, "situational": {"description": "true when only some fights need it: never counted as missing."}, "bonus": {"description": "true when it counts when someone brings it but is never missing (a hunter's pet's buff)."}, "uncertain": {"description": "The id of the open question it depends on (see uncertain), or null."}, "confidence": {"description": "How sure what is written is: high, medium or low."}, "source": {"description": "Where it was learned: an id of sources."}, "note": {"description": "What a raid leader needs to know of it, in a sentence or a few."}, "being_checked": {"description": "Added by the API: the addresses of the records it rests on that read otherwise now (name, rank, whether it is its spell's highest, text, ranks' texts, tooltip lines) than in the build it was last checked against (checked_against), or that are gone. While the list is not empty it is being checked; [] when nothing changed."}}}}, "blessings": {"type": "array", "description": "The ids of the paladin Blessings a player may be given, one each: whoever casts it, a second one replaces the first."}, "hunter_pets": {"type": "array", "description": "The pets a planner tells apart, in a fixed order: id, label, ability, the buff it brings (null for none), what it gives, the record of its ability, rests_on and being_checked (as a buff's)."}, "resistances": {"type": "object", "description": "For each school, who raises its resistance: class, spell, the buff it is, whether it is an aura (a paladin's one aura) and the spell's record. An empty list for a school nobody raises. Its buff's being_checked covers it."}, "uncertain": {"type": "object", "description": "The open questions a buff can depend on, by id: what is not confirmed in WoW Forever, and how sure the guess is."}, "sources": {"type": "object", "description": "Where what is written was learned, by id."}, "fields": {"type": "object", "description": "What each part and field means: this table."}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/class-tools": {"get": {"summary": "Who can do the jobs a raid needs covered (remove magic, curses, poison or disease, interrupt, purge, remove a Frenzy, bring back a dead player), and who has a healing cooldown or a defensive of their own: by class, spec, talent and pet, each with the words of its tooltip that show it.", "parameters": [], "responses": {"200": {"description": "What we know.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string"}, "read": {"type": "string"}, "license": {"type": "string"}, "terms": {"type": "string"}, "knowledge": {"type": "string", "description": "The version of what is written here: the day it last changed. It changes when we change it, not with the build."}, "checked_against": {"type": "string", "description": "The build every piece was last checked against (being_checked says what changed since)."}, "about": {"type": "string"}, "taken_over": {"type": "string", "description": "Where it was first written, and what was changed when we took it over."}, "jobs": {"type": "array", "description": "The jobs a raid needs covered, in a fixed order, each with its id (never changed), a short label and a title."}, "cooldown_kinds": {"type": "array", "description": "The two kinds of cooldown a raid plans, each with its id (never changed), a label and what counts as one."}, "tools": {"type": "array", "description": "Who can do each job, one entry for each class and spell, in a fixed order (a player is shown with the first that fits). Counts only: how many a fight needs is not said here.", "items": {"type": "object", "properties": {"job": {"description": "The id of the job (of jobs, or of cooldown_kinds for a cooldown)."}, "class": {"description": "The class that has it."}, "spell": {"description": "Its name, as a raid calls it."}, "record": {"description": "The address of the spell's record, at its highest rank."}, "rests_on": {"description": "The addresses of every record what is written here rests on: when the game changes one, this entry is to be checked again."}, "quote": {"description": "The words of its tooltip that show it does the job, as the record's text has them."}, "specs": {"description": "Only these specs of the class have it (a talent gives it, or it needs a shield, which only Protection carries); null when every spec does."}, "talent": {"description": "The address of the talent that gives it: a player's own talents decide, a spec alone is a guess. null when no talent is needed."}, "pet": {"description": "The warlock's demon that must be out for it (Felhunter, Voidwalker): it counts, but as a guess. null otherwise."}, "note": {"description": "What is said beside it (needs a shield, before the pull). null when nothing."}, "being_checked": {"description": "Added by the API: the addresses of the records it rests on that read otherwise now (name, rank, whether it is its spell's highest, text, ranks' texts, tooltip lines) than in the build it was last checked against (checked_against), or that are gone. While the list is not empty it is being checked; [] when nothing changed."}}}}, "cooldowns": {"type": "array", "description": "Who has a healing cooldown or a defensive of their own, one entry for each class and spell, in a fixed order (a player is shown with the first that fits: a frost mage with Ice Block, another with a Ward).", "items": {"type": "object", "properties": {"job": {"description": "The id of the job (of jobs, or of cooldown_kinds for a cooldown)."}, "class": {"description": "The class that has it."}, "spell": {"description": "Its name, as a raid calls it."}, "record": {"description": "The address of the spell's record, at its highest rank."}, "rests_on": {"description": "The addresses of every record what is written here rests on: when the game changes one, this entry is to be checked again."}, "quote": {"description": "The words of its tooltip that show it does the job, as the record's text has them."}, "specs": {"description": "Only these specs of the class have it (a talent gives it, or it needs a shield, which only Protection carries); null when every spec does."}, "talent": {"description": "The address of the talent that gives it: a player's own talents decide, a spec alone is a guess. null when no talent is needed."}, "pet": {"description": "The warlock's demon that must be out for it (Felhunter, Voidwalker): it counts, but as a guess. null otherwise."}, "note": {"description": "What is said beside it (needs a shield, before the pull). null when nothing."}, "being_checked": {"description": "Added by the API: the addresses of the records it rests on that read otherwise now (name, rank, whether it is its spell's highest, text, ranks' texts, tooltip lines) than in the build it was last checked against (checked_against), or that are gone. While the list is not empty it is being checked; [] when nothing changed."}}}}, "fields": {"type": "object", "description": "What each part and field means: this table."}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/ability-notes": {"get": {"summary": "For each talent and class spell: what it changes, what it takes from others and gives them, what it does not stack with, its numbers, what it does for a raid and what is still open, with the shared rules the notes cite. Written by hand from the tooltips, each claim saying how sure it is; every note is a draft, not confirmed in the game.", "parameters": [], "responses": {"200": {"description": "What we know.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string"}, "read": {"type": "string"}, "license": {"type": "string"}, "terms": {"type": "string"}, "knowledge": {"type": "string", "description": "The version of what is written here: the day it last changed. It changes when we change it, not with the build."}, "checked_against": {"type": "string", "description": "The build every piece was last checked against (being_checked says what changed since)."}, "about": {"type": "string"}, "taken_over": {"type": "string", "description": "Where it was first written, and what was changed when we took it over."}, "talents": {"type": "array", "description": "A note for each talent, class by class and tree by tree.", "items": {"type": "object", "properties": {"record": {"description": "The address of the talent or class spell the note is about, a spell's at its highest rank. null for the few the API holds no record of: skills every class shares (Block, Dodge, Languages, Shoot), a hunter's pet's Sonic Blast, Omen of Clarity, and the Arcane Wrath talent, which this build holds as a spell only."}, "name": {"description": "Its name."}, "class": {"description": "The class that has it."}, "tree": {"description": "A talent's tree; Baseline for a spell every spec has, Pet for a hunter's pet's ability."}, "modifies": {"description": "The spells and talents it changes, each {name, record}, another class's too (Dampen Magic in a heal's note); record is null for one the API holds no record of."}, "category": {"description": "What it is for: damage, healing, defense, threat, utility, mobility, cooldown, rage or pvp."}, "roles": {"description": "Whom it is for, of melee, ranged, caster, healer and tank."}, "raid": {"description": "How much it matters in a raid: core, good, situational, low or none."}, "uses": {"description": "What it takes from others to work better, each {kind, how, detail, domains, certainty, quote}: kind, the stat or effect (mana, crit, armor_reduction); how, the way it is used (scales, cost, trigger, window, limit, protects); detail, in a sentence; domains, the kinds of hit it concerns (melee, ranged, healing, or a school); certainty: text (its tooltip says so, and quote holds the words), open (a guess still to be checked) or unconfirmed (taken from how such things are assumed to work, not confirmed in WoW Forever); quote: null unless certainty is text."}, "gives": {"description": "What it gives others, each {kind, reach, detail, amount, domains, certainty, quote}: reach, who gets it (raid, party, one_ally, enemy_target, self); amount, {value, unit} with unit flat or %, or null; certainty: text (its tooltip says so, and quote holds the words), open (a guess still to be checked) or unconfirmed (taken from how such things are assumed to work, not confirmed in WoW Forever); quote: null unless certainty is text."}, "not_with": {"description": "What it does not stack with or add nothing beside, each {kind, from, why, domains, certainty, quote}: from, the spells or talents, each {name, record}; why, in a sentence; certainty: text (its tooltip says so, and quote holds the words), open (a guess still to be checked) or unconfirmed (taken from how such things are assumed to work, not confirmed in WoW Forever); quote: null unless certainty is text."}, "numbers": {"description": "Its numbers as its tooltip gives them, each {label, value, unit}."}, "analysis": {"description": "What it does for a raid, in a few sentences."}, "open": {"description": "What is still open about it, each a question in words or rule:<id>, a shared rule of rules."}, "status": {"description": "draft: written from the tooltips and not yet confirmed in the game."}, "rests_on": {"description": "The addresses of every record the note rests on (its own, and what it changes or does not stack with): when the game changes one, the note is to be checked again."}, "being_checked": {"description": "Added by the API: the addresses of the records it rests on that read otherwise now (name, rank, whether it is its spell's highest, text, ranks' texts, tooltip lines) than in the build it was last checked against (checked_against), or that are gone. While the list is not empty it is being checked; [] when nothing changed."}}}}, "spells": {"type": "array", "description": "A note for each class spell (each name once, at its highest rank) and each hunter's pet's ability.", "items": {"type": "object", "properties": {"record": {"description": "The address of the talent or class spell the note is about, a spell's at its highest rank. null for the few the API holds no record of: skills every class shares (Block, Dodge, Languages, Shoot), a hunter's pet's Sonic Blast, Omen of Clarity, and the Arcane Wrath talent, which this build holds as a spell only."}, "name": {"description": "Its name."}, "class": {"description": "The class that has it."}, "tree": {"description": "A talent's tree; Baseline for a spell every spec has, Pet for a hunter's pet's ability."}, "modifies": {"description": "The spells and talents it changes, each {name, record}, another class's too (Dampen Magic in a heal's note); record is null for one the API holds no record of."}, "category": {"description": "What it is for: damage, healing, defense, threat, utility, mobility, cooldown, rage or pvp."}, "roles": {"description": "Whom it is for, of melee, ranged, caster, healer and tank."}, "raid": {"description": "How much it matters in a raid: core, good, situational, low or none."}, "uses": {"description": "What it takes from others to work better, each {kind, how, detail, domains, certainty, quote}: kind, the stat or effect (mana, crit, armor_reduction); how, the way it is used (scales, cost, trigger, window, limit, protects); detail, in a sentence; domains, the kinds of hit it concerns (melee, ranged, healing, or a school); certainty: text (its tooltip says so, and quote holds the words), open (a guess still to be checked) or unconfirmed (taken from how such things are assumed to work, not confirmed in WoW Forever); quote: null unless certainty is text."}, "gives": {"description": "What it gives others, each {kind, reach, detail, amount, domains, certainty, quote}: reach, who gets it (raid, party, one_ally, enemy_target, self); amount, {value, unit} with unit flat or %, or null; certainty: text (its tooltip says so, and quote holds the words), open (a guess still to be checked) or unconfirmed (taken from how such things are assumed to work, not confirmed in WoW Forever); quote: null unless certainty is text."}, "not_with": {"description": "What it does not stack with or add nothing beside, each {kind, from, why, domains, certainty, quote}: from, the spells or talents, each {name, record}; why, in a sentence; certainty: text (its tooltip says so, and quote holds the words), open (a guess still to be checked) or unconfirmed (taken from how such things are assumed to work, not confirmed in WoW Forever); quote: null unless certainty is text."}, "numbers": {"description": "Its numbers as its tooltip gives them, each {label, value, unit}."}, "analysis": {"description": "What it does for a raid, in a few sentences."}, "open": {"description": "What is still open about it, each a question in words or rule:<id>, a shared rule of rules."}, "status": {"description": "draft: written from the tooltips and not yet confirmed in the game."}, "rests_on": {"description": "The addresses of every record the note rests on (its own, and what it changes or does not stack with): when the game changes one, the note is to be checked again."}, "being_checked": {"description": "Added by the API: the addresses of the records it rests on that read otherwise now (name, rank, whether it is its spell's highest, text, ranks' texts, tooltip lines) than in the build it was last checked against (checked_against), or that are gone. While the list is not empty it is being checked; [] when nothing changed."}}}}, "rules": {"type": "object", "description": "The shared rules the notes cite as rule:<id>, by id (never changed): question, what is assumed until it is known (assume), status (unconfirmed, unknown, announced, observed or tooltip), source, the classes it concerns, and the kinds and domains of claims it blocks, supports or depends on."}, "fight_talents": {"type": "array", "description": "The talents a fight makes useless when its enemy can never be in a state (bleeding, frozen), in a fixed order.", "items": {"type": "object", "properties": {"id": {"description": "Never changes and is never given to another."}, "needs": {"description": "The state the enemy must be able to be in for the talent to do anything: bleed or freeze."}, "class": {"description": "The class that has the talent."}, "specs": {"description": "The specs that are taken to have it when a player's own talents are not known."}, "talent": {"description": "The talent's name."}, "record": {"description": "The address of the talent's record."}, "quote": {"description": "The words of its text that show what it needs, as the record's text has them."}, "rests_on": {"description": "The address of the talent's record: when the game changes it, this is to be checked again."}, "being_checked": {"description": "Added by the API: the addresses of the records it rests on that read otherwise now (name, rank, whether it is its spell's highest, text, ranks' texts, tooltip lines) than in the build it was last checked against (checked_against), or that are gone. While the list is not empty it is being checked; [] when nothing changed."}}}}, "fields": {"type": "object", "description": "What each part and field means: this table."}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/openapi.json": {"get": {"summary": "The API as an OpenAPI 3.1 document: every address, what it can be asked with the values allowed, what it answers and how it refuses. A record's fields each have their line; the parts of the other answers are named with the kind of value each holds.", "parameters": [], "responses": {"200": {"description": "This document.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/examples": {"get": {"summary": "Real records chosen by rule, one for each case a reader needs to see, each with the address that returns it.", "parameters": [], "responses": {"200": {"description": "The answer.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string"}, "read": {"type": "string"}, "license": {"type": "string"}, "terms": {"type": "string"}, "chosen": {"type": "string"}, "examples": {"type": "object"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}, "/api/v1/how-we-know": {"get": {"summary": "What our copy of the data can say of each kind by itself: how many records, how many of Blizzard's working records, how many texts hold a ?, where the records were first made, and which version of our reading rules read which build, and when.", "parameters": [], "responses": {"200": {"description": "The answer.", "headers": {"ETag": {"schema": {"type": "string"}, "description": "Send it back as If-None-Match: 304 when nothing changed."}, "Cache-Control": {"schema": {"type": "string"}, "description": "public, max-age=3600"}}, "content": {"application/json": {"schema": {"type": "object", "properties": {"build": {"type": "string", "description": "The build of the game these records were read from."}, "read": {"type": "string", "description": "The day we read it from the game's files."}, "license": {"type": "string"}, "terms": {"type": "string"}, "product": {"type": "string", "description": "The name Blizzard's version server lists the build under: wow_classic_beta is the beta's, wowf the one a build named Retail was first listed under. When two of them hold WoW Forever, this says which one these records were read from."}, "build_name": {"type": "string", "description": "What Blizzard calls the build itself: a beta build's name ends in ForeverBeta."}, "reader": {"type": "integer", "description": "The version of our reading rules that read it: a number raised with every correction to how we turn the game's files into records. Two readings are compared as a change in the game only when the same version made both."}, "layout": {"type": "integer", "description": "The version of the shape our copy of the data is kept in: a number raised when a record's fields change."}, "kinds": {"type": "object"}, "meaning": {"type": "object"}, "second_reading": {"type": "string"}}}}}}, "400": {"$ref": "#/components/responses/400"}, "429": {"$ref": "#/components/responses/429"}, "503": {"$ref": "#/components/responses/503"}}}}}, "components": {"schemas": {"talent": {"type": "object", "required": ["kind", "id", "name", "class", "origin", "url", "icon", "internal", "text", "mechanics", "rank_mechanics", "headers", "tooltip", "tree", "row", "col", "ranks", "rank_texts", "open", "points", "requires", "spell", "level", "teaches", "learned_from", "mechanic", "dispel", "affects", "affected_by", "ppm", "summons", "enchants", "interrupted_by", "breaks_on"], "properties": {"kind": {"type": "string", "description": "What the record is: talent, spell, racial, item, zone or achievement."}, "id": {"type": "string", "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}, "name": {"type": "string", "description": "Its name as the game shows it."}, "class": {"type": "string", "description": "The one class it belongs to, in small letters. null for a racial, and for an item that is not for one class alone (see classes)."}, "origin": {"type": "string", "description": "Where it was first made, told by its number in the game: classic (original Classic), later (a later expansion), sod (Season of Discovery) or forever (made for WoW Forever). null for a racial: the files give it no number to tell it by."}, "url": {"type": "string", "description": "Where this one record is read."}, "icon": {"type": "string", "description": "The name of its icon's file in the game, without folder or ending. Its picture, read from that file, is at https://wowforever.news/icons/<icon>.png (a name with a space has none). null when the files name none."}, "internal": {"type": "boolean", "description": "true for one of Blizzard's own working records, not meant for players: its name carries a note of theirs such as Deprecated, Test or [PH]. Listings leave these out unless internal=true is asked for; each can still be read by its id."}, "text": {"type": "string", "description": "Its description as the game's tooltip words it, for a level 60 character before gear. A ? stands for a number the files do not hold. A talent's is its first rank's; an item's is its own line of description in the tooltip. null when it has none."}, "mechanics": {"type": "object", "required": ["version", "context", "spell_id", "effects", "misc", "duration", "aura_options", "target_restrictions", "source", "related_spells", "related_spells_truncated", "unsupported"], "properties": {"version": {"type": "integer", "const": 2}, "context": {"type": "string", "const": "base-client-record"}, "spell_id": {"type": "integer"}, "effects": {"type": ["array", "null"], "items": {"type": "object", "required": ["id", "index", "effect_type", "aura_type", "mechanic", "implicit_targets", "spell_class_mask", "trigger_spell_id", "base_points", "radius_yards", "raw"], "properties": {"id": {"type": ["integer", "null"]}, "index": {"type": ["integer", "null"]}, "effect_type": {"type": ["integer", "null"]}, "aura_type": {"type": ["integer", "null"]}, "mechanic": {"type": ["integer", "null"]}, "trigger_spell_id": {"type": ["integer", "null"]}, "implicit_targets": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Numeric implicit target A and B, in order; no inferred scope."}, "spell_class_mask": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Raw four-word mask; cannot be matched across classes without spell family evidence."}, "base_points": {"type": ["number", "null"]}, "radius_yards": {"type": ["number", "null"], "description": "The effect's area in yards from its radius index, or null for none or when the radius table was not read."}, "raw": {"type": ["object", "null"], "additionalProperties": true}}}}, "misc": {"type": ["object", "null"], "additionalProperties": true}, "duration": {"type": ["object", "null"], "additionalProperties": true}, "aura_options": {"type": ["object", "null"], "additionalProperties": true}, "target_restrictions": {"type": ["object", "null"], "additionalProperties": true}, "source": {"type": "object", "required": ["build", "reader", "tables", "missing_tables"], "properties": {"build": {"type": "string"}, "reader": {"type": "integer"}, "tables": {"type": "array", "items": {"type": "string"}}, "missing_tables": {"type": "array", "items": {"type": "string"}}}}, "related_spells": {"type": "array", "maxItems": 64, "items": {"type": "object", "required": ["spell_id", "effects", "misc", "duration", "aura_options", "target_restrictions"], "properties": {"spell_id": {"type": "integer"}, "effects": {"type": ["array", "null"], "items": {"type": "object", "required": ["id", "index", "effect_type", "aura_type", "mechanic", "implicit_targets", "spell_class_mask", "trigger_spell_id", "base_points", "radius_yards", "raw"], "properties": {"id": {"type": ["integer", "null"]}, "index": {"type": ["integer", "null"]}, "effect_type": {"type": ["integer", "null"]}, "aura_type": {"type": ["integer", "null"]}, "mechanic": {"type": ["integer", "null"]}, "trigger_spell_id": {"type": ["integer", "null"]}, "implicit_targets": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Numeric implicit target A and B, in order; no inferred scope."}, "spell_class_mask": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Raw four-word mask; cannot be matched across classes without spell family evidence."}, "base_points": {"type": ["number", "null"]}, "radius_yards": {"type": ["number", "null"], "description": "The effect's area in yards from its radius index, or null for none or when the radius table was not read."}, "raw": {"type": ["object", "null"], "additionalProperties": true}}}}, "misc": {"type": ["object", "null"], "additionalProperties": true}, "duration": {"type": ["object", "null"], "additionalProperties": true}, "aura_options": {"type": ["object", "null"], "additionalProperties": true}, "target_restrictions": {"type": ["object", "null"], "additionalProperties": true}, "name": {"type": ["string", "null"]}}}}, "related_spells_truncated": {"type": "boolean"}, "unsupported": {"type": "array", "items": {"type": "string"}}}, "description": "Versioned raw client mechanic evidence for the base spell, or null; see spells.mechanics. Do not infer cross-player ownership, stacking or server behavior from these records."}, "rank_mechanics": {"type": "array", "description": "Point allocations for each talent rank, or null. Effects expose level-60 before-gear points_min/points_max calculated by our tooltip reader, with curve_id and operation_type from TraitDefinitionEffectPoints. These are effect points, not player damage, healing or proc uptime; ranks share the base spell ID."}, "headers": {"type": "object", "description": "Base-client headers for the talent's spell ID, or null when unavailable. These are decoded client records, not player-effective values or an in-game verification. Rank descriptions do not imply matching headers for every rank. See spells.headers."}, "tooltip": {"type": "array", "description": "The lines of its spell's tooltip between the name and the description, as the game lays them out and words them: see spells.tooltip. [] for a passive talent."}, "tree": {"type": "string", "description": "The talent tree it is in, by the name on the tree's tab (Arcane, Fire, Frost)."}, "row": {"type": "integer", "description": "Its row in the tree, counted from the top: 1 is the top row."}, "col": {"type": "integer", "description": "Its place in that row, counted from the left: 1 is the leftmost column."}, "ranks": {"type": "integer", "description": "How many points can be put into it."}, "rank_texts": {"type": "array", "description": "Its description at each rank, the first rank first: as many as ranks. text is the first of them."}, "open": {"type": "boolean", "description": "true when one of its texts holds a ?: a number the game's files do not hold, left open rather than guessed."}, "points": {"type": ["integer", "null"], "description": "How many points must be spent in its tree before it can be taken, as the tree's own condition says (10 for Pyroblast's row); null for none."}, "requires": {"type": "array", "description": "The talent it needs first, as the tree's edges say (Presence of Mind before Arcane Power): a list of {spell, name}, [] for none. An edge drawn both ways between two talents says no order and names none."}, "spell": {"type": "integer", "description": "The number the game gives the talent's spell."}, "level": {"type": ["integer", "null"], "description": "The level a character learns it at, as the game's spell level table gives it (Requires level 1 on Shadow Bolt's first rank); null when the table gives none."}, "teaches": {"type": "array", "description": "The numbers of the spells this one teaches when learned (a book's or a trainer's spell teaches the ability), from the game's own table of what teaches what. [] for none; null when the build read did not hold that table."}, "learned_from": {"type": "array", "description": "The numbers of the spells that teach this one, the same table the other way. [] for none; null when the table was not read."}, "mechanic": {"type": ["null", "string"], "description": "The game's own word for what its category does to a target (Stunned, Rooted, Disarmed), or null for none or when the table was not read."}, "dispel": {"type": ["null", "string"], "description": "The game's own word for what removes it (Magic, Curse, Poison, Disease), or null for none or when the table was not read."}, "affects": {"type": "array", "description": "The spells of its own class family that its effects change, each {spell, name}: the effects' class masks matched against the family masks of the class's spells, so a talent that says \"your Fireball and Pyroblast\" names them here from the files, not the text. [] for none; null when the table was not read."}, "affected_by": {"type": "array", "description": "The talents and spells whose effects change this one, the same match the other way, each {spell, name}. [] for none; null when the table was not read."}, "ppm": {"type": "null", "description": "Its procs per minute when the files give one, or null."}, "summons": {"type": "array", "description": "For each summon effect, what it brings: {creature, name, kind}: the creature's number, its name when the client holds it (the client holds few creatures, so mostly null) and what the game calls the summoned (pet, guardian, totem, companion). [] for none; null when the tables were not read."}, "enchants": {"type": "array", "description": "For each effect that puts an enchantment on an item (a shaman's weapon imbue, a rogue's poison, a rune): {id, name, duration_s, charges, effects}, the enchantment as the game's table has it, each effect {kind, amount, spell, name}: what it does in words (while equipped, chance on hit to cast, a stat or a resistance by name), its points, and the spell it casts with its name when it casts one. [] for none; null when the table was not read."}, "interrupted_by": {"type": "array", "description": "What stops its cast, in words by the game's flags (moving, being pushed back, an interrupt, taking damage); a flag without a word is kept as its bit. [] for none; null when the table was not read."}, "breaks_on": {"type": "array", "description": "What ends the aura it applies, in words by the game's flags (taking damage, moving, casting, attacking, mounting …); a flag without a word is kept as its bit. [] for none; null when the table was not read."}}}, "spell": {"type": "object", "required": ["kind", "id", "name", "class", "origin", "url", "icon", "internal", "text", "mechanics", "headers", "tooltip", "top", "spell", "rank", "taught_by", "pet", "level", "teaches", "learned_from", "mechanic", "dispel", "affects", "affected_by", "ppm", "summons", "enchants", "interrupted_by", "breaks_on"], "properties": {"kind": {"type": "string", "description": "What the record is: talent, spell, racial, item, zone or achievement."}, "id": {"type": "string", "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}, "name": {"type": "string", "description": "Its name as the game shows it."}, "class": {"type": "string", "description": "The one class it belongs to, in small letters. null for a racial, and for an item that is not for one class alone (see classes)."}, "origin": {"type": "string", "description": "Where it was first made, told by its number in the game: classic (original Classic), later (a later expansion), sod (Season of Discovery) or forever (made for WoW Forever). null for a racial: the files give it no number to tell it by."}, "url": {"type": "string", "description": "Where this one record is read."}, "icon": {"type": ["null", "string"], "description": "The name of its icon's file in the game, without folder or ending. Its picture, read from that file, is at https://wowforever.news/icons/<icon>.png (a name with a space has none). null when the files name none."}, "internal": {"type": "boolean", "description": "true for one of Blizzard's own working records, not meant for players: its name carries a note of theirs such as Deprecated, Test or [PH]. Listings leave these out unless internal=true is asked for; each can still be read by its id."}, "text": {"type": "string", "description": "Its description as the game's tooltip words it, for a level 60 character before gear. A ? stands for a number the files do not hold. A talent's is its first rank's; an item's is its own line of description in the tooltip. null when it has none."}, "mechanics": {"type": "object", "required": ["version", "context", "spell_id", "effects", "misc", "duration", "aura_options", "target_restrictions", "source", "related_spells", "related_spells_truncated", "unsupported"], "properties": {"version": {"type": "integer", "const": 2}, "context": {"type": "string", "const": "base-client-record"}, "spell_id": {"type": "integer"}, "effects": {"type": ["array", "null"], "items": {"type": "object", "required": ["id", "index", "effect_type", "aura_type", "mechanic", "implicit_targets", "spell_class_mask", "trigger_spell_id", "base_points", "radius_yards", "raw"], "properties": {"id": {"type": ["integer", "null"]}, "index": {"type": ["integer", "null"]}, "effect_type": {"type": ["integer", "null"]}, "aura_type": {"type": ["integer", "null"]}, "mechanic": {"type": ["integer", "null"]}, "trigger_spell_id": {"type": ["integer", "null"]}, "implicit_targets": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Numeric implicit target A and B, in order; no inferred scope."}, "spell_class_mask": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Raw four-word mask; cannot be matched across classes without spell family evidence."}, "base_points": {"type": ["number", "null"]}, "radius_yards": {"type": ["number", "null"], "description": "The effect's area in yards from its radius index, or null for none or when the radius table was not read."}, "raw": {"type": ["object", "null"], "additionalProperties": true}}}}, "misc": {"type": ["object", "null"], "additionalProperties": true}, "duration": {"type": ["object", "null"], "additionalProperties": true}, "aura_options": {"type": ["object", "null"], "additionalProperties": true}, "target_restrictions": {"type": ["object", "null"], "additionalProperties": true}, "source": {"type": "object", "required": ["build", "reader", "tables", "missing_tables"], "properties": {"build": {"type": "string"}, "reader": {"type": "integer"}, "tables": {"type": "array", "items": {"type": "string"}}, "missing_tables": {"type": "array", "items": {"type": "string"}}}}, "related_spells": {"type": "array", "maxItems": 64, "items": {"type": "object", "required": ["spell_id", "effects", "misc", "duration", "aura_options", "target_restrictions"], "properties": {"spell_id": {"type": "integer"}, "effects": {"type": ["array", "null"], "items": {"type": "object", "required": ["id", "index", "effect_type", "aura_type", "mechanic", "implicit_targets", "spell_class_mask", "trigger_spell_id", "base_points", "radius_yards", "raw"], "properties": {"id": {"type": ["integer", "null"]}, "index": {"type": ["integer", "null"]}, "effect_type": {"type": ["integer", "null"]}, "aura_type": {"type": ["integer", "null"]}, "mechanic": {"type": ["integer", "null"]}, "trigger_spell_id": {"type": ["integer", "null"]}, "implicit_targets": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Numeric implicit target A and B, in order; no inferred scope."}, "spell_class_mask": {"type": ["array", "null"], "items": {"type": "integer"}, "description": "Raw four-word mask; cannot be matched across classes without spell family evidence."}, "base_points": {"type": ["number", "null"]}, "radius_yards": {"type": ["number", "null"], "description": "The effect's area in yards from its radius index, or null for none or when the radius table was not read."}, "raw": {"type": ["object", "null"], "additionalProperties": true}}}}, "misc": {"type": ["object", "null"], "additionalProperties": true}, "duration": {"type": ["object", "null"], "additionalProperties": true}, "aura_options": {"type": ["object", "null"], "additionalProperties": true}, "target_restrictions": {"type": ["object", "null"], "additionalProperties": true}, "name": {"type": ["string", "null"]}}}}, "related_spells_truncated": {"type": "boolean"}, "unsupported": {"type": "array", "items": {"type": "string"}}}, "description": "Version 2 base-client-record evidence, or null: source.build/reader describe the actual decoded tables; missing_tables lists unavailable inputs. effects retains numeric effect_type/aura_type/mechanic, implicit_targets as [A,B], four spell_class_mask words, trigger_spell_id, base_points, radius_yards (the effect's area from its radius index, null for none) and the raw SpellEffect row. misc, aura_options, target_restrictions and duration retain raw base rows or null. related_spells bundles triggered records (maximum 64); related_spells_truncated declares incomplete closure. Zero remains zero; unknown enums are not named. unsupported explicitly lists server behavior, ownership, stacking exclusivity and aura-state prerequisites. No in-game verification or automatic synergy guarantee."}, "headers": {"type": "object", "description": "Base-client spell headers, or null. Sections costs, cast, range, cooldown and reagents may each be null when unknown. Costs retain all resource rows and flat, percentage, per-level, recurring and conditional amounts; they are not a calculated player cost. Cast base_ms/minimum_ms/static_ms and cooldown ability_ms/category_ms/gcd_ms are milliseconds; GCD is separate from ability cooldown. Range keeps friendly and hostile min/max yards plus melee flags. Reagents are exact item IDs/counts without inferred names. Passive, channeled, next_melee (it strikes with the next melee swing) and drains_all_power flags qualify display. This is client evidence, not confirmed gameplay or an in-game tooltip receipt."}, "tooltip": {"type": "array", "description": "The lines of its tooltip between the name and the description, as the game lays them out and words them: rows of [left, right], cost and range first (3,400 Mana | 40 yd range), then cast time and cooldown (Instant | 30 sec cooldown), then one row for each thing it needs (Requires Battle Stance; Requires Shields; Tools: Air Totem; Reagents: Sacred Candle); null for an empty side. Read from the files, so before talents and gear. A part we cannot read for certain is left out rather than guessed. [] for a passive spell, which shows none; null when the spell's details are not known."}, "top": {"type": "boolean", "description": "true for the highest rank of the spell its class has (Rank 6 of Power Word: Fortitude), for a spell without ranks, and for a variant the game names apart under the same name (Polymorph: Turtle, Sunfire: Cat). false for every lower rank, for a part of a ranked spell that carries no rank, and for Blizzard's working records."}, "spell": {"type": "integer", "description": "The number the game gives this spell. Each rank of a spell has a number of its own."}, "rank": {"type": ["null", "string"], "description": "The word the game writes under the name: mostly its rank (Rank 3), sometimes another (Passive, Summon). null when none."}, "taught_by": {"type": ["integer", "null"], "description": "For a hunter pet's ability: the number of the spell the hunter learns in order to teach it. null for every other spell."}, "pet": {"type": ["null", "string"], "description": "For an ability of a warlock's demon: the demon that casts it (Imp, Voidwalker, Succubus, Felhunter). Its class is the warlock's. null for every other spell."}, "level": {"type": ["integer", "null"], "description": "The level a character learns it at, as the game's spell level table gives it (Requires level 1 on Shadow Bolt's first rank); null when the table gives none."}, "teaches": {"type": "array", "description": "The numbers of the spells this one teaches when learned (a book's or a trainer's spell teaches the ability), from the game's own table of what teaches what. [] for none; null when the build read did not hold that table."}, "learned_from": {"type": "array", "description": "The numbers of the spells that teach this one, the same table the other way. [] for none; null when the table was not read."}, "mechanic": {"type": ["null", "string"], "description": "The game's own word for what its category does to a target (Stunned, Rooted, Disarmed), or null for none or when the table was not read."}, "dispel": {"type": ["null", "string"], "description": "The game's own word for what removes it (Magic, Curse, Poison, Disease), or null for none or when the table was not read."}, "affects": {"type": "array", "description": "The spells of its own class family that its effects change, each {spell, name}: the effects' class masks matched against the family masks of the class's spells, so a talent that says \"your Fireball and Pyroblast\" names them here from the files, not the text. [] for none; null when the table was not read."}, "affected_by": {"type": "array", "description": "The talents and spells whose effects change this one, the same match the other way, each {spell, name}. [] for none; null when the table was not read."}, "ppm": {"type": "null", "description": "Its procs per minute when the files give one, or null."}, "summons": {"type": "array", "description": "For each summon effect, what it brings: {creature, name, kind}: the creature's number, its name when the client holds it (the client holds few creatures, so mostly null) and what the game calls the summoned (pet, guardian, totem, companion). [] for none; null when the tables were not read."}, "enchants": {"type": "array", "description": "For each effect that puts an enchantment on an item (a shaman's weapon imbue, a rogue's poison, a rune): {id, name, duration_s, charges, effects}, the enchantment as the game's table has it, each effect {kind, amount, spell, name}: what it does in words (while equipped, chance on hit to cast, a stat or a resistance by name), its points, and the spell it casts with its name when it casts one. [] for none; null when the table was not read."}, "interrupted_by": {"type": "array", "description": "What stops its cast, in words by the game's flags (moving, being pushed back, an interrupt, taking damage); a flag without a word is kept as its bit. [] for none; null when the table was not read."}, "breaks_on": {"type": "array", "description": "What ends the aura it applies, in words by the game's flags (taking damage, moving, casting, attacking, mounting …); a flag without a word is kept as its bit. [] for none; null when the table was not read."}}}, "racial": {"type": "object", "required": ["kind", "id", "name", "class", "origin", "url", "icon", "internal", "text", "race", "spell", "spell_text", "headers", "tooltip"], "properties": {"kind": {"type": "string", "description": "What the record is: talent, spell, racial, item, zone or achievement."}, "id": {"type": "string", "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}, "name": {"type": "string", "description": "Its name as the game shows it."}, "class": {"type": "null", "description": "The one class it belongs to, in small letters. null for a racial, and for an item that is not for one class alone (see classes)."}, "origin": {"type": "null", "description": "Where it was first made, told by its number in the game: classic (original Classic), later (a later expansion), sod (Season of Discovery) or forever (made for WoW Forever). null for a racial: the files give it no number to tell it by."}, "url": {"type": "string", "description": "Where this one record is read."}, "icon": {"type": "string", "description": "The name of its icon's file in the game, without folder or ending. Its picture, read from that file, is at https://wowforever.news/icons/<icon>.png (a name with a space has none). null when the files name none."}, "internal": {"type": "boolean", "description": "true for one of Blizzard's own working records, not meant for players: its name carries a note of theirs such as Deprecated, Test or [PH]. Listings leave these out unless internal=true is asked for; each can still be read by its id."}, "text": {"type": "string", "description": "Its description as the game's tooltip words it, for a level 60 character before gear. A ? stands for a number the files do not hold. A talent's is its first rank's; an item's is its own line of description in the tooltip. null when it has none."}, "race": {"type": "string", "description": "The race that has it."}, "spell": {"type": ["integer", "null"], "description": "The number of the spell behind it, found on the race's own racial skill line by the racial's name; null when that line holds no spell of the name, or several (Expansive Mind is one spell per resource)."}, "spell_text": {"type": ["null", "string"], "description": "That spell's description with its numbers filled in, the text the game shows in its tooltip; text is the shorter line of the character screen. null without a spell."}, "headers": {"type": ["null", "object"], "description": "That spell's headers, as a spell's; null without a spell."}, "tooltip": {"type": ["array", "null"], "description": "That spell's tooltip lines, as a spell's (Instant | 3 min cooldown); null without a spell."}}}, "item": {"type": "object", "required": ["kind", "id", "name", "class", "origin", "url", "icon", "internal", "text", "type", "slot", "quality", "level", "requires", "binds", "classes", "speed", "stats", "effects", "set", "armor", "damage", "unique", "name_line", "sell", "buy"], "properties": {"kind": {"type": "string", "description": "What the record is: talent, spell, racial, item, zone or achievement."}, "id": {"type": "string", "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}, "name": {"type": "string", "description": "Its name as the game shows it."}, "class": {"type": ["null", "string"], "description": "The one class it belongs to, in small letters. null for a racial, and for an item that is not for one class alone (see classes)."}, "origin": {"type": "string", "description": "Where it was first made, told by its number in the game: classic (original Classic), later (a later expansion), sod (Season of Discovery) or forever (made for WoW Forever). null for a racial: the files give it no number to tell it by."}, "url": {"type": "string", "description": "Where this one record is read."}, "icon": {"type": ["null", "string"], "description": "The name of its icon's file in the game, without folder or ending. Its picture, read from that file, is at https://wowforever.news/icons/<icon>.png (a name with a space has none). null when the files name none."}, "internal": {"type": "boolean", "description": "true for one of Blizzard's own working records, not meant for players: its name carries a note of theirs such as Deprecated, Test or [PH]. Listings leave these out unless internal=true is asked for; each can still be read by its id."}, "text": {"type": ["null", "string"], "description": "Its description as the game's tooltip words it, for a level 60 character before gear. A ? stands for a number the files do not hold. A talent's is its first rank's; an item's is its own line of description in the tooltip. null when it has none."}, "type": {"type": "string", "description": "What sort of thing it is, as the game files it (Weapon / Sword, Armor / Cloth, Consumable / Potions)."}, "slot": {"type": ["null", "string"], "description": "Where it is worn or held (Head, Trinket, Two-Hand). null for what cannot be equipped."}, "quality": {"type": "string", "description": "Its colour in the game: Poor (grey), Common (white), Uncommon (green), Rare (blue), Epic (purple), Legendary (orange), Artifact or Heirloom."}, "level": {"type": "integer", "description": "Its item level: how strong the game counts it. Not the level a character needs (see requires)."}, "requires": {"type": ["integer", "null"], "description": "The level a character needs to use it. null when any level will do."}, "binds": {"type": ["null", "string"], "description": "How it is tied to a character: Binds when picked up, Binds when equipped, Binds when used, or Quest Item. null when it is not."}, "classes": {"type": "array", "description": "The classes that may use it, when the game names them. An empty list when every class may."}, "speed": {"type": ["null", "number"], "description": "Its attack speed as the game stores it: a weapon's seconds between two attacks. null when it has none."}, "stats": {"type": "object", "description": "What it adds while worn, each stat with its amount, in the order the item lists them (its tooltip's order). The amounts are worked out from the item level as the game does, not stored. Armor here is bonus armor on top of the item's own (see armor). A stat we have no name for yet shows as Stat and its number."}, "effects": {"type": "array", "description": "What else it does, one entry each: on (Equip, Use, Chance on hit or Learn), name and spell (the spell behind it and that spell's number), text (what the tooltip says; for Learn, the description of the spell taught) and teaches (the number of the spell it teaches, or null)."}, "set": {"type": ["null", "string"], "description": "The name of the set it belongs to. null when it is of no set."}, "armor": {"type": ["integer", "null"], "description": "Its own armor, worked out as the game works it out from its tables: the row of its item level, the column of its quality and the slot's share (a shield from the shield table). Computed, not stored. null for an item without armor, or when a table the build did not hold would be needed."}, "damage": {"type": ["null", "object"], "description": "A weapon's damage, worked out as the game works it out: {min, max, per_second}, from its table's damage per second at its item level and quality, its speed and its variance. Computed, not stored. null for what is not a weapon or ammunition."}, "unique": {"type": ["null", "object"], "description": "What limits how many a character may carry or wear: {name, count}: the limit's name when it is shared by several items (Trinket of the Dawn), else null, and how many. null when there is no limit."}, "name_line": {"type": ["null", "string"], "description": "The grey line the game shows under the name (Raid Unique, a colour, a title), or null."}, "sell": {"type": ["integer", "null"], "description": "What a vendor pays for it, in copper (100 copper is a silver, 100 silver a gold). null when it cannot be sold."}, "buy": {"type": ["integer", "null"], "description": "What a vendor charges for it, in copper, when the files give a price. null otherwise."}}}, "zone": {"type": "object", "required": ["kind", "id", "name", "class", "origin", "url", "icon", "internal", "text", "map", "parent", "zone", "level", "faction"], "properties": {"kind": {"type": "string", "description": "What the record is: talent, spell, racial, item, zone or achievement."}, "id": {"type": "string", "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}, "name": {"type": "string", "description": "Its name as the game shows it."}, "class": {"type": "null", "description": "The one class it belongs to, in small letters. null for a racial, and for an item that is not for one class alone (see classes)."}, "origin": {"type": "null", "description": "Where it was first made, told by its number in the game: classic (original Classic), later (a later expansion), sod (Season of Discovery) or forever (made for WoW Forever). null for a racial: the files give it no number to tell it by."}, "url": {"type": "string", "description": "Where this one record is read."}, "icon": {"type": "null", "description": "The name of its icon's file in the game, without folder or ending. Its picture, read from that file, is at https://wowforever.news/icons/<icon>.png (a name with a space has none). null when the files name none."}, "internal": {"type": "boolean", "description": "true for one of Blizzard's own working records, not meant for players: its name carries a note of theirs such as Deprecated, Test or [PH]. Listings leave these out unless internal=true is asked for; each can still be read by its id."}, "text": {"type": "null", "description": "Its description as the game's tooltip words it, for a level 60 character before gear. A ? stands for a number the files do not hold. A talent's is its first rank's; an item's is its own line of description in the tooltip. null when it has none."}, "map": {"type": ["null", "string"], "description": "The map it is on (Eastern Kingdoms, Kalimdor, or an instance's own map), or null when the files name none."}, "parent": {"type": ["integer", "null"], "description": "The number of the area it lies in (a subzone's zone), or null for a zone of its own."}, "zone": {"type": ["null", "string"], "description": "The name of the zone it lies in, up the chain of parents, or null for a zone of its own."}, "level": {"type": ["integer", "null"], "description": "The level the game counts it explored at, as the files give it; null when they give none (most zones' level ranges are not in these files)."}, "faction": {"type": ["null", "string"], "description": "Whose side the game counts it on: Alliance, Horde, Both, or null for contested or neither."}}}, "achievement": {"type": "object", "required": ["kind", "id", "name", "class", "origin", "url", "icon", "internal", "text", "points", "category", "faction", "reward", "statistic"], "properties": {"kind": {"type": "string", "description": "What the record is: talent, spell, racial, item, zone or achievement."}, "id": {"type": "string", "description": "What this API calls it, always text. An item's, a zone's and an achievement's is its number in the game (19019); a talent's and a spell's is its class and its spell's number (mage-11366); a racial's is its race and its name (orc-blood-fury)."}, "name": {"type": "string", "description": "Its name as the game shows it."}, "class": {"type": "null", "description": "The one class it belongs to, in small letters. null for a racial, and for an item that is not for one class alone (see classes)."}, "origin": {"type": "null", "description": "Where it was first made, told by its number in the game: classic (original Classic), later (a later expansion), sod (Season of Discovery) or forever (made for WoW Forever). null for a racial: the files give it no number to tell it by."}, "url": {"type": "string", "description": "Where this one record is read."}, "icon": {"type": ["null", "string"], "description": "The name of its icon's file in the game, without folder or ending. Its picture, read from that file, is at https://wowforever.news/icons/<icon>.png (a name with a space has none). null when the files name none."}, "internal": {"type": "boolean", "description": "true for one of Blizzard's own working records, not meant for players: its name carries a note of theirs such as Deprecated, Test or [PH]. Listings leave these out unless internal=true is asked for; each can still be read by its id."}, "text": {"type": ["null", "string"], "description": "Its description as the game's tooltip words it, for a level 60 character before gear. A ? stands for a number the files do not hold. A talent's is its first rank's; an item's is its own line of description in the tooltip. null when it has none."}, "points": {"type": "integer", "description": "The achievement points it gives; 0 for a statistic and for most of this client's rows."}, "category": {"type": "string", "description": "The category the game files it under (Dungeons and Raids, Quests, Statistics' Deaths …), or null."}, "faction": {"type": ["null", "string"], "description": "Alliance or Horde when only one side can earn it; null for both."}, "reward": {"type": ["null", "string"], "description": "What the game says it rewards (a title, an item), or null."}, "statistic": {"type": "boolean", "description": "true for a counter the game keeps (kills, deaths, quests completed), not an achievement to earn; the client's table holds both."}}}, "refusal": {"type": "object", "required": ["ok", "error"], "properties": {"ok": {"type": "boolean", "enum": [false]}, "error": {"type": "string", "description": "What is wrong, in a sentence."}, "retry_after": {"type": "integer", "description": "With 429 and 503: the seconds to wait, as in Retry-After."}}}}, "responses": {"400": {"description": "The question is refused and told what is wrong: a parameter the address does not take, one given twice or with no value, a value that is not allowed.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/refusal"}}}}, "404": {"description": "No such address, or no such record.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/refusal"}}}}, "429": {"description": "More than 120 requests in a minute from one address.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/refusal"}}}, "headers": {"Retry-After": {"schema": {"type": "integer"}, "description": "The seconds until the next minute starts."}}}, "503": {"description": "Our copy of the game's data is being rebuilt: before the first reading, or for a few minutes after an update of ours that changes how the records are kept. Not to be kept.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/refusal"}}}, "headers": {"Retry-After": {"schema": {"type": "integer"}, "description": "60 seconds."}}}}}}