Examples

Two copy-paste blocks to go from install to a working, authenticated API: a hardened config.yml and a curl walkthrough of every endpoint. For full integrations (dashboards, leaderboards, a Discord bot), see the integration examples.

The config.yml

On first run the plugin writes plugins/statfyr/config.yml. This excerpt sets the values you almost certainly want to change before exposing the API beyond localhost; all keys and defaults are straight from the shipped config file:

plugins/statfyr/config.ymlyaml
https:
  enabled: true
  keystore-path: "plugins/statfyr/keystore.jks"
  keystore-password: "changeit"       # set your own, or env STATFYR_KEYSTORE_PASSWORD

security:
  # Bearer auth: Authorization: Bearer <your-key>
  enable-api-key: true
  api-key: "GENERATE_ME"              # e.g. openssl rand -hex 32, or env STATFYR_API_KEY

  # Rate limiting (per client IP)
  enable-rate-limit: true
  rate-limit-requests: 120
  rate-limit-window-seconds: 60

  # CORS
  enable-cors: true
  allowed-origins:
    - "https://dashboard.example.com"

http:
  port: 8080
  bind-address: "0.0.0.0"             # 127.0.0.1 keeps the API localhost-only

After editing, apply changes without a restart: /statfyr reload. Generate the key once, hand it only to trusted clients; it grants full read access to every statistic.

All 7 endpoints, in order

With enable-api-key: true, every route requires the header, including /api/health included. Requests are GET-only (anything else answers 405; CORS preflight OPTIONS answers 204).

first-requests.shbash
BASE="http://127.0.0.1:8080"
KEY="GENERATE_ME"

# 1) API index: name, version, docs pointer
curl -s -H "Authorization: Bearer $KEY" "$BASE/api"

# 2) Self-describing endpoint list
curl -s -H "Authorization: Bearer $KEY" "$BASE/api/docs"

# 3) Health check
curl -s -H "Authorization: Bearer $KEY" "$BASE/api/health"

# 4) Every tracked player (online ones only)
curl -s -H "Authorization: Bearer $KEY" "$BASE/api/players?online_only=true"

# 5) Full stats for one player, by name or UUID
curl -s -H "Authorization: Bearer $KEY" "$BASE/api/player/Notch"

# 6) The same player as a computed summary
curl -s -H "Authorization: Bearer $KEY" "$BASE/api/player/069a79f4-44e9-4726-a5be-fca90e38aaf5/summary"

# 7) Leaderboard: playtime, deaths, player_kills, mob_kills, blocks_mined, items_picked_up, items_crafted
curl -s -H "Authorization: Bearer $KEY" "$BASE/api/leaderboard/playtime?limit=5"

Fetch it from JavaScript

The whole client is one wrapper: base URL plus Bearer header:

statfyr.jsjavascript
const BASE = "http://127.0.0.1:8080";

export async function statfyr(path) {
  const res = await fetch(BASE + path, {
    headers: { Authorization: "Bearer " + process.env.STATFYR_API_KEY },
  });
  if (!res.ok) throw new Error("statfyr " + res.status);
  return res.json();
}

const health = await statfyr("/api/health");
const top = await statfyr("/api/leaderboard/playtime?limit=10");

Manage it in game

Both commands need the statfyr.admin permission (default: operator):

/statfyr reload   # re-read config.yml and restart the embedded HTTP server
/statfyr status   # current runtime status

Go deeper