[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"api-docs-html:en-US":3},"\u003Ch1>NukkitHub Public API (v2)\u003C\u002Fh1>\n\u003Cp>A read-only JSON API over the NukkitHub plugin index, shaped after the\n\u003Ca href=\"https:\u002F\u002Fdocs.modrinth.com\u002Fapi\u002F\" rel=\"noopener nofollow ugc\" target=\"_blank\">Modrinth API v2\u003C\u002Fa>. It exists so that tools —\nserver-panel installers, bots, package managers — can list Nukkit-family\nplugins and fetch installable jar URLs. The \u003Ccode>\u002Fv2\u002F\u003C\u002Fcode> prefix deliberately\nmatches Modrinth's own: point a Modrinth client that accepts a custom base\nURL at \u003Ccode>{api_base}\u003C\u002Fcode> and its \u003Ccode>\u002Fv2\u002F…\u003C\u002Fcode> requests resolve here directly (see\n\u003Ca href=\"#pointing-modrinth-tooling-at-nukkithub\" rel=\"noopener nofollow ugc\" target=\"_blank\">Pointing Modrinth tooling at NukkitHub\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Canonical base URL\u003C\u002Fstrong>: \u003Ccode>https:\u002F\u002Fplugins.nukkit-mot.com\u002Fapi\u003C\u002Fcode> (\u003Ccode>{api_base}\u003C\u002Fcode> below) —\nsame origin as the main site\u003C\u002Fli>\n\u003Cli>\u003Ccode>meta.json\u003C\u002Fcode> re-declares the canonical \u003Ccode>api_base\u003C\u002Fcode> — prefer it over hard-coded\nURLs for long-term addressing\u003C\u002Fli>\n\u003Cli>All responses are UTF-8 JSON, timestamps are ISO 8601, CORS is open\n(\u003Ccode>Access-Control-Allow-Origin: *\u003C\u002Fcode>)\u003C\u002Fli>\n\u003Cli>Unknown fields may appear at any time — ignore them\u003C\u002Fli>\n\u003Cli>\u003Ccode>\u002Fv2\u002F\u003C\u002Fcode> is the first published version; changes within it are additive-only,\nbreaking changes will go to \u003Ccode>\u002Fv3\u002F\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Quick start — panel install flow (two GETs)\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-bash\"># 1. list installable plugins for one runtime\ncurl -s https:\u002F\u002Fplugins.nukkit-mot.com\u002Fapi\u002Fv2\u002Fsearch\u002Fnkmot.json \\\n  | jq '.hits[] | {project_id, title, latest_version}'\n\n# 2. resolve the jar URL for a chosen plugin\ncurl -s https:\u002F\u002Fplugins.nukkit-mot.com\u002Fapi\u002Fv2\u002Fproject\u002FSoBadFish\u002FBedWar\u002Flatest.json \\\n  | jq '.files[] | select(.primary) | .url'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>For richer queries use dynamic search (\u003Ccode>\u002Fv2\u002Fsearch\u003C\u002Fcode> below); to work from a\nfull list, pull \u003Ccode>search.json\u003C\u002Fcode> (a few hundred KiB) and filter client-side.\nPoll \u003Ccode>version.json\u003C\u002Fcode> for updates rather than \u003Ccode>latest.json\u003C\u002Fcode>\nif you also want to see prereleases; poll at most every 15 minutes — the index\nrebuilds hourly and deploys trail it.\u003C\u002Fp>\n\u003Ch2>Endpoints\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Endpoint\u003C\u002Fth>\n\u003Cth>Description\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fsearch\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>Dynamic search\u003C\u002Fstrong>: \u003Ccode>query\u003C\u002Fcode>\u002F\u003Ccode>facets\u003C\u002Fcode>\u002F\u003Ccode>index\u003C\u002Fcode>\u002F\u003Ccode>offset\u003C\u002Fcode>\u002F\u003Ccode>limit\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fprojects?ids=[&quot;owner\u002Fname&quot;,…]\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Batch project lookup, ≤ 20 ids; slugs and \u003Ccode>%2F\u003C\u002Fcode>-encoded ids accepted\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{id}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Project detail (bare object); \u003Ccode>{id}\u003C\u002Fcode> is \u003Ccode>owner\u002Fname\u003C\u002Fcode>, a unique single-segment slug, or \u003Ccode>%2F\u003C\u002Fcode>-encoded\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{id}\u002Fversion\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Version list (bare array); optional \u003Ccode>?loaders=\u003C\u002Fcode> \u002F \u003Ccode>?game_versions=\u003C\u002Fcode> JSON-array filters\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{id}\u002Fversion\u002F{version_number}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Single version with files\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fversion\u002F{version_id}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Single version by globally-unique version id (\u003Ccode>{project_id}@{version_number}\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fversions?ids=[&quot;{version_id}&quot;,…]\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Batch version lookup, ≤ 20 ids; unresolvable ids are skipped\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fversion_file\u002F{hash}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Version owning the file with this hash (lowercase hex; the index carries \u003Ccode>sha256\u003C\u002Fcode>) — 404 when unknown\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{id}\u002Flatest\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Latest installable version: first non-prerelease, else newest (404 if the plugin has no releases)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Ftag\u002F{name}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Tags: \u003Ccode>loader\u003C\u002Fcode> \u002F \u003Ccode>category\u003C\u002Fcode> \u002F \u003Ccode>game_version\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fmeta\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Index metadata, counts, canonical \u003Ccode>api_base\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fsearch.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Every plugin in one Modrinth-style search response (a parameterless \u003Ccode>\u002Fv2\u002Fsearch\u003C\u002Fcode>), sorted by \u003Ccode>date_modified\u003C\u002Fcode> descending\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fsearch\u002F{loader}.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Same shape, pre-filtered by loader (\u003Ccode>nkmot\u003C\u002Fcode>, \u003Ccode>pnx\u003C\u002Fcode>, \u003Ccode>lumi\u003C\u002Fcode>, \u003Ccode>nkx\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{owner}\u002F{name}.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Project detail with all metadata; \u003Ccode>versions\u003C\u002Fcode> lists version ids newest-first\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{owner}\u002F{name}\u002Fversion.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Version list (bare array)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{owner}\u002F{name}\u002Fversion\u002F{version_number}.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Single version with files\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fversion_file\u002F{hash}.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Static form of the hash lookup (one file per indexed sha256)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fproject\u002F{owner}\u002F{name}\u002Flatest.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Latest installable version\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Ftag\u002F{loader|category|game_version}.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Tag files\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET {api_base}\u002Fv2\u002Fmeta.json\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Index metadata, counts, canonical \u003Ccode>api_base\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>\u003Ccode>{owner}\u002F{name}\u003C\u002Fcode> is the GitHub-derived id (multi-module repositories use\n\u003Ccode>owner\u002Frepo--module-suffix\u003C\u002Fcode>). Plugin ids with no indexed downloads (no GitHub\nRelease and no CI build) simply have an empty \u003Ccode>versions\u003C\u002Fcode> array and no\n\u003Ccode>latest\u003C\u002Fcode>. Visiting \u003Ccode>{api_base}\u002F\u003C\u002Fcode> serves a small human-readable endpoint index\npage.\u003C\u002Fp>\n\u003Cp>Version numbers come from GitHub Release tags. Additionally, repositories that\nbuild on \u003Ca href=\"https:\u002F\u002Fmotci.cn\" rel=\"noopener nofollow ugc\" target=\"_blank\">motci.cn\u003C\u002Fa> carry one snapshot version numbered\n\u003Ccode>ci-{build}\u003C\u002Fcode> (\u003Ccode>version_type: &quot;beta&quot;\u003C\u002Fcode>) whose files point at the Jenkins build\nartifacts. \u003Ccode>latest\u003C\u002Fcode> still prefers a non-prerelease release when one exists.\u003C\u002Fp>\n\u003Cp>Version numbers are only unique \u003Cstrong>within\u003C\u002Fstrong> a project, so the globally-unique\nversion id is the composite \u003Ccode>{project_id}@{version_number}\u003C\u002Fcode> — for example\n\u003Ccode>SoBadFish\u002FBedWar@v2.2.3\u003C\u002Fcode>. \u003Ccode>versions\u003C\u002Fcode> arrays carry these ids, and\n\u003Ccode>\u002Fv2\u002Fversion\u002F{version_id}\u003C\u002Fcode> and \u003Ccode>\u002Fv2\u002Fversions?ids=[…]\u003C\u002Fcode> accept them (URL-encode\nthe \u003Ccode>\u002F\u003C\u002Fcode> and the \u003Ccode>@\u003C\u002Fcode> when an id goes into a path, e.g.\n\u003Ccode>\u002Fv2\u002Fversion\u002FSoBadFish%2FBedWar%40v2.2.3\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Ch2>Dynamic search\u003C\u002Fh2>\n\u003Cp>\u003Ccode>GET {api_base}\u002Fv2\u002Fsearch\u003C\u002Fcode> takes the Modrinth v2 parameter syntax; called\nwith no parameters it returns exactly what \u003Ccode>search.json\u003C\u002Fcode> contains.\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Parameter\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Notes\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>query\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Cem>(none)\u003C\u002Fem>\u003C\u002Ftd>\n\u003Ctd>Case-insensitive substring match over \u003Ccode>title\u003C\u002Fcode> + \u003Ccode>description\u003C\u002Fcode> (max 256 chars)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>facets\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Cem>(none)\u003C\u002Fem>\u003C\u002Ftd>\n\u003Ctd>JSON array of arrays — outer AND, inner OR. Keys: \u003Ccode>loaders\u003C\u002Fcode>, \u003Ccode>categories\u003C\u002Fcode>, \u003Ccode>versions\u003C\u002Fcode> (matches version ids), \u003Ccode>game_versions\u003C\u002Fcode>, \u003Ccode>project_type\u003C\u002Fcode>, \u003Ccode>license\u003C\u002Fcode>, \u003Ccode>author\u003C\u002Fcode>, \u003Ccode>title\u003C\u002Fcode>. Unknown keys match nothing (forward compatible). Max 16 groups x 16 terms.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>index\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>relevance\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>relevance\u003C\u002Fcode> (title prefix &gt; title &gt; description, then recency), \u003Ccode>updated\u003C\u002Fcode>, \u003Ccode>newest\u003C\u002Fcode>, \u003Ccode>stars\u003C\u002Fcode>, \u003Ccode>downloads\u003C\u002Fcode>, \u003Ccode>follows\u003C\u002Fcode> — the last two are approximated by \u003Ccode>stars\u003C\u002Fcode> until download telemetry exists\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>offset\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>0\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>limit\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>20\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Max 100\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl -s 'https:\u002F\u002Fplugins.nukkit-mot.com\u002Fapi\u002Fv2\u002Fsearch?facets=%5B%5B%22loaders%3Ankmot%22%5D%5D&amp;query=economy&amp;index=stars&amp;limit=10'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Malformed \u003Ccode>facets\u003C\u002Fcode> returns \u003Ccode>400\u003C\u002Fcode> with an explanatory message. Responses carry\n\u003Ccode>Access-Control-Allow-Origin: *\u003C\u002Fcode>, \u003Ccode>Cache-Control: public, max-age=300\u003C\u002Fcode> and\n\u003Ccode>X-Content-Type-Options: nosniff\u003C\u002Fcode>. GET and HEAD are supported; other methods\nreturn \u003Ccode>405\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2>Pointing Modrinth tooling at NukkitHub\u003C\u002Fh2>\n\u003Cp>Modrinth SDKs and clients that let you override the API base URL can talk to\nNukkitHub directly: configure the base as \u003Ccode>https:\u002F\u002Fplugins.nukkit-mot.com\u002Fapi\u003C\u002Fcode>\nso the client's \u003Ccode>\u002Fv2\u002F…\u003C\u002Fcode> request paths land on our routes.\u003C\u002Fp>\n\u003Cp>Works out of the box:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Fsearch\u003C\u002Fcode> with the full parameter syntax, including \u003Ccode>facets\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Fprojects?ids=[…]\u003C\u002Fcode> batch lookup (max 20 ids per call)\u003C\u002Fli>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Fproject\u002F{id}\u003C\u002Fcode> — \u003Ccode>owner\u002Fname\u003C\u002Fcode> ids, including \u003Ccode>%2F\u003C\u002Fcode>-encoded forms,\nplus single-segment slugs (when the slug identifies exactly one plugin)\u003C\u002Fli>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Fproject\u002F{id}\u002Fversion\u003C\u002Fcode> with \u003Ccode>?loaders=\u003C\u002Fcode> \u002F \u003Ccode>?game_versions=\u003C\u002Fcode> filters\u003C\u002Fli>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Fproject\u002F{id}\u002Fversion\u002F{version_number}\u003C\u002Fcode> and \u003Ccode>\u002Flatest\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Fversion\u002F{version_id}\u003C\u002Fcode> and \u003Ccode>GET \u002Fv2\u002Fversions?ids=[…]\u003C\u002Fcode> (batch, max 20\nids) — version ids are \u003Ccode>{project_id}@{version_number}\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Fversion_file\u002F{sha256}\u003C\u002Fcode> — reverse hash lookup, returns the version\nwhose files include this sha256\u003C\u002Fli>\n\u003Cli>\u003Ccode>GET \u002Fv2\u002Ftag\u002F*\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Does not work, by design:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>authentication, user, team, notification, and payout endpoints\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Shapes\u003C\u002Fh2>\n\u003Cp>The field names and structure follow Modrinth v2. Quick orientation:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-jsonc\">\u003Cspan class=\"hljs-comment\">\u002F\u002F search.json (top level)\u003C\u002Fspan>\n\u003Cspan class=\"hljs-punctuation\">{\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;offset&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;limit&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-number\">359\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;total_hits&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-number\">359\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;hits&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan> \u003Cspan class=\"hljs-comment\">\u002F* SearchHit *\u002F\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"hljs-comment\">\u002F\u002F SearchHit (essentials only shown)\u003C\u002Fspan>\n\u003Cspan class=\"hljs-punctuation\">{\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;project_id&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;SoBadFish\u002FBedWar&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>  \u003Cspan class=\"hljs-comment\">\u002F\u002F &quot;owner\u002Fname&quot; — two segments, not base62\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;project_type&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;plugin&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;slug&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;BedWar&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;author&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;SoBadFish&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;title&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;BedWar&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;description&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;…&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;categories&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"hljs-string\">&quot;game-mechanics&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;loaders&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"hljs-string\">&quot;nkx&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;nkmot&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>       \u003Cspan class=\"hljs-comment\">\u002F\u002F runtime targets\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;game_versions&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"hljs-string\">&quot;1.0.11&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>       \u003Cspan class=\"hljs-comment\">\u002F\u002F server API versions\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;versions&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"hljs-string\">&quot;SoBadFish\u002FBedWar@v2.2.3&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;…&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>  \u003Cspan class=\"hljs-comment\">\u002F\u002F version ids ({project_id}@{version_number})\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;latest_version&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;v2.2.3&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;downloads&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>                     \u003Cspan class=\"hljs-comment\">\u002F\u002F reserved, currently always 0\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;icon_url&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;…&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;date_created&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;2024-08-27T04:01:38.000Z&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;date_modified&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;2024-08-27T04:01:38.000Z&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;license&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">{\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;id&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;MIT&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;name&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;MIT License&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;url&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;…&quot;\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;stars&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-number\">12\u003C\u002Fspan>                         \u003Cspan class=\"hljs-comment\">\u002F\u002F NukkitHub extension (GitHub stars)\u003C\u002Fspan>\n\u003Cspan class=\"hljs-punctuation\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"hljs-comment\">\u002F\u002F Version (element of version.json, or the \u002Fversion\u002F{n} and \u002Flatest bodies)\u003C\u002Fspan>\n\u003Cspan class=\"hljs-punctuation\">{\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;id&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;SoBadFish\u002FBedWar@v2.2.3&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>    \u003Cspan class=\"hljs-comment\">\u002F\u002F globally-unique version id\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;project_id&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;SoBadFish\u002FBedWar&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;name&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;2023\u002F08\u002F27 v2.2.3 更新&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;version_number&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;v2.2.3&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;changelog&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;…&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;version_type&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;release&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>          \u003Cspan class=\"hljs-comment\">\u002F\u002F &quot;beta&quot; for GitHub prereleases and ci-* snapshots\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;date_published&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;2024-08-27T04:01:38.000Z&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;downloads&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-number\">0\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;loaders&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"hljs-string\">&quot;nkx&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;nkmot&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>        \u003Cspan class=\"hljs-comment\">\u002F\u002F inherited from the project\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;game_versions&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"hljs-string\">&quot;1.0.11&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;files&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C\u002Fspan>\n      \u003Cspan class=\"hljs-attr\">&quot;url&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;https:\u002F\u002Fgithub.com\u002F…\u002FBedWar_v2.2.3.jar&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n      \u003Cspan class=\"hljs-attr\">&quot;filename&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;BedWar_v2.2.3.jar&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n      \u003Cspan class=\"hljs-attr\">&quot;primary&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-literal\">\u003Cspan class=\"hljs-keyword\">true\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>                \u003Cspan class=\"hljs-comment\">\u002F\u002F the jar a panel should install\u003C\u002Fspan>\n      \u003Cspan class=\"hljs-attr\">&quot;size&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-number\">437018\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n      \u003Cspan class=\"hljs-attr\">&quot;hashes&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">{\u003C\u002Fspan>                     \u003Cspan class=\"hljs-comment\">\u002F\u002F checksums by algorithm\u003C\u002Fspan>\n        \u003Cspan class=\"hljs-attr\">&quot;sha256&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;9f86d0…&quot;\u003C\u002Fspan>           \u003Cspan class=\"hljs-comment\">\u002F\u002F {} when the source has no digest\u003C\u002Fspan>\n      \u003Cspan class=\"hljs-punctuation\">}\u003C\u002Fspan>\n    \u003Cspan class=\"hljs-punctuation\">}\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-attr\">&quot;dependencies&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">[\u003C\u002Fspan>\n    \u003Cspan class=\"hljs-punctuation\">{\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;plugin_id&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;EconomyAPI&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;version_range&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"hljs-attr\">&quot;dependency_type&quot;\u003C\u002Fspan>\u003Cspan class=\"hljs-punctuation\">:\u003C\u002Fspan> \u003Cspan class=\"hljs-string\">&quot;optional&quot;\u003C\u002Fspan> \u003Cspan class=\"hljs-punctuation\">}\u003C\u002Fspan>\n  \u003Cspan class=\"hljs-punctuation\">]\u003C\u002Fspan>\n\u003Cspan class=\"hljs-punctuation\">}\u003C\u002Fspan>\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Project detail objects additionally carry \u003Ccode>body\u003C\u002Fcode> (full README markdown),\n\u003Ccode>gallery\u003C\u002Fcode>, \u003Ccode>authors\u003C\u002Fcode>, \u003Ccode>source_url\u003C\u002Fcode>, \u003Ccode>issues_url\u003C\u002Fcode>, \u003Ccode>wiki_url\u003C\u002Fcode>, \u003Ccode>discord_url\u003C\u002Fcode>,\nand the NukkitHub extensions (\u003Ccode>stars\u003C\u002Fcode>, \u003Ccode>authors\u003C\u002Fcode>, \u003Ccode>homepage_url\u003C\u002Fcode>,\n\u003Ccode>api_version\u003C\u002Fcode>, \u003Ccode>server_version\u003C\u002Fcode>, \u003Ccode>dependencies\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Cp>The full type contract lives in\n\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FMemoriesOfTime\u002FNukkitHub\u002Fblob\u002Fmaster\u002Fsrc\u002Ftypes\u002Fapi-v2.d.ts\" rel=\"noopener nofollow ugc\" target=\"_blank\">\u003Ccode>src\u002Ftypes\u002Fapi-v2.d.ts\u003C\u002Fcode>\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2>Differences from Modrinth API v2\u003C\u002Fh2>\n\u003Cp>This is a \u003Cstrong>shape-compatible subset with Modrinth-style addressing, not a\ndrop-in replacement\u003C\u002Fstrong>. What remains different:\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Modrinth capability\u003C\u002Fth>\n\u003Cth>Here\u003C\u002Fth>\n\u003Cth>Why\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv2\u002Fsearch?query=&amp;facets=&amp;offset=&amp;limit=\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>\u002Fv2\u002Fsearch\u003C\u002Fcode> with the same syntax; facet keys and sort values are a subset (see the parameter table)\u003C\u002Ftd>\n\u003Ctd>The index only carries those dimensions\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv2\u002Fprojects?ids=[…]\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Supported (≤ 20 ids)\u003C\u002Ftd>\n\u003Ctd>—\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv2\u002Fversions?ids=[…]\u003C\u002Fcode>, \u003Ccode>GET \u002Fv2\u002Fversion\u002F{id}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Supported — version ids are \u003Ccode>{project_id}@{version_number}\u003C\u002Fcode> composites (version numbers alone are only unique per project)\u003C\u002Ftd>\n\u003Ctd>Identity is the GitHub release\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>GET \u002Fv2\u002Fversion_file\u002F{hash}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Supported for \u003Ccode>sha256\u003C\u002Fcode> (the only hash the index carries); \u003Ccode>sha1\u003C\u002Fcode>\u002F\u003Ccode>sha512\u003C\u002Fcode>-length hashes are accepted but always 404\u003C\u002Ftd>\n\u003Ctd>Only GitHub exposes file digests, sha256 only\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>featured\u003C\u002Fcode> flag \u002F \u003Ccode>?featured\u003C\u002Fcode> filter\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>latest\u003C\u002Fcode> route instead\u003C\u002Ftd>\n\u003Ctd>No featured concept in the source data\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>follows\u003C\u002Fcode> \u002F \u003Ccode>followers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Extension field \u003Ccode>stars\u003C\u002Fcode> instead\u003C\u002Ftd>\n\u003Ctd>No telemetry\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>8-char base62 ids, single-segment slugs\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>owner\u002Fname\u003C\u002Fcode> two-segment ids; single-segment slugs resolve when unique\u003C\u002Ftd>\n\u003Ctd>Identity is the GitHub repository\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Auth, teams, notifications, reports, payouts\u003C\u002Ftd>\n\u003Ctd>Not present\u003C\u002Ftd>\n\u003Ctd>Read-only public data, no user system\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Rate-limit headers, mandatory User-Agent\u003C\u002Ftd>\n\u003Ctd>None enforced\u003C\u002Ftd>\n\u003Ctd>A descriptive User-Agent is still appreciated\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2>Data caveats\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Ccode>downloads\u003C\u002Fcode> is \u003Cstrong>always 0\u003C\u002Fstrong> today (reserved placeholder).\u003C\u002Fli>\n\u003Cli>\u003Ccode>files[].hashes\u003C\u002Fcode> carries \u003Ccode>sha256\u003C\u002Fcode> where the source provides a digest.\nGitHub only exposes digests for release assets uploaded since mid-2025;\nolder assets, and \u003Ccode>ci-{build}\u003C\u002Fcode> CI artifacts, have \u003Ccode>&quot;hashes&quot;: {}\u003C\u002Fcode>. The\n\u003Ccode>meta.counts.files_with_hashes\u003C\u002Fcode> figure tracks the coverage.\u003C\u002Fli>\n\u003Cli>\u003Ccode>version_number\u003C\u002Fcode> is usable directly as the project-scoped\n\u003Ccode>\u002Fproject\u002F{id}\u002Fversion\u002F{version_number}\u003C\u002Fcode> path segment; both parts of a\nversion id (\u003Ccode>{project_id}@{version_number}\u003C\u002Fcode>) are already path-safe —\nfilename-unsafe characters are replaced by the exporter.\u003C\u002Fli>\n\u003Cli>\u003Ccode>body\u003C\u002Fcode> and \u003Ccode>changelog\u003C\u002Fcode> are raw markdown from the repository README\u002Frelease\nnotes. Sanitize before rendering (the NukkitHub site treats them the same way).\u003C\u002Fli>\n\u003C\u002Ful>\n",1790329219427]