BulbaStats

About BulbaStats

BulbaStats is an independent, read-only analytics view of BulbaStore, the Minecraft item exchange. It reads the same public API anyone can call, cross-joins the endpoints, and derives the statistics the API doesn't compute itself. It has no API key, places no orders, and holds no database.

Methodology & caveats

Realized P&L

Computed by weighted-average cost basis over observable market trades. A buy raises the average, a sell realizes the difference against it, and the 4% taker fee is charged into cost or deducted from proceeds. Items obtained in-world — mined, crafted, gifted — never appear as a purchase, so selling them realizes their whole price as profit. Every player page counts those units separately and says so. It measures trading, not wealth creation.

Inventory value

Holdings are valued at the current mid of their variant. Items with no quoted mid are excluded rather than valued at zero, and the count of excluded items is shown, because “we don't know” and “worth nothing” are different claims. On a thin book a mid can move a long way on one order, so treat these as indications.

The house market maker

The BulbaStore account holds roughly 92% of resting orders and is a counterparty to most trades. Leaving it in a ranking drowns out every human trader, so leaderboards exclude it by default and order-flow statistics report it separately. Its cancel rate reflects requoting to track price, not failed trades.

Both sides are counted

One trade produces a taker leg and one maker leg per resting order matched. Per-player volume counts a player's own legs, so summing volume across players exceeds market volume — that's the intended reading of “how much did this account trade”, not a double-count of the market.

Time windows

Windowed figures like “last 7 days” are anchored to the most recent trade in the dataset, not the wall clock. Aggregates are computed over a cached crawl, so a wall-clock window would make the same data yield different numbers as the cache ages. Order age and book staleness do use real time, since those are genuinely live quantities.

Volatility & price change

Volatility is the standard deviation of log returns between consecutive candle closes, deliberately not annualized. Price change returns nothing at all unless a candle old enough to compare against exists, rather than silently comparing to the oldest bucket available and labelling it “24h”.

The fee is deflationary

The 4% taker fee is debited from the buyer and credited to no bank account. Market-wide currency totals therefore shrink as volume grows. This is upstream behaviour and not an artefact of the aggregation.

Slippage curves

Simulated locally against the book as it stands, ignoring the taker fee. A real order also moves the price it is being measured against, so the curve is a floor on cost, not a quote.

Net flow between traders

Direction of currency, not profit. A pair's net flow is the diamonds one account received from the other minus what it paid back; the receiver handed over goods worth it. Taker fees are excluded because they go to the treasury rather than the counterparty, so the figure is strictly what moved between the two accounts.

Stack and shulker prices

Minecraft stack size is a property of the item — 64 for most blocks, 16 for eggs and pearls, 1 for tools — so a per-stack price is a per-row multiplier, not a constant. A shulker box is 27 stacks. Only unit prices scale with the toggle: spread stays a ratio and volume stays a total.

Resting value near mid

An order parked far from mid will not trade, so total resting value flatters a book. The median resting order sits a long way out, and only a small fraction of all resting value falls within 5% of mid — the distance bands on the orders page separate depth you could realistically hit from a market maker's ladder.

Trends, and where they're missing

Stat tiles built from the trade record carry a sparkline and a change against the prior period. The book-structure tiles — two-sided books, median spread — carry neither on purpose: the API exposes the order book only as it stands right now, so there is no history behind them and a trend line would be invented. Changes in a share are given in percentage points, because a share moving from 40% to 43% has risen three points, not 3%.

Data sources

https://webstore.bulbastore.uk/upstream/api/v1

Endpoints read

All public, all unauthenticated

EndpointUsed forCache
GET /listingsItem catalog60s
GET /orderbookQuotes for every listing in one call15s
GET /orderbook/:idDepth, ladder, participants15s
GET /orderbook/:id/viewListing + book + fills in one trip15s
GET /orderbook/:id/candlesPrice history60s
GET /transactions?view=tradesComplete trade history300s
GET /transactions?view=fillsBank movements300s
GET /ordersResting and closed orders900s
GET /players/:usernameProfile, banks, balances60s
GET /treasury*Pools, revenue, distributions300s
GET /commandsBot command reference1h
GET /docs/:slugThis reference1h
WS /api/wsLive trade tapelive

Documented but not deployed

Verified 404 against the live host — no feature depends on them

  • GET /health
  • GET /ledger, /ledger/balance/…, /ledger/audit/…
  • GET /banks/:id

The client treats these as optional: a missing endpoint removes a section rather than failing a page.

Live but undocumented

Found in the official web client, verified unauthenticated

  • GET /treasury
  • GET /treasury/revenue
  • GET /treasury/distributions
  • GET /lending/orders, /lending/loans

These power the Treasury section. Being undocumented, they may change or disappear without notice — that section degrades to a notice if they do.

Efficiency

GET /transactions?view=trades returns one row per taker action with every resting order it matched in a makers[] array. Checked against the fills view, its 3,674 maker legs matched 3,674 isMaker: true rows with zero gaps — so the complete trade record costs a two-page crawl rather than a twenty-page one, and every per-player and per-item statistic on this site is built from it.

Sparklines come from actual fill prices rather than per-listing candle requests, saving roughly 118 requests per market page view. Depth ownership uses one resting-order crawl instead of 118 individual book fetches. The read tier allows 120 requests a minute per IP; crawls are capped, fan-out is bounded, and everything is cached server-side, so a page view usually costs the upstream API nothing at all.

Upstream reference

Loading…