⚙ Builder API

REST tooling for external builders on top of the Monsterion MMO: create quests with real in-game rewards and read the live player marketplace — listings, prices, transactions. JSON over HTTPS, versioned under /api/v1/.

Base URL & authentication

All endpoints live under the game server:

https://<worker-host>/api/v1/

Every request must carry an issued builder key (keys start with mbk_):

Authorization: Bearer mbk_xxxxxxxxxxxxxxxxxxxxxxxx
  • 10 alpha keys are minted, each with a label (builder-01builder-10). Ask the team for yours.
  • Keys are verified by SHA-256 hash — the server never stores plaintext. Lose it, and a new one must be issued.
  • Everything you create is stamped with your label: only you can update or retire your own quests.
  • Missing/invalid key → 401 {"error":"unauthorized"}.

Quests

Builder quests appear in-game at the Tools Marketplace — the Antikythera mechanism outside the village tree ring. Players accept them there, watch objectives tick, and claim your reward.

GET /api/v1/quests

List all active builder quests (max 200, newest first).

curl -H "Authorization: Bearer $KEY" https://<host>/api/v1/quests
# → { "quests": [ { "id", "title", "lore", "objectives", "reward", "created" }, … ] }

POST /api/v1/quests

Create a quest — or update one of yours (same id, same key). Omitting id generates one.

curl -X POST https://<host>/api/v1/quests \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{
    "id": "herbalist-trial",
    "title": "The Herbalist Trial",
    "lore": "Gather for the village apothecary before the frost.",
    "objectives": [
      { "type": "harvest", "n": 200 },
      { "type": "craft",   "n": 5 }
    ],
    "reward": {
      "slot": "trinket", "base": "charm", "rarity": "epic",
      "name": "Apothecary Charm",
      "flavor": "Smells faintly of every herb at once.",
      "affixes": [ { "stat": "xp_gain", "val": 12 } ]
    }
  }'
# → { "ok": true, "id": "herbalist-trial", "builder": "builder-03" }

Request schema

fieldtyperules
idstring?optional; ≤48 chars; stable id = updatable quest
titlestringrequired, ≤80 chars
lorestringrequired, ≤1000 chars — shown to players
objectivesarray1–8 of {type, n}; n 1…100000
rewardobjectsee the reward schema below

Objective types

Objectives bind to the game's lifetime activity counters; progress counts from the moment a player accepts your quest.

typecounts
harvestresources gathered (wood, ore, herbs, digs…)
craftitems / consumables crafted
trademarketplace trades completed
missionOlga missions finished
killboss kills (tracking expanding)

Reward schema

fieldtyperules
slotstringweapon | armor | trinket | mount | consumable
basestringdecides the 3D model: item_<base>.glb on the CDN. Reuse existing bases (charm, idol, ring, blade, plate, greataxe, …) or ship a new model with the team.
raritystringcommonmythic. Alpha edition caps apply: uncommon 500 · rare 250 · epic 100 · legendary 25 · mythic 8 — server-numbered like every item.
namestringrequired, ≤60 chars
flavorstring?italic lore line on the item
affixesarray?≤6 of {stat, val} — stats: atk, def, hp, spd, crit_chance, lifesteal, magic_find, xp_gain

GET /api/v1/quests/:id

Fetch one quest (active or retired).

curl -H "Authorization: Bearer $KEY" https://<host>/api/v1/quests/herbalist-trial
# → { "quest": { … } }   |   404 { "error": "not found" }

DELETE /api/v1/quests/:id

Retire one of your quests (soft delete — it disappears from the game; players mid-quest keep their progress and the claim stays honored).

curl -X DELETE -H "Authorization: Bearer $KEY" https://<host>/api/v1/quests/herbalist-trial
# → { "ok": true }

Marketplace (read)

Live data from the in-game gold marketplace — the same server-settled trades players see.

GET /api/v1/market/listings

Listings by status: ?status=active (default) or sold. Max 300, newest first.

curl -H "Authorization: Bearer $KEY" "https://<host>/api/v1/market/listings?status=active"
# → { "listings": [ { "id": 42, "seller_name": "Rawen", "price": 1200,
#       "status": "active", "created": 1783100000000,
#       "item": { "slot":"weapon", "base":"blade", "rarity":"epic", … } }, … ] }

GET /api/v1/market/prices

Recent sale prices grouped by item type (base:rarity) — the exact data behind the in-game price charts. Up to the last 500 sales.

curl -H "Authorization: Bearer $KEY" https://<host>/api/v1/market/prices
# → { "prices": { "blade:epic": [ { "price": 1150, "at": 1783099000000 }, … ] } }

GET /api/v1/market/transactions

Completed sales, newest first. ?limit= up to 500 (default 100).

curl -H "Authorization: Bearer $KEY" "https://<host>/api/v1/market/transactions?limit=50"
# → { "transactions": [ { "id", "seller_name", "price", "created", "item": { … } }, … ] }

Models — publish your own GLBs

Bring your own art: publish a textured .glb, we validate + host it, and the engine auto-rigs and animates it at load (runtime soft-skin rig: walk, pen-wander, ride, fly for winged models, hunt/chase). Use it in rewards via model_url.

POST /api/v1/models?name=<name>

Raw binary body. Name: 3–48 chars of [A-Za-z0-9_-]. Re-POST the same name (same key) to update.

curl -X POST "https://<host>/api/v1/models?name=crystal_stag" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/octet-stream" \
  --data-binary @crystal_stag.glb

Validation: binary .glb magic · max 8 MB · textures embedded · at least one mesh. The response includes the public url and the animation set the engine will apply.

GET /api/v1/models

List your published models (name, bytes, created).

GET /api/v1/models/:name

Public (no key) — this is the URL game clients stream. Serves model/gltf-binary, cached 1 h.

Rewards with your model

"reward": { "slot": "mount", "base": "custom", "rarity": "epic",
            "name": "Crystal Stag", "model_url": "/api/v1/models/crystal_stag" }

Errors

statusbodymeaning
400{"error":"…"}validation failed — the message names the exact field and rule
401{"error":"unauthorized…"}missing or unknown builder key
404{"error":"not found"} / unknown endpointbad id or path
503{"error":"no database configured"}server misconfiguration — tell the team
500{"error":"…"}unexpected — retry once, then report

How it feels in-game

  1. Your quest appears at the ⚙ Tools Marketplace — the turning bronze Antikythera mechanism past the village tree ring.
  2. A player presses Accept: their activity counters snapshot, and your objectives count from zero for them.
  3. Objectives tick live on the quest card (✔ Harvest: 200/200).
  4. Claim reward grants your item for real: it lands in the bag, wears on the body, shows in the character sheet, can be socketed, traded on the gold market — and minted as an NFT at the Blacksmith.

Roadmap

Per-builder key self-service · write-side marketplace ops with player-consent tokens · custom quest locations & NPCs · webhook notifications on quest completion & sales.