MarketDB API: Difference between revisions

From MuhRO
Jump to navigation Jump to search
Created page with "== MarketDB API == The MarketDB API serves pre-generated JSON snapshot files for vending, buying and trend data. This endpoint is snapshot-based: * API requests do ''not'' execute live database queries. * Responses are served from JSON files which are usually refreshed every 5 minutes. == Endpoint == Typical request format: <pre> https://flux.muhro.eu/?module=marketdb&action=api&name=<dataset> </pre> == Query Parameters == {| class="wikitable" ! Parameter !..."
 
No edit summary
 
(2 intermediate revisions by one other user not shown)
Line 1: Line 1:
== MarketDB API ==
== MuhRO Web API ==
 
The MuhRO Web API serves pre-generated JSON snapshot files from the control panel. There are two parts:


The MarketDB API serves pre-generated JSON snapshot files for vending, buying and trend data.
* '''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.


This endpoint is snapshot-based:
Both parts are snapshot-based:
* API requests do ''not'' execute live database queries.
* API requests do ''not'' execute live database queries.
* Responses are served from JSON files which are usually refreshed every 5 minutes.
* Responses are served from JSON files and carry cache headers, so clients should honour <code>ETag</code> and <code>Cache-Control</code>.
 
== Base URL ==


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


Typical request format:
All endpoints use the query form. The <code>key</code> parameter is accepted everywhere but currently not required.
 
== MarketDB API ==
 
=== Endpoint ===


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


== Query Parameters ==
=== Query Parameters ===


{| class="wikitable"
{| class="wikitable"
Line 28: Line 39:
| <code>key</code>
| <code>key</code>
| No
| No
| currently not used
| Currently not used.
|}
|}


== Available Datasets ==
=== Available Datasets ===


{| class="wikitable"
{| class="wikitable"
Line 83: Line 94:
|}
|}


== Example Requests ==
=== Example Requests ===


<pre>
<pre>
Line 93: Line 104:
https://flux.muhro.eu/?module=marketdb&action=api&name=vending_trend_hourly_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
https://flux.muhro.eu/?module=marketdb&action=api&name=vending_last_sales_latest
</pre>
== 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 ===
{| class="wikitable"
! Endpoint
! Description
|-
| <code>?module=api&action=itemdata</code>
| Full item list. Returns <code>{generated_at, count, items: [...]}</code> with compact rows.
|-
| <code>?module=api&action=itemdata&id=<item id></code>
| One item with all details (see below).
|-
| <code>?module=api&action=monsterdata</code>
| Full monster list. Returns <code>{generated_at, count, monsters: [...]}</code> with compact rows.
|-
| <code>?module=api&action=monsterdata&id=<monster id></code>
| One monster with all details (see below).
|-
| <code>?module=api&action=itemgroups</code>
| All item groups (boxes): <code>{groups: {<group name>: {containers: [...], contents: [...]}}}</code>.
|-
| <code>?module=api&action=gamedbmeta</code>
| Snapshot metadata: <code>generated_at</code>, <code>server</code>, item and monster counts, <code>exp_rates</code>, <code>drop_rates</code>. Poll this to detect a new snapshot.
|}
=== Item list row ===
<code>id</code>, <code>aegis_name</code>, <code>name</code>, <code>type</code>, <code>subtype</code>, <code>price_buy</code>, <code>price_sell</code>, <code>weight</code>, <code>attack</code>, <code>magic_attack</code>, <code>defense</code>, <code>range</code>, <code>slots</code>, <code>refineable</code>, <code>view</code>, <code>equip_locations[]</code>, <code>custom</code>
=== Item detail ===
{| class="wikitable"
! Field
! Description
|-
| Base fields
| Everything from the list row plus <code>alias_name</code>, <code>gender</code>, <code>weapon_level</code>, <code>armor_level</code>, <code>equip_level_min</code>, <code>equip_level_max</code>, <code>gradable</code>, <code>jobs[]</code>, <code>classes[]</code>, <code>trade_restrictions[]</code>, <code>flags[]</code>, <code>nouse[]</code>, <code>delay</code>, <code>stack</code>, <code>script</code>, <code>equip_script</code>, <code>unequip_script</code>.
|-
| <code>description</code>, <code>description_info</code>
| Item description as shown in the client and the extra info block from the control panel.
|-
| <code>item_group</code>, <code>group_contents[]</code>
| For boxes: the group name and its contents (<code>item_id</code>, <code>name</code>, <code>amount</code>, <code>rate</code>, <code>subgroup</code>, <code>algorithm</code>).
|-
| <code>contained_in[]</code>
| Boxes that can give this item (<code>item_id</code>, <code>name</code>, <code>aegis_name</code>, <code>group</code>).
|-
| <code>npc_shops[]</code>
| NPC shops that sell the item: <code>npc_id</code>, <code>npc_name</code>, <code>shop_type</code>, <code>map</code>, <code>x</code>, <code>y</code>, <code>price</code>, <code>currency</code>, <code>quantity</code> (market shops) and <code>cost_items[]</code> (barter shops).
|-
| <code>barter_ingredient_for[]</code>
| Barter shops that take the item as payment, with <code>reward_item_id</code> and <code>reward_item_name</code>.
|-
| <code>itemshop_cost</code>
| Control panel item shop price, if any.
|-
| <code>drops[]</code>
| Monsters that drop the item, sorted by chance. See drop entries below.
|-
| <code>images</code>
| <code>icon</code> and <code>collection</code> image URLs.
|}
=== Monster list row ===
<code>id</code>, <code>sprite</code>, <code>name</code>, <code>name_japanese</code>, <code>level</code>, <code>hp</code>, <code>size</code>, <code>race</code>, <code>element</code>, <code>element_level</code>, <code>base_exp</code>, <code>job_exp</code>, <code>mvp_exp</code>, <code>mvp</code>, <code>custom</code>
=== Monster detail ===
{| class="wikitable"
! Field
! Description
|-
| Base fields
| Everything from the list row plus <code>sp</code>, <code>attack</code>, <code>attack2</code>, <code>defense</code>, <code>magic_defense</code>, <code>resistance</code>, <code>magic_resistance</code>, <code>str</code>, <code>agi</code>, <code>vit</code>, <code>int</code>, <code>dex</code>, <code>luk</code>, <code>attack_range</code>, <code>skill_range</code>, <code>chase_range</code>, <code>race_groups[]</code>, <code>walk_speed</code>, <code>attack_delay</code>, <code>attack_motion</code>, <code>damage_motion</code>, <code>damage_taken</code>, <code>ai</code>, <code>class</code>, <code>boss</code>, <code>modes[]</code>.
|-
| <code>base_exp_rated</code>, <code>job_exp_rated</code>, <code>mvp_exp_rated</code>
| Exp with the server exp rates applied. The unsuffixed fields are the raw database values.
|-
| <code>drops[]</code>
| The normal drop slots: <code>slot</code>, <code>item_id</code>, <code>aegis_name</code>, <code>name</code>, <code>item_type</code>, <code>rate_raw</code>, <code>rate</code>, <code>steal</code>, <code>option</code>, <code>index</code>.
|-
| <code>mvp_drops[]</code>
| The MVP reward slots, same fields. <code>rate</code> already accounts for the earlier slots being rolled first.
|-
| <code>extra_drops[]</code>
| Additional drops from the server drop table (<code>item_id</code>, <code>name</code>, <code>rate_raw</code>, <code>rate</code>).
|-
| <code>map_drops[]</code>
| Map specific drops (<code>map</code>, <code>item_id</code>, <code>name</code>, <code>rate_raw</code>, <code>rate</code>).
|-
| <code>skills[]</code>
| Monster skills with cast conditions, if the server publishes them.
|-
| <code>spawns[]</code>
| Spawn points: <code>map</code>, <code>x</code>, <code>y</code>, <code>respawn_min</code>, <code>respawn_max</code>, <code>quantity</code>.
|-
| <code>image</code>
| Sprite image URL.
|}
=== Drop entries on items ===
Each entry in an item's <code>drops[]</code> has <code>monster_id</code>, <code>monster_name</code>, <code>monster_level</code>, <code>monster_race</code>, <code>monster_element</code>, <code>monster_element_level</code>, <code>boss</code>, <code>type</code>, <code>rate_raw</code>, <code>rate</code>, <code>steal</code> and, for map drops, <code>map</code>.
{| class="wikitable"
! <code>type</code>
! Meaning
|-
| <code>normal</code>
| One of the ten regular drop slots.
|-
| <code>mvp</code>
| MVP reward slot.
|-
| <code>extra</code>
| Additional server drop.
|-
| <code>map</code>
| Map specific drop on the map named in <code>map</code>.
|}
=== Drop chances ===
* <code>rate</code> 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).
* <code>rate_raw</code> 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 <code>gamedbmeta</code> as <code>drop_rates</code> and <code>exp_rates</code>.
* Drops whose item is not in the item database have <code>item_id</code> set to <code>null</code>.
=== Example Requests ===
<pre>
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
</pre>
Example drop entry from a monster:
<pre>
{"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}
</pre>
</pre>


Line 105: Line 267:
|-
|-
| <code>Cache-Control</code>
| <code>Cache-Control</code>
| Public cache header with <code>max-age</code> from <code>MarketDbCache.ApiCacheSeconds</code>.
| Public cache header with <code>max-age</code>: 300 seconds for MarketDB, 3600 seconds for Game DB.
|-
|-
| <code>ETag</code>
| <code>ETag</code>
| Entity tag based on the snapshot file and modification time.
| Entity tag based on the snapshot file and modification time. Send it back as <code>If-None-Match</code>.
|-
|-
| <code>Last-Modified</code>
| <code>Last-Modified</code>
| Snapshot file modification timestamp in GMT.
| Snapshot file modification timestamp in GMT. Game DB endpoints also answer <code>If-Modified-Since</code>.
|-
|-
| <code>Content-Encoding</code>
| <code>Content-Encoding</code>
| Set to <code>gzip</code> when gzip is enabled and supported by the client.
| Set to <code>gzip</code> when the client sends <code>Accept-Encoding: gzip</code>. The full item list is about 11 MB raw and under 1 MB gzipped, so always request gzip for the list endpoints.
|-
| <code>Access-Control-Allow-Origin</code>
| <code>*</code> on Game DB endpoints, so they can be called from browser scripts on other sites.
|}
|}


Default cache TTL:
== Rate Limits ==
* <code>MarketDbCache.ApiCacheSeconds = 300</code> (5 minutes)


== Authentication, Rate Limits, and Compression ==
{| class="wikitable"
 
! API
=== Rate Limiting ===
! Limit
 
|-
Simple per-IP rate limiting is controlled by <code>MarketDbCache.ApiRatePerMinute</code>.
| MarketDB
 
| 120 requests per minute per IP.
Default setting:
|-
* <code>120</code> requests per minute
| Game DB
| 240 requests per minute per IP.
|}


=== Gzip Compression ===
Fetch the list endpoints once and cache them; the game data only changes about weekly and <code>gamedbmeta</code> tells you when.
 
If <code>MarketDbCache.ApiEnableGzip</code> is enabled and the client sends <code>Accept-Encoding: gzip</code>, the API returns a gzipped response body.


== Status Codes ==
== Status Codes ==
Line 144: Line 308:
| <code>304</code>
| <code>304</code>
| The client cache is still valid for the current <code>ETag</code>.
| The client cache is still valid for the current <code>ETag</code>.
|-
| <code>400</code>
| Invalid <code>id</code> parameter (Game DB).
|-
|-
| <code>403</code>
| <code>403</code>
Line 149: Line 316:
|-
|-
| <code>404</code>
| <code>404</code>
| Unknown dataset name or snapshot file missing.
| Unknown dataset name, unknown item or monster id or snapshot file missing.
|-
|-
| <code>429</code>
| <code>429</code>
Line 155: Line 322:
|-
|-
| <code>500</code>
| <code>500</code>
| MarketDb cache configuration is missing.
| MarketDB cache configuration is missing.
|-
| <code>503</code>
| Game DB API disabled.
|}
|}
Game DB errors are returned as JSON: <code>{"error": "..."}</code>.

Latest revision as of 08:10, 19 September 2026

MuhRO Web API

The MuhRO Web API serves pre-generated JSON snapshot files from the control panel. There are two 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.

Both parts are snapshot-based:

  • API requests do not execute live database queries.
  • Responses are served from JSON files and carry cache headers, so clients should honour ETag and Cache-Control.

Base URL

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

All endpoints use the query form. The key parameter is accepted everywhere but currently not required.

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}

Response Headers

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.

Fetch the list endpoints once and cache them; the game data only changes about weekly and gamedbmeta tells you when.

Status Codes

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": "..."}.