Recommended API base: https://client.grudge-studio.com
Game-data SSOT (direct): https://grudge-api-production-0d46.up.railway.app
ObjectStore JSON (direct): https://objectstore.grudge-studio.com/api/v1
info catalogs: https://info.grudge-studio.com/api/v1
CDN binaries: https://assets.grudge-studio.com
Deprecated: https://api.grudge-studio.com — do not use for new wiring.
Local: http://localhost:5000 (when GrudgeBuilder is running).
Non-public routes need Authorization: Bearer <JWT> or local X-Admin-Password.
Validate with grudge-dev doctor (JSON only — no HTML SPA leaks).
Full host map: Systems & APIs · ONE TRUTH · Databases · sharing · backups.
| Check | URL | Notes |
|---|---|---|
| Grudge ID | https://id.grudge-studio.com/api/health |
Auth gateway |
| Railway | https://grudge-api-production-0d46.up.railway.app/api/health |
Game data |
| Auth me | {apiBase}/api/auth/me |
401 unauthenticated is OK |
| ObjectStore items | {apiBase}/api/objectstore/v1/master-items.json |
Via client rewrites |
| ObjectStore direct | https://objectstore.grudge-studio.com/api/v1/master-items.json |
Direct catalog |
| CDN root | https://assets.grudge-studio.com |
HEAD |
| Legion | https://ai.grudge-studio.com/health |
Fleet AI |
| Forge | https://forge.grudge-studio.com/ |
Editor SPA |
| Coder | https://coder.grudge-studio.com/api/health |
IDE gateway when backend up |
| Open | https://open.grudge-studio.com/ |
Launcher |
| Multiverse SPA | https://grudge-multiverse.vercel.app/ |
Bermuda MP play |
| Multiverse room | https://grudge-multiverse-room-production.up.railway.app/api/health |
Rooms service; WS /api/mv |
apiBase = https://client.grudge-studio.com in production.
curl -s https://grudge-multiverse-room-production.up.railway.app/api/health
# {"status":"ok","service":"grudge-multiverse-room","ws":["/api/mv"],…}
Do not call Multiverse multiplayer on Carrier /api/carrier or gameopen Railway.
Routes used by Dev Tool Assets, CLI upload-pack, and agents.
Implementation often via fleet rewrites + ObjectStore Worker / R2.
GET /api/objectstore/listPaginated listing under a prefix.
Query: prefix (required), cursor, limit (default 100, max 1000).
curl -H "Authorization: Bearer $T" \
"https://client.grudge-studio.com/api/objectstore/list?prefix=prod/gltf/&limit=50"
Response (shape):
{
"items": [
{
"name": "prod/gltf/misc/hero.glb",
"size": 12345,
"contentType": "model/gltf-binary",
"updated": "2026-07-29T05:30:00Z",
"md5Hash": "..."
}
],
"folders": ["prod/gltf/races/"],
"nextCursor": "...",
"prefix": "prod/gltf/",
"count": 50
}
GET /api/objectstore/searchServer-side search (Assets tab: type >query).
Query: q, category, pack, limit (default 200, max 1000).
curl -H "Authorization: Bearer $T" \
"https://client.grudge-studio.com/api/objectstore/search?q=helmet&limit=50"
Response: { "count": N, "items": [ … ] }
POST /api/objectstore/upload-urlMint a presigned PUT for R2 / storage.
Body:
{
"path": "prod/gltf/misc/hero.glb",
"contentType": "model/gltf-binary",
"size": 12345,
"sha256": "...",
"allowOverwrite": false
}
Response: { "uploadURL", "objectPath", "bucketPath", "ttlSeconds", "uploadId", "echo" }
Errors: 400 missing path · 403 prefix / user mismatch · 409 exists (retry with allowOverwrite: true).
POST /api/objectstore/manifest (admin)Write pack manifest.json.
{
"packId": "classic64",
"version": "0.6",
"meta": { "license": "CC0", "author": "…" },
"entries": []
}
GET /api/objectstore/asset/<objectPath>?format=json: metadata + signed URL + public CDN URL.curl -L -H "Authorization: Bearer $T" \
"https://client.grudge-studio.com/api/objectstore/asset/prod/gltf/misc/hero.glb?format=json"
Public CDN equivalent: https://assets.grudge-studio.com/prod/gltf/misc/hero.glb
Prefer CDN keys for binaries; catalogs for game data:
https://objectstore.grudge-studio.com/api/v1/master-items.json
https://objectstore.grudge-studio.com/api/v1/master-recipes.json
https://info.grudge-studio.com/api/v1/… # live definitions when published
Dev Tool Store tab loads fleet categories from these catalogs.
Mounted by GrudgeBuilder / game-data; also available from Dev Tool UUID tab (src/shared/grudgeUUID.ts SSOT).
| Method | Path | Body / notes |
|---|---|---|
| GET | /api/uuid/test |
Sanity sample |
| POST | /api/uuid/generate |
{ slot, tier, itemId } → { uuid } |
| GET | /api/uuid/slots |
Slot-code map |
| POST | /api/uuid/apply-to-items |
Admin batch |
Format: SLOT-TIER-ITEMID-TIMESTAMP-COUNTER — see Grudge UUID.
Canonical browser login:
https://id.grudge-studio.com/login?redirect_uri=<origin>
Session / me:
curl -H "Authorization: Bearer $T" \
"https://client.grudge-studio.com/api/auth/me"
curl -X POST "https://ai.grudge-studio.com/v1/chat" \
-H "Authorization: Bearer $GRUDGE_AI_KEY" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"…"}],"agent":"general"}'
Health: GET https://ai.grudge-studio.com/health
Not the same product as Coder AI hub worker (GrudachainCode/workers/ai-hub).
Renderer talks only via window.grudge / preload. Major groups:
| Group | Purpose |
|---|---|
os.list / os.search / os.registerAsset |
ObjectStore / R2 |
viewer.open |
Always-on-top Asset Viewer |
forge.* |
Local tools / open remote CDN into local tools |
coder.launch / status |
Local Coder PTY |
preview.* |
HTML open helpers |
legion.* |
Fleet Legion chat |
skeleton.* |
Extract / T-pose / libraries |
ingest.* / upload |
Convert + push packs |
connectivity.probe |
ONE TRUTH score |
Channel names: src/shared/ipc.ts.
grudge-convert (SI scale, Draco/Meshopt, WebP) before R2.assets.grudge-studio.com/...).