The game's own trade market, direct:
`` POST eu-trade.naeu.playblackdesert.com/Trademarket/GetMarketPriceInfo POST eu-trade.naeu.playblackdesert.com/Trademarket/GetWorldMarketSubList ``
GetMarketPriceInfo returns 90 daily prices per item, pre-tax, oldest first. GetWorldMarketSubList returns the item's current standing. Its dash-separated fields decode as:
`` mainKey · subKey · minEnhance · basePrice · currentStock · totalTrades · priceMin · priceMax · lastSoldPrice · lastSoldTime ``
priceMin/priceMax are the hard band the game enforces. Verified by decoding against BDOlytics values already on disk: totalTrades matched to within normal drift on every item checked.
Both proxy this same service, and both refuse this build host - arsha's WAF blocks every request after a heavier run (upstream connect timeouts, not 429s), and BDOlytics is unreachable through the sandbox proxy. Going direct removes an intermediary and a rate limit. BDOlytics remains the source for the order book and for the live in-browser pull, which runs on your machine where it is reachable.
The history store is keyed by date, not by index, so re-running months from now grows the window past 90 days rather than overwriting it.
shrddr/workermanjs, the data behind Workerman: exploration.json (nodes and their CP cost), plantzone_drops.json (what each node yields), skills.json, distances_tk2pzk.json (town-to-node distances), r_latest.geojson (region polygons for the basemap), deck_icons.json (the in-game icons on the map), house_craft_inputs.json, item_info.json, loc.json (names).
Thell/bdo-empire formulates this as a mixed-integer program and HiGHS solves it. eu_300cp_v2 was proven optimal, not approximated.
| file | what it holds |
|---|---|
docs/assets/dashboard_data.json | the solved plan and the price model |
docs/assets/item_history.json | 90 days per item, volatility, hard bands, the plan's income band |
docs/assets/price_history.json | one point per day of the plan's own value |
Prices in this build: EU, 2026-08-20. History to 2026-08-20.