MarketDB API

From MuhRO
Revision as of 05:54, 21 October 2026 by Muhbot (talk | contribs) (Use normal Flux key management and clarify the API-only main database isolation.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

MuhRO Web API

The MuhRO Web API serves JSON snapshots from the control panel. There are three parts:

  • MarketDB API: vending, buying and sales trend data. Snapshots are refreshed about every 5 minutes.
  • Game DB API: item and monster data as shown on the item and monster pages, including drops, drop chances, NPC shops, spawns and item groups. Snapshots are rebuilt when the game database is updated, which is about once a week.
  • Private Account API: your own characters, inventories, carts, account/master storages and vending/buying shops. Requires a scoped private key. Background snapshots refresh every minute.

All three parts serve snapshots without querying the game database on API requests. Public MarketDB and Game DB responses support cache validation with ETag and Cache-Control. Private responses require authorization on every request and use Cache-Control: private, no-store.

Base URL

https://flux.muhro.eu/?module=<module>&action=<action>[&parameters]

All endpoints use the query form. Public MarketDB and Game DB endpoints currently do not require a key. The Private Account API requires an Authorization: Bearer or X-API-Key header and rejects keys in URLs. Use the canonical https://flux.muhro.eu/ address directly to avoid redirects when sending credentials.

MarketDB API

Endpoint

https://flux.muhro.eu/?module=marketdb&action=api&name=<dataset>

Query Parameters

Parameter Required Description
name Yes Dataset to fetch.
key No Currently not used.

Available Datasets

Dataset Description Notes
vendings Current vendor shop list. Shop-level snapshot.
v_vending Items currently for sale. Full rows from the vending cache view.
v_buying Items currently being bought. Full rows from the buying cache view.
buyingstores Current buying shop list. Shop-level snapshot.
vending_trend_daily Full daily sales trend dataset. Includes all available day buckets and items.
vending_trend_hourly Full hourly sales trend dataset. Includes all available hour buckets and items.
vending_last_sales Latest sales log snapshot. Currently limited to 1000 rows.
vending_trend_daily_latest Rolling summary for the last 24 hours. Ordered by sales_count descending.
vending_trend_hourly_latest Rolling summary for the last 60 minutes. Ordered by sales_count descending.
vending_last_sales_latest Latest sales feed. Currently the same 1000-row payload as vending_last_sales.
meta Snapshot metadata. Includes generated_at and server.

Example Requests

https://flux.muhro.eu/?module=marketdb&action=api&name=vendings
https://flux.muhro.eu/?module=marketdb&action=api&name=v_vending
https://flux.muhro.eu/?module=marketdb&action=api&name=v_buying
https://flux.muhro.eu/?module=marketdb&action=api&name=buyingstores
https://flux.muhro.eu/?module=marketdb&action=api&name=vending_trend_daily_latest
https://flux.muhro.eu/?module=marketdb&action=api&name=vending_trend_hourly_latest
https://flux.muhro.eu/?module=marketdb&action=api&name=vending_last_sales_latest

Game DB API

The Game DB API exposes the same item and monster data as the control panel item and monster pages. Drop chances and exp values are already adjusted with the server rates, so the numbers match what the web pages show.

Endpoints

Endpoint Description
?module=api&action=itemdata Full item list. Returns {generated_at, count, items: [...]} with compact rows.
?module=api&action=itemdata&id=<item id> One item with all details (see below).
?module=api&action=monsterdata Full monster list. Returns {generated_at, count, monsters: [...]} with compact rows.
?module=api&action=monsterdata&id=<monster id> One monster with all details (see below).
?module=api&action=itemgroups All item groups (boxes): {groups: {<group name>: {containers: [...], contents: [...]}}}.
?module=api&action=gamedbmeta Snapshot metadata: generated_at, server, item and monster counts, exp_rates, drop_rates. Poll this to detect a new snapshot.

Item list row

id, aegis_name, name, type, subtype, price_buy, price_sell, weight, attack, magic_attack, defense, range, slots, refineable, view, equip_locations[], custom

Item detail

Field Description
Base fields Everything from the list row plus alias_name, gender, weapon_level, armor_level, equip_level_min, equip_level_max, gradable, jobs[], classes[], trade_restrictions[], flags[], nouse[], delay, stack, script, equip_script, unequip_script.
description, description_info Item description as shown in the client and the extra info block from the control panel.
item_group, group_contents[] For boxes: the group name and its contents (item_id, name, amount, rate, subgroup, algorithm).
contained_in[] Boxes that can give this item (item_id, name, aegis_name, group).
npc_shops[] NPC shops that sell the item: npc_id, npc_name, shop_type, map, x, y, price, currency, quantity (market shops) and cost_items[] (barter shops).
barter_ingredient_for[] Barter shops that take the item as payment, with reward_item_id and reward_item_name.
itemshop_cost Control panel item shop price, if any.
drops[] Monsters that drop the item, sorted by chance. See drop entries below.
images icon and collection image URLs.

Monster list row

id, sprite, name, name_japanese, level, hp, size, race, element, element_level, base_exp, job_exp, mvp_exp, mvp, custom

Monster detail

Field Description
Base fields Everything from the list row plus sp, attack, attack2, defense, magic_defense, resistance, magic_resistance, str, agi, vit, int, dex, luk, attack_range, skill_range, chase_range, race_groups[], walk_speed, attack_delay, attack_motion, damage_motion, damage_taken, ai, class, boss, modes[].
base_exp_rated, job_exp_rated, mvp_exp_rated Exp with the server exp rates applied. The unsuffixed fields are the raw database values.
drops[] The normal drop slots: slot, item_id, aegis_name, name, item_type, rate_raw, rate, steal, option, index.
mvp_drops[] The MVP reward slots, same fields. rate already accounts for the earlier slots being rolled first.
extra_drops[] Additional drops from the server drop table (item_id, name, rate_raw, rate).
map_drops[] Map specific drops (map, item_id, name, rate_raw, rate).
skills[] Monster skills with cast conditions, if the server publishes them.
spawns[] Spawn points: map, x, y, respawn_min, respawn_max, quantity.
image Sprite image URL.

Drop entries on items

Each entry in an item's drops[] has monster_id, monster_name, monster_level, monster_race, monster_element, monster_element_level, boss, type, rate_raw, rate, steal and, for map drops, map.

type Meaning
normal One of the ten regular drop slots.
mvp MVP reward slot.
extra Additional server drop.
map Map specific drop on the map named in map.

Drop chances

  • rate is the chance in percent with the server drop rates applied, the same number the item and monster pages show. Cards are fixed at 0.20% (0.04% from bosses).
  • rate_raw is the untouched database value: 1/100 percent for normal, MVP and extra drops and 1/1000 percent for map drops.
  • The rates used are published in gamedbmeta as drop_rates and exp_rates.
  • Drops whose item is not in the item database have item_id set to null.

Example Requests

https://flux.muhro.eu/?module=api&action=itemdata&id=501
https://flux.muhro.eu/?module=api&action=monsterdata&id=1002
https://flux.muhro.eu/?module=api&action=itemdata
https://flux.muhro.eu/?module=api&action=monsterdata
https://flux.muhro.eu/?module=api&action=itemgroups
https://flux.muhro.eu/?module=api&action=gamedbmeta

Example drop entry from a monster:

{"slot":1,"item_id":909,"aegis_name":"Jellopy","name":"Jellopy","item_type":"Etc",
 "rate_raw":7000,"rate":93.37,"steal":true,"option":null,"index":0}

Private Account API

The Private Account API is available on LIVE. It gives a tool read access to the data owned by the master account that created its key. It cannot change game data or access another owner's data.

Create a private key

  1. Open Private API keys or follow the Private API keys link on your master account page.
  2. Use your normal Flux login. If you are already signed in, no separate API login is needed.
  3. Enter a label, select the required read scopes and choose an expiry of 7, 30, 90 or 365 days.
  4. Copy the key immediately. The full key is shown only once.
  5. Allow up to one minute for the first background refresh before requesting data.

You can have up to ten active keys. Revoke a key in the same manager when a tool no longer needs access. Revocation takes effect for subsequent requests immediately. Keep keys out of URLs, logs, public websites and distributed application binaries. The normal Flux key manager can revoke keys during a replica outage.

Endpoint and authentication

GET https://flux.muhro.eu/?module=api&action=private&name=<dataset>
Authorization: Bearer YOUR_PRIVATE_KEY

Alternatively send X-API-Key: YOUR_PRIVATE_KEY. Send keys only in headers over HTTPS. A conflicting pair of authentication headers is rejected. The key and token query parameters are rejected.

Example with the key already set in an environment variable:

curl --header "Authorization: Bearer $MUHRO_PRIVATE_KEY" \
  'https://flux.muhro.eu/?module=api&action=private&name=inventories'

Datasets and scopes

The name parameter also names the read scope required on the key.

name / scope Complete dataset
characters Current owned characters with account IDs, levels, saved zeny and online status.
inventories All inventory item instances on owned characters.
carts All cart item instances on owned characters.
storages All owned account and master storage items. Guild storage is excluded.
shops All owned vending and buying shops with nested item listings.

Deleted characters are excluded. Item rows use nameid for the item type; nested shop listings use item_id. Item-instance details include amount, equipment flags, identification, refine, cards, random options, enchant grade, binding, expiry and unique ID where applicable. Use the public Game DB API to resolve item names and descriptions.

Complete responses

Every successful response contains the entire matching dataset. There is no pagination, continuation token or silent truncation. Do not send page or page_size; they are rejected. A resource limit causes an unavailable response rather than a partial dataset.

Field Meaning
dataset Dataset name.
generated_at Snapshot generation time in UTC.
expires_at Snapshot expiry time in UTC.
filters Applied filters, or an empty object when none were supplied.
count Number of returned rows after filtering.
data Array containing all matching rows. Each shop row contains an items array.

Example response with fictional character data:

{
  "dataset": "characters",
  "generated_at": "2026-10-21T08:00:00Z",
  "expires_at": "2026-10-21T08:02:00Z",
  "filters": {},
  "count": 1,
  "data": [
    {
      "char_id": "12345", "account_id": "2000001", "char_num": "0",
      "name": "Example Merchant", "class": "5", "base_level": "100",
      "job_level": "50", "zeny": "100000", "online": "0"
    }
  ]
}

Numeric database fields are returned as strings. In particular preserve zeny, prices and item unique IDs as strings or use an integer type that can represent their full range. JavaScript Number cannot represent every possible value exactly.

Optional filters

Omit filters to receive the full dataset. Filters combine with AND and only narrow the owner's cached data. Unknown or inapplicable filters return 400. Filters do not run database queries or trigger a refresh.

Flag Applies to Meaning
account_id All datasets Exact game account ID. Excludes master storage rows because those belong to the master account.
char_id characters, inventories, carts, shops Exact character ID.
item_id inventories, carts, storages, shops Exact item type.
equipped=0 or equipped=1 inventories, carts, storages No equipment flags or any equipment flag.
bound=0 or bound=1 inventories, carts, storages Unbound or any binding type.
identified=0 or identified=1 inventories, carts, storages Unidentified or identified.
min_refine, max_refine inventories, carts, storages Inclusive refine range.
storage_type=account or storage_type=master storages Account or master storage.
storage_name storages Exact storage name returned in the data. URL-encode spaces and other special characters.
shop_type=vending or shop_type=buying shops Vending or buying shops.

For shops, item_id filters the nested listings and removes shops with no matching item. Other shop filters preserve every listing in each matching shop.

Examples below still require an authentication header:

https://flux.muhro.eu/?module=api&action=private&name=inventories&char_id=12345&equipped=1
https://flux.muhro.eu/?module=api&action=private&name=inventories&min_refine=10&bound=0
https://flux.muhro.eu/?module=api&action=private&name=storages&storage_type=master&item_id=501
https://flux.muhro.eu/?module=api&action=private&name=storages&storage_name=Master%20I
https://flux.muhro.eu/?module=api&action=private&name=shops&shop_type=vending&item_id=501

Refreshes, privacy and main database load

  • Private API data requests read local key state and private snapshot files only, even when you have an active Flux login cookie.
  • Key creation, listing and revocation use the normal Flux account page and session. This interactive management page may query the main database for account checks. The keys remain in local storage and existing keys continue to work.
  • Background snapshot refreshes query only a verified read-only replica connection. Private API data requests issue no queries to the main game database.
  • Background refresh runs every minute for owners with active keys. Requests and cache misses never trigger a refresh or fall back to the main database.
  • Snapshots and authorization expire 120 seconds after refresh starts. The replica must have running replication threads and no more than 15 seconds of lag. Unavailable or expired data returns 503; expired snapshots are not served as a fallback.
  • Password, account restrictions and ownership changes become visible through the replica. Their visibility can be delayed by up to about 135 seconds. Local key revocation applies immediately to subsequent requests.
  • Data reflects saved game state that has reached the replica. Shop data uses the same database approximation of active shops as MarketDB.

All private success and error responses use Cache-Control: private, no-store, max-age=0. Private responses do not use ETag/304 cache validation and do not enable cross-origin browser access. Do not put them in shared caches.

Zero main database queries for API data requests does not mean zero server resource usage: the private API still uses web-server CPU and disk. Interactive key management and ordinary website pages use their normal Flux database connections.

Private API limits and errors

Data requests are limited to 60 per minute per owner, shared across that owner's keys. Key creation is limited to five attempts per 15 minutes per owner. Sign-in uses the normal Flux authentication controls. A key can only use its selected scopes.

Errors return JSON such as {"error":"snapshot_unavailable"}.

Status Meaning / action
200 Complete matching dataset returned. An empty match has count: 0 and data: [].
400 Invalid dataset/filter or a key supplied in the URL. Fix the request.
401 Missing, invalid, expired or revoked key. Check the header or create a new key if needed.
403 Required scope is missing or the owner is unavailable.
405 The data endpoint only accepts GET.
429 Rate limit exceeded. Honor Retry-After: 60.
503 No fresh snapshot/authorization, a busy cache or another unavailable dependency. Honor Retry-After: 60. Repeated requests do not force a refresh.

Response Headers

This table applies to the public MarketDB and Game DB APIs. Private response headers are described above.

Header Description
Content-Type application/json; charset=utf-8
Cache-Control Public cache header with max-age: 300 seconds for MarketDB, 3600 seconds for Game DB.
ETag Entity tag based on the snapshot file and modification time. Send it back as If-None-Match.
Last-Modified Snapshot file modification timestamp in GMT. Game DB endpoints also answer If-Modified-Since.
Content-Encoding Set to gzip when the client sends Accept-Encoding: gzip. The full item list is about 11 MB raw and under 1 MB gzipped, so always request gzip for the list endpoints.
Access-Control-Allow-Origin * on Game DB endpoints, so they can be called from browser scripts on other sites.

Rate Limits

API Limit
MarketDB 120 requests per minute per IP.
Game DB 240 requests per minute per IP.
Private Account API 60 requests per minute per owner across all keys.

For the public APIs fetch the list endpoints once and cache them; the game data only changes about weekly and gamedbmeta tells you when.

Status Codes

This table applies to the public APIs. See the Private API limits and errors section above for private responses.

Status Meaning
200 Snapshot returned successfully.
304 The client cache is still valid for the current ETag.
400 Invalid id parameter (Game DB).
403 Invalid or missing API key when key protection is enabled.
404 Unknown dataset name, unknown item or monster id or snapshot file missing.
429 Rate limit exceeded.
500 MarketDB cache configuration is missing.
503 Game DB API disabled.

Game DB errors are returned as JSON: {"error": "..."}.