Goblin Exchange API
Let your AI agent read this site's data: the WoW Forever auction house market, the advisor's flip/buy/craft brief, the item index with sources, the talent trees, and your own characters, upgrades and talent builds.
The API only serves what this site already holds. It never talks to Blizzard and cannot log in to the game or the Battle.net API for you. Prices are as fresh as the site (about hourly). Agents can read /llms.txt or /api/openapi.json to set themselves up.
Your keys
Loading...
Two kinds of routes
public Market, advisor, items and talents are public static JSON. No key needed, and they don't count against any limit.
key Your characters, upgrades, talent builds, item search and import need a key: Authorization: Bearer gex_.... A key only ever sees its own Battle.net account's data.
export GEX_KEY=gex_your_key_here
curl -s -H "Authorization: Bearer $GEX_KEY" https://heyfatguy.com/api/v1/me
Public data (no key)
| Route | What |
|---|---|
GET /api/v1/market | Every item on the AH right now: ask, fair price, market value, quantity, sold per day, 24h change, flip math, BUY/SELL signal. Also scans, last (unix time of the newest snapshot), cut (AH cut, 0.05). About 1.5 MB. |
GET /api/v1/item/{id} | One item's price history (history: ask, median, fair, quantity per snapshot) and order book (book). 404 = no price history in this house. |
GET /api/v1/advisor | The advisor brief: brief.headline, brief.market_read, brief.picks (action, item_id, why, risk, size_gold, confidence), brief.avoid, plus the scored lists in picks (flip, craft, vendor, sell, momentum). |
GET /api/v1/crafts | Recipes priced against the live AH: reagent cost, sale value, profit. |
GET /api/v1/houses | Auction houses and the default one. Other houses' files live at /data/{slug}/market.json. |
GET /api/v1/items | The full item index (about 11k items, 2.7 MB): id, name, quality q, item level, required level lvl, slots, stats, weapon damage. Prefer the search route below. |
GET /api/v1/items/sources | Where items come from: quest, dungeon, raid, drop, vendor, crafted, other, each with provenance p. |
GET /api/v1/items/meta | Stat names, the Planner's role weights, slot ids. |
GET /api/v1/talents | Talent index: classes, points per level. |
GET /api/v1/talents/{class} | One class's trait trees (warrior, paladin, hunter, rogue, priest, shaman, mage, warlock, druid): nodes, ranks, spells, prerequisites. |
curl -s https://heyfatguy.com/api/v1/advisor | jq '.brief.picks[] | {action, name, size_gold, confidence}'
curl -s https://heyfatguy.com/api/v1/market | jq '[.items[] | select(.signal=="BUY")] | sort_by(-.flip.profit) | .[:10] | map({id, name, ask, mv, sold_day})'
curl -s https://heyfatguy.com/api/v1/item/2589 | jq '.history[-1]'
curl -s https://heyfatguy.com/api/v1/talents/paladin | jq 'keys'
Your data and search (key)
| Route | What |
|---|---|
GET /api/v1/me | Your key: account id, BattleTag, scopes, limits, usage today. |
GET /api/v1/characters | Your imported characters, newest snapshot first: guid, name, level, class, race, faction, realm, guild, gold (copper), spec, time. |
GET /api/v1/characters/{guid} | One full snapshot from the GoblinExchange addon: gear worn and in bags (item ids, links, stats), character sheet stats, talents, completed quests. |
GET /api/v1/upgrades | The AH upgrade finder's results per character (?guid= for one): by_role (ret, prot, holy) lists of AH items that beat what's worn, with score gain and gold per point, and note (the advisor's text, buy_first, spend_gold). |
GET /api/v1/talent-templates | Your saved talent builds (?class=paladin to filter), each with a share link. |
GET /api/v1/items/search | Search the item index on the server (the Planner's search). Params below. |
POST /api/v1/import | Push character snapshots: body {"chars": {"<guid>": {...}}}, the GoblinExchangeDB.chars table as JSON, 1 MB max. Needs a key with the import scope. |
items/search params
| Param | Meaning |
|---|---|
q | Name contains this (case-insensitive), or an exact item id. |
slot | Equip slot id: 1 Head, 2 Neck, 3 Shoulder, 5 Chest, 6 Waist, 7 Legs, 8 Feet, 9 Wrist, 10 Hands, 11/12 Finger, 13/14 Trinket, 15 Back, 16 Main Hand, 17 Off Hand, 18 Relic. |
min, max | Required level range. |
quality | Minimum quality: 0 poor, 1 common, 2 uncommon, 3 rare, 4 epic, 5 legendary. |
class | Drop items restricted to other classes, and quests for other classes. For paladin it also checks armor and weapon proficiency (plate from level 40; level defaults to max or 60). Other classes: proficiency is not checked. |
role | ret, prot or holy: adds score with the Planner's Paladin weights and sorts by it. |
onAh=1 | Only items listed on the AH right now. |
obtain | any (default): items with any allowed source. ah: on the AH, or a quest reward when quests are on. all: every item, even with no known source. |
quests, dungeons, raids | 0 or 1. When any source param is given, an item must have an allowed source; a dungeon or raid drop stops counting when its box is 0, but the item still shows if it is also on the AH, a vendor, a world drop or a quest. |
faction, race | H or A, and a race id: quest rewards for the other side are not counted. |
sort | score (default with a role), ilvl (default), lvl, price (cheapest first). |
limit, offset | Page size (default 50, max 200) and offset. |
curl -s -H "Authorization: Bearer $GEX_KEY" https://heyfatguy.com/api/v1/characters
curl -s -H "Authorization: Bearer $GEX_KEY" "https://heyfatguy.com/api/v1/upgrades" | jq '.characters[] | .note.text'
curl -s -H "Authorization: Bearer $GEX_KEY" "https://heyfatguy.com/api/v1/items/search?slot=1&min=20&max=30&class=paladin&role=ret&raids=0&limit=10"
curl -s -H "Authorization: Bearer $GEX_KEY" "https://heyfatguy.com/api/v1/items/search?q=lion&onAh=1&sort=price"
curl -s -X POST -H "Authorization: Bearer $GEX_KEY" -H "Content-Type: application/json" \
--data @chars.json https://heyfatguy.com/api/v1/import
Limits
- Per key: 30 requests a minute and 1,000 a day (UTC day). All keys together: 2,000 a day. Over a limit you get
429with aRetry-Afterheader in seconds. Responses carryX-RateLimit-Remaining-MinuteandX-RateLimit-Remaining-Day. - Up to 5 keys per account. Public routes are static files with no limit, but cache them: the data changes about hourly (see
lastin the market). - Why so low: the site runs on Netlify's free plan, 125,000 function runs a month for everything (the site's own pages spend some) and 100 GB of bandwidth. 2,000 key calls a day is about 60,000 a month, which leaves room for the site.
Errors and CORS
Every error on a key route is JSON: {"error": {"status": 401, "code": "unauthorized", "message": "..."}}. Codes: 400 bad_request, 401 unauthorized (no key, unknown or revoked key), 403 forbidden (missing scope, or the account left the allowlist), 404 not_found, 405 method_not_allowed, 413 too_large, 415 unsupported_media_type, 429 rate_limited, 502 upstream (site data missing). Static public routes give a plain 404 for a missing item.
CORS is open (Access-Control-Allow-Origin: *) on every /api/v1 route and the public data, so a browser-based agent can call it. Keys travel in the Authorization header only, never in the URL and never with cookies.
Getting a key
- Log in at heyfatguy.com with Battle.net. If you're not on the friends list yet, the header shows your account id: send it to Kewk.
- Once you're added, come back here and press Create key. Tick import only if your agent should push character snapshots.
- Copy the key right away; it's shown once. The site stores only a hash.
- Give it to your agent as
Authorization: Bearer gex_.... Revoke it here any time; it stops working on the next request.
Fan site, not affiliated with or endorsed by Blizzard Entertainment. World of Warcraft is a trademark of Blizzard Entertainment.