Files
Emberfall/docs/API.md
T

3.7 KiB
Raw Blame History

API.md

Base path: /api. JSON in, JSON out. Auth via session cookie.

Response envelope

Success: { "ok": true, "data": { ... } } Failure: { "ok": false, "error": { "code": "INSUFFICIENT_ENERGY", "message": "Not enough energy." } }

Status codes

Code Use
200 success
201 created (register, create hero)
400 validation failed (VALIDATION_ERROR)
401 not logged in (UNAUTHENTICATED)
403 logged in but not allowed (FORBIDDEN, BANNED)
404 not found (NOT_FOUND)
409 conflict (USERNAME_TAKEN, HERO_EXISTS, EXPEDITION_ACTIVE)
422 rule violation (INSUFFICIENT_ENERGY, INSUFFICIENT_GOLD, LEVEL_TOO_LOW, NOT_READY)
429 rate limited
500 unexpected (never leak stack traces)

Endpoints

Auth (public unless noted)

Method Path Body Returns
POST /auth/register {username, password} {user:{id,username}} + sets session
POST /auth/login {username, password} {user:{id,username}, hasHero}
POST /auth/logout 🔒 – {}
GET /auth/me 🔒 – {user:{id,username}, hasHero}

Validation: username 3–20 chars [A-Za-z0-9_]; password 8–72 chars. Login failure always returns the same generic message (INVALID_CREDENTIALS) — don't reveal whether the username exists.

Character 🔒

Method Path Body Returns
POST /character {name, class} {character}
GET /character – {character, derived, equipment, energy:{current,max,nextTickInSec}}
POST /character/allocate {str,agi,int,vit} (points to add) {character, derived}
POST /character/rest – heals to full for gold cost (see BALANCE)

Hunting 🔒

Method Path Body Returns
GET /zones – zones with unlocked flag
POST /hunt {zoneId} {result:{won,rounds[],xp,gold,loot[],leveledUp,newLevel}, character}
GET /combat-log?limit=20 – recent fights

Inventory 🔒

Method Path Body Returns
GET /inventory – {items:[{inventoryId,item,quantity,equippedSlot}]}
POST /inventory/equip {inventoryId} {equipment, derived}
POST /inventory/unequip {slot} {equipment, derived}
POST /inventory/use {inventoryId} {character, message}

Shop 🔒

Method Path Body Returns
GET /shop – stock list with prices and canAfford, levelOk
POST /shop/buy {itemId, quantity} (1–99) {gold, inventory}
POST /shop/sell {inventoryId, quantity} {gold, inventory}

Expeditions 🔒

Method Path Body Returns
GET /expeditions – available defs + active one (with remainingSec)
POST /expeditions/start {defId} {expedition}
POST /expeditions/claim – {rewards, character}

Leaderboard & heroes (public read)

Method Path Query Returns
GET /leaderboard `type=level gold
GET /heroes/:name – public profile (name, class, level, kills, equipped item names)

Misc

| GET | /health | – | {ok:true} |

Rules for every route

  1. Validate with zod; on failure → 400 VALIDATION_ERROR with field messages.
  2. Never trust client-supplied ids for ownership: always scope by req.session.userId → character.
  3. Responses never include password_hash or session data.
  4. State-changing endpoints are POST. GET must never modify state.
  5. Return the updated character where relevant so the UI can refresh without a second call.