API Reference
API Reference
Section titled “API Reference”The web dashboard uses these endpoints. They are stable for third-party integrations but not formally versioned yet – expect additive changes.
Base URL and WebSocket URL
Section titled “Base URL and WebSocket URL”Base URL: http://<host>:<port>WebSocket URL: ws://<host>:<port + 1>Authentication
Section titled “Authentication”All /api/v1/ endpoints except /api/v1/auth/link and /api/v1/health require a JWT in the Authorization header:
Authorization: Bearer <jwt>Obtain a JWT by exchanging a /bazaar link code:
POST /api/v1/auth/linkContent-Type: application/json
{ "code": "ABC123" }Returns:
{ "token": "eyJ...", "expiresAt": 1740000000000, "user": { "uuid": "...", "name": "...", "isAdmin": false }}HTTP Endpoints
Section titled “HTTP Endpoints”| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/auth/link | Exchange link code for JWT. |
| GET | /api/v1/auth/me | Current user info, including admin flag. |
Listings
Section titled “Listings”| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/listings | Paginated active listings. Query: market (gts|ah), channel, sort, page, pageSize, search. |
| GET | /api/v1/listings/{id} | Listing detail. |
| GET | /api/v1/listings/{id}/history | Transaction history + sparkline for this listing’s identity key. |
| GET | /api/v1/listings/{id}/similar | Similar listings (same identity key). |
| POST | /api/v1/listings/{id}/buy | Buy it now. Body: { "confirm": true }. |
| POST | /api/v1/listings/{id}/bid | Place a bid. Body: { "amount": 1500 }. |
Buy Orders
Section titled “Buy Orders”| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/orders | Paginated active buy orders. |
| POST | /api/v1/orders | Create a buy order. Body: { "identityKey": "...", "price": 1500, "quantity": 1 }. |
Player
Section titled “Player”| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/players/{uuid}/profile | Public profile. |
| GET | /api/v1/me/listings | Your active listings. |
| GET | /api/v1/me/orders | Your active buy orders. |
| GET | /api/v1/me/collection | Your unclaimed collection entries. |
| GET | /api/v1/me/transactions | Your transaction history. |
| POST | /api/v1/me/collection/{id}/claim | Claim a collection entry. |
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/stats/overview | Global stats (active listings, active orders, freeze state, sync mode). |
| GET | /api/v1/stats/summary/{key} | Summary for an identity key (avg price, volume, high/low). |
| GET | /api/v1/stats/history/{key} | Transaction history for an identity key. |
| GET | /api/v1/stats/trending | Top items by 24h volume. |
| GET | /api/v1/stats/leaderboard | Top sellers/buyers. |
| GET | /api/v1/stats/distribution/{key} | Price distribution histogram. |
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/theme | Resolved theme JSON for the current preset selected in web-theme.conf. |
| GET | /api/v1/theme/presets | Available preset names. |
| GET | /api/v1/theme/css | Resolved CSS overrides. |
Channels
Section titled “Channels”| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/channels | List channels visible to the caller. |
| GET | /api/v1/channels/{id}/listings | Listings filtered to that channel. |
Admin (requires bazaar.admin)
Section titled “Admin (requires bazaar.admin)”| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/admin/alerts | Security alerts. |
| GET | /api/v1/admin/economy | Economy-wide stats. |
| GET | /api/v1/admin/inspect/{uuid} | Full player inspection. |
| GET | /api/v1/admin/players/search?q=... | Autocomplete by name. |
| POST | /api/v1/admin/freeze | { "frozen": true | false }. |
| POST | /api/v1/admin/remove/{id} | Remove a listing or buy order. |
| POST | /api/v1/admin/purge | Purge all expired listings. |
Health
Section titled “Health”| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/health | { "status": "ok" } if the server is up. No auth. |
WebSocket
Section titled “WebSocket”Connect to ws://<host>:<port+1>.
Authenticating
Section titled “Authenticating”Send:
{ "type": "auth", "token": "<jwt>" }Notifications only arrive after successful auth. Unauthenticated sockets can still subscribe to public channels (market events), but not player-specific channels.
Subscribing
Section titled “Subscribing”{ "type": "subscribe", "channels": ["market", "notifications"] }{ "type": "unsubscribe", "channels": ["market"] }Channels
Section titled “Channels”| Channel | Who receives it | Payload |
|---|---|---|
market | anyone | New listings, bids, sales, cancellations. |
channel:<id> | anyone with channel browse permission | Same as market but filtered. |
notifications | authed user | Player-scoped events: outbid, sold, won, collection ready. |
admin.alerts | admins only | Security alerts, system events. |
Event Payload
Section titled “Event Payload”All events use a consistent envelope:
{ "type": "listing.created", "timestamp": 1740000000000, "payload": { ... }}Event types currently emitted:
listing.createdlisting.updatedlisting.cancelledlisting.expiredlisting.soldbid.placedbid.outbidorder.createdorder.filledcollection.readynotification.push(for thenotificationschannel)
Rate Limits
Section titled “Rate Limits”The API enforces the same per-minute limits as in-game actions (see limits.conf). A rejected request returns 429 Too Many Requests with a Retry-After header.
Pagination
Section titled “Pagination”Endpoints that return lists accept page (0-based) and pageSize (default 24, max 100). Responses wrap:
{ "items": [ ... ], "page": 0, "pageSize": 24, "total": 183}