{"openapi":"3.1.0","info":{"title":"Valheim guild site API","version":"1.0.0","summary":"Public read API, admin API, live stream and telemetry ingest of the guild site.","description":"Conventions: JSON UTF-8; timestamps ISO 8601 UTC with Z; world day integer; coordinates x and z in world metres (the world is a disc of radius 10,000 m centred on 0,0); durations in seconds unless the field name ends in _ms. Ids: players, characters, sessions, raids and jobs are integers; events and server runs are UUID strings; boss keys and global keys are strings. Pagination: limit (1 to 200, default 50) and an opaque cursor; list responses are { items, next_cursor } ordered newest first unless stated. Errors: the HTTP status plus { error: { code, message } }. Caching: public GET responses carry Cache-Control: public, max-age=15 and an ETag; /stream and admin responses are uncacheable. Rate limit: 120 requests per minute per IP on public endpoints, answered with 429 rate_limited; ingest and stream are exempt. Admin auth: POST /admin/login sets a signed session cookie; admin endpoints answer 401 without it; state-changing requests require the Origin header to match ORIGIN."},"servers":[{"url":"http://localhost:5173","description":"Local development server (npm run dev, npm run dev:mock)."},{"url":"http://localhost:3000","description":"Local production image (docker compose up)."},{"url":"https://{host}","description":"Railway deployment.","variables":{"host":{"default":"guild.example.org","description":"The site domain."}}}],"security":[],"tags":[{"name":"status","description":"Server status and history."},{"name":"players","description":"Players, characters and their statistics."},{"name":"bosses","description":"Boss progression and timelines."},{"name":"raids","description":"Random events."},{"name":"world","description":"World, progression keys, saves and the map."},{"name":"chat","description":"Shouts, pings and relayed speech."},{"name":"structures","description":"Building activity."},{"name":"activity","description":"The unified feed."},{"name":"system","description":"Health and this contract."},{"name":"stream","description":"Live updates over server-sent events."},{"name":"admin","description":"Password-protected administration."},{"name":"ingest","description":"Signed telemetry from the server plugin."},{"name":"zone","description":"Zone-leader measurements, their ranking and the probe the browser measures against."}],"paths":{"/api/v1/status":{"get":{"operationId":"getStatus","tags":["status"],"summary":"Server status","description":"Online state, player count, versions, world and run information from the plugin and, independently, from Steam A2S polling.","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/status/history":{"get":{"operationId":"getStatusHistory","tags":["status"],"summary":"Player count history","parameters":[{"name":"range","in":"query","required":false,"description":"Window to return, downsampled to at most 600 points.","schema":{"type":"string","enum":["24h","7d","30d"],"default":"24h"}}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusHistory"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/online":{"get":{"operationId":"getOnline","tags":["status"],"summary":"Players online now","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnlineList"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/runs":{"get":{"operationId":"listRuns","tags":["status"],"summary":"Server runs","description":"One item per server process start, newest first.","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players":{"get":{"operationId":"listPlayers","tags":["players"],"summary":"Player list","description":"Hidden players are omitted.","parameters":[{"name":"q","in":"query","required":false,"description":"Search by display name, character name, raw id or display id.","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"Sort key.","schema":{"type":"string","enum":["playtime","last_seen","deaths","kills","name","first_seen"],"default":"last_seen"}},{"name":"order","in":"query","required":false,"description":"Sort direction.","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"online","in":"query","required":false,"description":"Only players online right now.","schema":{"type":"boolean"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players/{id}":{"get":{"operationId":"getPlayer","tags":["players"],"summary":"Player profile","parameters":[{"$ref":"#/components/parameters/PlayerId"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Player"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players/{id}/sessions":{"get":{"operationId":"listPlayerSessions","tags":["players"],"summary":"Session history","parameters":[{"$ref":"#/components/parameters/PlayerId"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players/{id}/deaths":{"get":{"operationId":"listPlayerDeaths","tags":["players"],"summary":"Deaths","parameters":[{"$ref":"#/components/parameters/PlayerId"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeathPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players/{id}/kills":{"get":{"operationId":"getPlayerKills","tags":["players"],"summary":"Creature kills","description":"Credited kills come from RegisterKill RPCs relayed through the server; nearby kills are counted by proximity.","parameters":[{"$ref":"#/components/parameters/PlayerId"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerKills"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players/{id}/positions":{"get":{"operationId":"getPlayerPositions","tags":["players"],"summary":"Position trail","parameters":[{"$ref":"#/components/parameters/PlayerId"},{"name":"range","in":"query","required":false,"description":"Window to return.","schema":{"type":"string","enum":["1h","6h","24h","7d"],"default":"24h"}},{"name":"limit","in":"query","required":false,"description":"Maximum number of points after downsampling.","schema":{"type":"integer","minimum":1,"maximum":5000,"default":500}}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PositionList"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players/{id}/structures":{"get":{"operationId":"getPlayerStructures","tags":["players"],"summary":"Structures built","parameters":[{"$ref":"#/components/parameters/PlayerId"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerStructures"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/players/{id}/activity":{"get":{"operationId":"listPlayerActivity","tags":["players"],"summary":"Player activity","parameters":[{"$ref":"#/components/parameters/PlayerId"},{"$ref":"#/components/parameters/Types"},{"$ref":"#/components/parameters/Since"},{"$ref":"#/components/parameters/Until"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/bosses":{"get":{"operationId":"listBosses","tags":["bosses"],"summary":"Boss progression","description":"Every boss in progression order with its kill summary; unknown defeated_* keys appear with the raw key as name.","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BossList"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/bosses/{key}":{"get":{"operationId":"getBoss","tags":["bosses"],"summary":"Boss detail","parameters":[{"$ref":"#/components/parameters/BossKey"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BossDetail"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/bosses/{key}/events":{"get":{"operationId":"listBossEvents","tags":["bosses"],"summary":"Boss timeline","parameters":[{"$ref":"#/components/parameters/BossKey"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BossEventPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/raids":{"get":{"operationId":"listRaids","tags":["raids"],"summary":"Raids","parameters":[{"$ref":"#/components/parameters/Since"},{"$ref":"#/components/parameters/Until"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RaidPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/raids/{id}":{"get":{"operationId":"getRaid","tags":["raids"],"summary":"Raid detail","parameters":[{"$ref":"#/components/parameters/RaidId"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RaidDetail"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/progression":{"get":{"operationId":"getProgression","tags":["world"],"summary":"World progression keys","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgressionList"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/world":{"get":{"operationId":"getWorld","tags":["world"],"summary":"World","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/World"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/world/map.png":{"get":{"operationId":"getWorldMap","tags":["world"],"summary":"World map image","description":"The biome map rendered by the plugin for the current world uid.","responses":{"200":{"description":"The PNG.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"image/png":{"schema":{"type":"string","contentMediaType":"image/png"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/saves":{"get":{"operationId":"listSaves","tags":["world"],"summary":"World saves","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavePage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/chat":{"get":{"operationId":"listChat","tags":["chat"],"summary":"Chat","parameters":[{"name":"kind","in":"query","required":false,"description":"Only this kind.","schema":{"type":"string","enum":["shout","ping","say"]}},{"$ref":"#/components/parameters/PlayerFilter"},{"$ref":"#/components/parameters/Since"},{"$ref":"#/components/parameters/Until"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/structures":{"get":{"operationId":"getStructures","tags":["structures"],"summary":"Structures summary","parameters":[{"name":"range","in":"query","required":false,"description":"Window for the series and totals.","schema":{"type":"string","enum":["7d","30d","all"],"default":"30d"}}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Structures"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/structures/recent":{"get":{"operationId":"listStructureEvents","tags":["structures"],"summary":"Recent structure events","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StructureEventPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/activity":{"get":{"operationId":"listActivity","tags":["activity"],"summary":"Activity feed","description":"Every event newest first, excluding server.heartbeat, player.position, structure.* and creature.died unless requested through types.","parameters":[{"$ref":"#/components/parameters/Types"},{"$ref":"#/components/parameters/PlayerFilter"},{"$ref":"#/components/parameters/Since"},{"$ref":"#/components/parameters/Until"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/zone/results":{"get":{"operationId":"listZoneResults","tags":["zone"],"summary":"Ranked zone-leader results","description":"Every stored measurement, ranked best first by overall score with ties broken by failure rate, median latency, jitter, single-thread CPU, stability score and name. One entry per character name.","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZoneResultList"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/zone/results/{name}":{"put":{"operationId":"putZoneResult","tags":["zone"],"summary":"Store or replace a measurement","description":"Stores the result under the normalised character name (trimmed, inner whitespace collapsed, upper-cased), replacing any earlier result for that name. The body must carry the same name. Scores, rating and penalties are recomputed from the measurements on the server and tested_at is stamped with server time; the answer is the stored entry with its rank in the fresh ranking.","parameters":[{"$ref":"#/components/parameters/ZoneName"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZoneResult"}}}},"responses":{"200":{"description":"The stored entry with its rank.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZoneRankedResult"}}}},"400":{"description":"bad_request: the name is empty or over 48 characters, the body does not match ZoneResult, or the body names a different character.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"unprocessable: the diagnostic version is incompatible, the measurements are impossible, or the run did not complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteZoneResult","tags":["zone"],"summary":"Remove a measurement","parameters":[{"$ref":"#/components/parameters/ZoneName"}],"responses":{"204":{"description":"Removed."},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/zone/probe/health":{"get":{"operationId":"getZoneProbeHealth","tags":["zone"],"summary":"Probe health","description":"The probe the browser measures against. Probe routes are served by the site itself in every mode, carry no ETag and are exempt from the rate limit.","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProbeHealth"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/zone/probe/ping":{"get":{"operationId":"getZoneProbePing","tags":["zone"],"summary":"Probe round trip","description":"Answers immediately with the server clock so the browser can time a round trip.","parameters":[{"name":"t","in":"query","required":false,"description":"Cache buster; ignored.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProbePing"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/zone/probe/download":{"get":{"operationId":"getZoneProbeDownload","tags":["zone"],"summary":"Probe download payload","description":"A deterministic binary payload of the requested size for timing a download.","parameters":[{"name":"bytes","in":"query","required":false,"description":"Payload size in bytes, clamped to 16 to 2097152.","schema":{"type":"integer","minimum":16,"maximum":2097152,"default":65536}}],"responses":{"200":{"description":"The payload, with its Content-Length.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/octet-stream":{"schema":{"type":"string","contentMediaType":"application/octet-stream"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/zone/probe/upload":{"post":{"operationId":"postZoneProbeUpload","tags":["zone"],"summary":"Probe upload sink","description":"Accepts up to 2 MiB, discards it and answers with the byte count so the browser can time an upload.","requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","contentMediaType":"application/octet-stream"}}}},"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProbeUpload"}}}},"413":{"description":"payload_too_large: body over 2 MiB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/health":{"get":{"operationId":"getHealth","tags":["system"],"summary":"Health","description":"Container health check.","responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/openapi.json":{"get":{"operationId":"getOpenApi","tags":["system"],"summary":"This contract as JSON","responses":{"200":{"description":"The OpenAPI document.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"429":{"description":"rate_limited: more than 120 requests per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/stream":{"get":{"operationId":"streamEvents","tags":["stream"],"summary":"Live stream","description":"Server-sent events. Event names: status (the Status object, sent on connect and whenever it changes), online (the OnlineList object, on connect and on change) and activity (one ActivityItem per accepted event that the feed includes, with id set to the event id). A comment frame every 15 s keeps the connection alive. A reconnect with Last-Event-ID first replays activity items newer than that id (at most 100).","parameters":[{"$ref":"#/components/parameters/LastEventId"},{"name":"last_event_id","in":"query","required":false,"description":"Same as the Last-Event-ID header, for clients that reconnect manually and cannot set headers.","schema":{"type":"string"}}],"x-sse-events":{"status":{"description":"The /status object.","schema":{"$ref":"#/components/schemas/Status"}},"online":{"description":"The /online list.","schema":{"$ref":"#/components/schemas/OnlineList"}},"activity":{"description":"One activity item; the frame id is the event id.","schema":{"$ref":"#/components/schemas/ActivityItem"}}},"responses":{"200":{"description":"An event stream that stays open.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"text/event-stream":{"schema":{"$ref":"#/components/schemas/StreamFrame"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/login":{"post":{"operationId":"adminLogin","tags":["admin"],"summary":"Log in","description":"Sets an HttpOnly, SameSite=Lax (Secure in production) session cookie signed with ADMIN_SESSION_SECRET. Limited to 5 attempts per minute per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"204":{"description":"Logged in; the cookie is set.","headers":{"Set-Cookie":{"description":"The admin session cookie.","schema":{"type":"string"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized: wrong password.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: more than 5 login attempts per minute from this IP.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/logout":{"post":{"operationId":"adminLogout","tags":["admin"],"summary":"Log out","security":[{"adminCookie":[]}],"responses":{"204":{"description":"Logged out; the cookie is cleared."},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden: the Origin header does not match ORIGIN.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/session":{"get":{"operationId":"getAdminSession","tags":["admin"],"summary":"Session state","security":[{"adminCookie":[]}],"responses":{"200":{"description":"Whether the cookie is a valid session; authenticated is false without a valid cookie.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSession"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/players":{"get":{"operationId":"listAdminPlayers","tags":["admin"],"summary":"Players including hidden","security":[{"adminCookie":[]}],"parameters":[{"name":"include_hidden","in":"query","required":false,"description":"Include hidden players.","schema":{"type":"boolean","default":true}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlayerPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/players/{id}":{"patch":{"operationId":"updateAdminPlayer","tags":["admin"],"summary":"Rename or hide a player","security":[{"adminCookie":[]}],"parameters":[{"$ref":"#/components/parameters/PlayerId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerPatch"}}}},"responses":{"200":{"description":"The updated player.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlayer"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden: the Origin header does not match ORIGIN.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/players/{id}/merge":{"post":{"operationId":"mergeAdminPlayer","tags":["admin"],"summary":"Merge a player into another","description":"All rows of {id} move to into, {id} becomes an alias of into. Reversible only through a rebuild plus alias removal.","security":[{"adminCookie":[]}],"parameters":[{"$ref":"#/components/parameters/PlayerId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MergeRequest"}}}},"responses":{"200":{"description":"The surviving player.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlayer"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden: the Origin header does not match ORIGIN.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict: a player cannot be merged into itself or into an alias.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/players/{id}/aliases/{alias}":{"delete":{"operationId":"deleteAdminPlayerAlias","tags":["admin"],"summary":"Remove an alias","security":[{"adminCookie":[]}],"parameters":[{"$ref":"#/components/parameters/PlayerId"},{"$ref":"#/components/parameters/Alias"}],"responses":{"204":{"description":"Removed."},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden: the Origin header does not match ORIGIN.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/events":{"get":{"operationId":"listAdminEvents","tags":["admin"],"summary":"Raw events","security":[{"adminCookie":[]}],"parameters":[{"name":"type","in":"query","required":false,"description":"Only this event type.","schema":{"$ref":"#/components/schemas/EventType"}},{"name":"run_id","in":"query","required":false,"description":"Only this run.","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PlayerFilter"},{"$ref":"#/components/parameters/Since"},{"$ref":"#/components/parameters/Until"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Raw envelopes newest first.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventPage"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/events/{id}":{"get":{"operationId":"getAdminEvent","tags":["admin"],"summary":"One raw event","security":[{"adminCookie":[]}],"parameters":[{"$ref":"#/components/parameters/EventId"}],"responses":{"200":{"description":"The event with received_at.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoredEvent"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/projections/rebuild":{"post":{"operationId":"rebuildProjections","tags":["admin"],"summary":"Rebuild projections","description":"Truncates every projection table and replays events in (ts, seq) order.","security":[{"adminCookie":[]}],"responses":{"202":{"description":"Queued.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden: the Origin header does not match ORIGIN.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict: a rebuild is already running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/backups/run":{"post":{"operationId":"runBackup","tags":["admin"],"summary":"Run a backup now","security":[{"adminCookie":[]}],"responses":{"202":{"description":"Queued.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden: the Origin header does not match ORIGIN.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict: a backup is already running.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/backups":{"get":{"operationId":"listBackups","tags":["admin"],"summary":"Backups on the volume","security":[{"adminCookie":[]}],"responses":{"200":{"description":"Newest first.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupList"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/jobs/{id}":{"get":{"operationId":"getJob","tags":["admin"],"summary":"Job state","security":[{"adminCookie":[]}],"parameters":[{"$ref":"#/components/parameters/JobId"}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"bad_request: a parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found: no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/admin/health":{"get":{"operationId":"getAdminHealth","tags":["admin"],"summary":"Telemetry health","security":[{"adminCookie":[]}],"responses":{"200":{"description":"OK","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminHealth"}}}},"401":{"description":"unauthorized: no valid admin session cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/ingest":{"post":{"operationId":"ingestBatch","tags":["ingest"],"summary":"Ingest an event batch","description":"Verifies the timestamp window (5 minutes) and the HMAC with a constant-time comparison, sorts by seq, inserts events with ON CONFLICT DO NOTHING, applies projections for inserted rows in the same transaction and publishes accepted events to the stream.","security":[{"telemetrySignature":[]}],"parameters":[{"$ref":"#/components/parameters/TelemetryTimestamp"},{"$ref":"#/components/parameters/TelemetrySignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestBatch"}}}},"responses":{"200":{"description":"Counts for the batch.","headers":{"Cache-Control":{"$ref":"#/components/headers/NoStore"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}}}},"401":{"description":"unauthorized: bad signature or stale timestamp.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large: body over 1 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"unprocessable: malformed batch.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: database unavailable; the plugin retries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/ingest/map":{"post":{"operationId":"ingestMap","tags":["ingest"],"summary":"Upload the world map image","description":"Body is a PNG. The signature is the HMAC over timestamp + \".\" + sha256hex(body). Stored per world uid, replacing any previous image for that uid. Limit 16 MB.","security":[{"telemetrySignature":[]}],"parameters":[{"$ref":"#/components/parameters/TelemetryTimestamp"},{"$ref":"#/components/parameters/TelemetrySignature"},{"name":"X-World-Uid","in":"header","required":true,"description":"World uid the image belongs to.","schema":{"type":"integer"}},{"name":"X-Map-Size","in":"header","required":true,"description":"Pixels per side.","schema":{"type":"integer","minimum":1}},{"name":"X-Map-Radius","in":"header","required":true,"description":"Metres represented by half the side.","schema":{"type":"number","minimum":1}}],"requestBody":{"required":true,"content":{"image/png":{"schema":{"type":"string","contentMediaType":"image/png"}}}},"responses":{"204":{"description":"Stored."},"401":{"description":"unauthorized: bad signature or stale timestamp.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large: body over 16 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"unprocessable: not a PNG or headers missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"not_implemented: the handler is not built yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"unavailable: the database cannot be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"adminCookie":{"type":"apiKey","in":"cookie","name":"admin_session","description":"Session cookie set by POST /api/v1/admin/login."},"telemetrySignature":{"type":"apiKey","in":"header","name":"X-Telemetry-Signature","description":"sha256=<hex HMAC-SHA256> over X-Telemetry-Timestamp + \".\" + body with the shared TELEMETRY_SECRET."}},"headers":{"CacheControl":{"description":"public, max-age=15 on public GET responses.","schema":{"type":"string"}},"ETag":{"description":"Entity tag of the response body.","schema":{"type":"string"}},"NoStore":{"description":"no-store on stream and admin responses.","schema":{"type":"string"}}},"parameters":{"Limit":{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},"Cursor":{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous next_cursor.","schema":{"type":"string"}},"Since":{"name":"since","in":"query","required":false,"description":"Only items at or after this time.","schema":{"type":"string","format":"date-time"}},"Until":{"name":"until","in":"query","required":false,"description":"Only items before this time.","schema":{"type":"string","format":"date-time"}},"Types":{"name":"types","in":"query","required":false,"description":"Restrict to these event types.","schema":{"type":"string","description":"Comma-separated list of event types."}},"PlayerFilter":{"name":"player","in":"query","required":false,"description":"Only items involving this player id.","schema":{"type":"integer"}},"PlayerId":{"name":"id","in":"path","required":true,"description":"Player id.","schema":{"type":"integer"}},"BossKey":{"name":"key","in":"path","required":true,"description":"Boss key, for example defeated_eikthyr.","schema":{"type":"string"}},"RaidId":{"name":"id","in":"path","required":true,"description":"Raid id.","schema":{"type":"integer"}},"EventId":{"name":"id","in":"path","required":true,"description":"Event id.","schema":{"type":"string","format":"uuid"}},"JobId":{"name":"id","in":"path","required":true,"description":"Job id.","schema":{"type":"integer"}},"Alias":{"name":"alias","in":"path","required":true,"description":"Raw platform user id of the alias.","schema":{"type":"string"}},"ZoneName":{"name":"name","in":"path","required":true,"description":"Character name, normalised: trimmed, inner whitespace collapsed, upper-cased.","schema":{"type":"string","minLength":1,"maxLength":48}},"LastEventId":{"name":"Last-Event-ID","in":"header","required":false,"description":"Sent by EventSource on reconnect; activity items newer than this id are replayed first (at most 100).","schema":{"type":"string"}},"TelemetryTimestamp":{"name":"X-Telemetry-Timestamp","in":"header","required":true,"description":"Signature timestamp.","schema":{"type":"integer","description":"Unix seconds; must be within 5 minutes of the server clock."}},"TelemetrySignature":{"name":"X-Telemetry-Signature","in":"header","required":true,"description":"HMAC-SHA256 of timestamp + \".\" + body (or the body SHA-256 hex for the map upload) with the shared secret.","schema":{"type":"string","pattern":"^sha256=[0-9a-f]{64}$"}}},"schemas":{"Error":{"type":"object","description":"Error envelope returned with every non-2xx status.","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["bad_request","unauthorized","forbidden","not_found","conflict","payload_too_large","unprocessable","rate_limited","unavailable","not_implemented"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"Platform":{"type":"string","enum":["Steam","Xbox","PlayStation","Nintendo"],"description":"Platform prefix of the raw platform user id."},"Biome":{"type":"string","enum":["Meadows","BlackForest","Swamp","Mountain","Plains","Mistlands","AshLands","DeepNorth","Ocean","None"],"description":"Biome identifier exactly as the game names it."},"HitType":{"type":"string","enum":["EnemyHit","PlayerHit","Fall","Drowning","Burning","Freezing","Poisoned","Water","Smoke","EdgeOfWorld","Impact","Cart","Tree","Self","Structural","Turret","Boat","Stalagtite","Catapult","CinderFire","AshlandsOcean","AshlandsLava","Incinerator","DrawBridge","Undefined"],"description":"HitData hit type of the last server-observed damage before a death."},"EventType":{"type":"string","enum":["server.started","server.stopping","server.heartbeat","server.lost","world.save_started","world.saved","world.rollback_detected","player.joined","player.spawned","player.died","player.left","player.biome_changed","player.position","boss.summoned","boss.engaged","boss.defeated","global_key.set","raid.started","raid.ended","structure.built","structure.destroyed","creature.died","chat.message"],"description":"Every event type in the catalogue, including the two synthetic ones written by the backend (server.lost, world.rollback_detected)."},"LeftReason":{"type":"string","enum":["disconnect","timeout","kicked","server_stop","reconciled","server_lost"],"description":"Why a session ended. reconciled and server_lost are assigned by the backend."},"PlayerRef":{"type":"object","description":"Reference to a player wherever a player is named. Hidden players appear as null instead of this object.","properties":{"id":{"type":"integer","description":"Player id."},"display_name":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"}},"required":["id","display_name","platform"],"additionalProperties":false},"StatusWorld":{"type":"object","properties":{"name":{"type":"string"},"uid":{"type":"integer","description":"World uid (the world seed identifier as a 64-bit integer)."},"day":{"type":"integer","description":"Current world day."},"time_of_day":{"type":"number","minimum":0,"maximum":1,"description":"Fraction of the current day that has elapsed, 0 at midnight."},"net_time":{"type":"number","description":"World time in seconds as reported by the server."}},"required":["name","uid","day","time_of_day","net_time"],"additionalProperties":false},"StatusRun":{"type":"object","properties":{"run_id":{"type":"string","format":"uuid","description":"Identifier of the current server process run."},"started_at":{"type":"string","format":"date-time"},"uptime_s":{"type":"number"},"plugin_version":{"type":"string"}},"required":["run_id","started_at","uptime_s","plugin_version"],"additionalProperties":false},"StatusTelemetry":{"type":"object","properties":{"live":{"type":"boolean","description":"True while heartbeats arrive within the watchdog window."},"last_heartbeat_at":{"type":["string","null"],"format":"date-time"},"delayed_since":{"type":["string","null"],"format":"date-time","description":"Set when the plugin has been silent for longer than 180 s."}},"required":["live","last_heartbeat_at","delayed_since"],"additionalProperties":false},"Status":{"type":"object","description":"Server status as shown on the dashboard, in the status strip and on /api/status.","properties":{"online":{"type":"boolean"},"source":{"type":"string","enum":["plugin","a2s","none"],"description":"Which signal produced this status."},"player_count":{"type":"integer","minimum":0},"max_players":{"type":"integer","minimum":0},"game_version":{"type":["string","null"]},"network_version":{"type":["integer","null"]},"server_name":{"type":"string"},"world":{"anyOf":[{"$ref":"#/components/schemas/StatusWorld"},{"type":"null"}]},"run":{"anyOf":[{"$ref":"#/components/schemas/StatusRun"},{"type":"null"}]},"last_save_at":{"type":["string","null"],"format":"date-time"},"telemetry":{"$ref":"#/components/schemas/StatusTelemetry"},"updated_at":{"type":"string","format":"date-time"}},"required":["online","source","player_count","max_players","game_version","network_version","server_name","world","run","last_save_at","telemetry","updated_at"],"additionalProperties":false},"StatusHistoryPoint":{"type":"object","properties":{"ts":{"type":"string","format":"date-time"},"online":{"type":"boolean"},"player_count":{"type":"integer","minimum":0}},"required":["ts","online","player_count"],"additionalProperties":false},"StatusHistory":{"type":"object","properties":{"range":{"type":"string","enum":["24h","7d","30d"]},"step_s":{"type":"integer","minimum":1,"description":"Seconds between points after downsampling."},"items":{"type":"array","items":{"$ref":"#/components/schemas/StatusHistoryPoint"},"maxItems":600}},"required":["range","step_s","items"],"additionalProperties":false},"OnlinePlayer":{"type":"object","properties":{"player_id":{"type":"integer"},"display_name":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"character_name":{"type":"string"},"biome":{"$ref":"#/components/schemas/Biome"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"since":{"type":"string","format":"date-time","description":"When the current session started."}},"required":["player_id","display_name","platform","character_name","biome","x","z","since"],"additionalProperties":false},"OnlineList":{"type":"object","description":"Players online right now. Hidden players are omitted.","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/OnlinePlayer"}}},"required":["items"],"additionalProperties":false},"Run":{"type":"object","properties":{"run_id":{"type":"string","format":"uuid"},"started_at":{"type":"string","format":"date-time"},"stopped_at":{"type":["string","null"],"format":"date-time"},"stop_reason":{"type":["string","null"],"enum":["graceful","inferred",null]},"game_version":{"type":["string","null"]},"plugin_version":{"type":["string","null"]},"peak_players":{"type":"integer","minimum":0},"saves":{"type":"integer","minimum":0}},"required":["run_id","started_at","stopped_at","stop_reason","game_version","plugin_version","peak_players","saves"],"additionalProperties":false},"RunPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Run"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"PlayerListItem":{"type":"object","properties":{"id":{"type":"integer"},"display_name":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"display_id":{"type":"string","description":"Display form used by the F2 panel and the list files, for example V_76561198012345678."},"online":{"type":"boolean"},"current_biome":{"anyOf":[{"$ref":"#/components/schemas/Biome"},{"type":"null"}]},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"playtime_s":{"type":"number","minimum":0},"sessions":{"type":"integer","minimum":0},"deaths":{"type":"integer","minimum":0},"kills":{"type":"integer","minimum":0,"description":"Creature kills, credited and by proximity together."},"boss_kills":{"type":"integer","minimum":0},"structures_built":{"type":"integer","minimum":0},"distance_m":{"type":"number","minimum":0},"characters":{"type":"array","items":{"type":"string"},"description":"Character names, latest first."}},"required":["id","display_name","platform","platform_user_id","display_id","online","current_biome","first_seen","last_seen","playtime_s","sessions","deaths","kills","boss_kills","structures_built","distance_m","characters"],"additionalProperties":false},"PlayerPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PlayerListItem"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"Character":{"type":"object","properties":{"character_id":{"type":"integer","description":"Character profile id (a 64-bit integer generated by the game)."},"name":{"type":"string"},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"}},"required":["character_id","name","first_seen","last_seen"],"additionalProperties":false},"CurrentSession":{"type":"object","properties":{"joined_at":{"type":"string","format":"date-time"},"character_name":{"type":"string"},"biome":{"$ref":"#/components/schemas/Biome"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."}},"required":["joined_at","character_name","biome","x","z"],"additionalProperties":false},"PlayerStats":{"type":"object","properties":{"playtime_s":{"type":"number","minimum":0},"sessions":{"type":"integer","minimum":0},"deaths":{"type":"integer","minimum":0},"kills_credited":{"type":"integer","minimum":0},"kills_nearby":{"type":"integer","minimum":0},"boss_kills":{"type":"integer","minimum":0},"raids":{"type":"integer","minimum":0},"structures_built":{"type":"integer","minimum":0},"structures_destroyed":{"type":"integer","minimum":0},"shouts":{"type":"integer","minimum":0},"distance_m":{"type":"number","minimum":0}},"required":["playtime_s","sessions","deaths","kills_credited","kills_nearby","boss_kills","raids","structures_built","structures_destroyed","shouts","distance_m"],"additionalProperties":false},"PlayerBiome":{"type":"object","properties":{"biome":{"$ref":"#/components/schemas/Biome"},"first_at":{"type":"string","format":"date-time"},"first_day":{"type":"integer"},"visits":{"type":"integer","minimum":1},"last_at":{"type":"string","format":"date-time"}},"required":["biome","first_at","first_day","visits","last_at"],"additionalProperties":false},"KillsByCreature":{"type":"object","properties":{"creature":{"type":"string","description":"Resolved creature name."},"credited":{"type":"integer","minimum":0},"nearby":{"type":"integer","minimum":0}},"required":["creature","credited","nearby"],"additionalProperties":false},"BossParticipation":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"at":{"type":"string","format":"date-time"},"day":{"type":"integer"},"role":{"type":"string","enum":["credited","nearby"]}},"required":["key","name","at","day","role"],"additionalProperties":false},"PlayerRaid":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"label":{"type":"string"},"at":{"type":"string","format":"date-time"},"day":{"type":"integer"},"survived":{"type":"boolean"}},"required":["id","name","label","at","day","survived"],"additionalProperties":false},"Player":{"type":"object","description":"The player list item plus everything the player page shows.","properties":{"id":{"type":"integer"},"display_name":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"display_id":{"type":"string","description":"Display form used by the F2 panel and the list files, for example V_76561198012345678."},"online":{"type":"boolean"},"current_biome":{"anyOf":[{"$ref":"#/components/schemas/Biome"},{"type":"null"}]},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"playtime_s":{"type":"number","minimum":0},"sessions":{"type":"integer","minimum":0},"deaths":{"type":"integer","minimum":0},"kills":{"type":"integer","minimum":0,"description":"Creature kills, credited and by proximity together."},"boss_kills":{"type":"integer","minimum":0},"structures_built":{"type":"integer","minimum":0},"distance_m":{"type":"number","minimum":0},"characters":{"type":"array","items":{"$ref":"#/components/schemas/Character"}},"current_session":{"anyOf":[{"$ref":"#/components/schemas/CurrentSession"},{"type":"null"}]},"stats":{"$ref":"#/components/schemas/PlayerStats"},"biomes":{"type":"array","items":{"$ref":"#/components/schemas/PlayerBiome"}},"deaths_by_cause":{"type":"object","description":"Death counts keyed by observed hit type, with \"unknown\" for deaths whose fatal hits the server never saw.","additionalProperties":{"type":"integer","minimum":0}},"kills_by_creature":{"type":"array","items":{"$ref":"#/components/schemas/KillsByCreature"}},"boss_participation":{"type":"array","items":{"$ref":"#/components/schemas/BossParticipation"}},"raids":{"type":"array","items":{"$ref":"#/components/schemas/PlayerRaid"}},"aliases":{"type":"array","items":{"type":"string"},"description":"Raw platform user ids merged into this player."}},"required":["id","display_name","platform","platform_user_id","display_id","online","current_biome","first_seen","last_seen","playtime_s","sessions","deaths","kills","boss_kills","structures_built","distance_m","characters","current_session","stats","biomes","deaths_by_cause","kills_by_creature","boss_participation","raids","aliases"],"additionalProperties":false},"Session":{"type":"object","properties":{"id":{"type":"integer"},"joined_at":{"type":"string","format":"date-time"},"left_at":{"type":["string","null"],"format":"date-time"},"duration_s":{"type":["number","null"],"minimum":0},"left_reason":{"anyOf":[{"$ref":"#/components/schemas/LeftReason"},{"type":"null"}]},"character_name":{"type":"string"},"run_id":{"type":"string","format":"uuid"}},"required":["id","joined_at","left_at","duration_s","left_reason","character_name","run_id"],"additionalProperties":false},"SessionPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Session"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"DeathCause":{"type":"object","description":"Present only when the fatal hits were relayed through the server.","properties":{"hit_type":{"$ref":"#/components/schemas/HitType"},"attacker_prefab":{"type":["string","null"]},"attacker":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]}},"required":["hit_type","attacker_prefab","attacker"],"additionalProperties":false},"Death":{"type":"object","properties":{"id":{"type":"integer"},"at":{"type":"string","format":"date-time"},"day":{"type":"integer"},"biome":{"$ref":"#/components/schemas/Biome"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"cause":{"anyOf":[{"$ref":"#/components/schemas/DeathCause"},{"type":"null"}]}},"required":["id","at","day","biome","x","z","cause"],"additionalProperties":false},"DeathPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Death"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"RecentKill":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"creature":{"type":"string"},"level":{"type":"integer","minimum":1},"boss":{"type":"boolean"},"basis":{"type":"string","enum":["credited","nearby"]}},"required":["at","creature","level","boss","basis"],"additionalProperties":false},"PlayerKills":{"type":"object","properties":{"credited":{"type":"integer","minimum":0},"nearby":{"type":"integer","minimum":0},"by_creature":{"type":"array","items":{"$ref":"#/components/schemas/KillsByCreature"}},"recent":{"type":"array","items":{"$ref":"#/components/schemas/RecentKill"},"maxItems":50}},"required":["credited","nearby","by_creature","recent"],"additionalProperties":false},"Position":{"type":"object","properties":{"ts":{"type":"string","format":"date-time"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"}},"required":["ts","x","z","biome"],"additionalProperties":false},"PositionList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Position"},"description":"Oldest first, downsampled to the requested limit."}},"required":["items"],"additionalProperties":false},"StructuresByPrefab":{"type":"object","properties":{"prefab":{"type":"string"},"built":{"type":"integer","minimum":0}},"required":["prefab","built"],"additionalProperties":false},"RecentStructure":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"prefab":{"type":"string"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"}},"required":["at","prefab","x","z","biome"],"additionalProperties":false},"PlayerStructures":{"type":"object","properties":{"built":{"type":"integer","minimum":0},"destroyed":{"type":"integer","minimum":0},"by_prefab":{"type":"array","items":{"$ref":"#/components/schemas/StructuresByPrefab"}},"recent":{"type":"array","items":{"$ref":"#/components/schemas/RecentStructure"}}},"required":["built","destroyed","by_prefab","recent"],"additionalProperties":false},"FirstKill":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"day":{"type":"integer"},"participants":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]}}},"required":["at","day","participants"],"additionalProperties":false},"BossDefeat":{"type":"object","description":"The earliest evidence that the world has defeated this boss. observed is true when the plugin saw the first kill, in which case since and day equal first_kill. observed is false when the boss's defeated_* key was already among the world's saved global keys when the log first saw it: the kill itself predates the log, and since and day only say when the log learned of it.","properties":{"since":{"type":"string","format":"date-time"},"day":{"type":"integer"},"observed":{"type":"boolean"}},"required":["since","day","observed"],"additionalProperties":false},"Boss":{"type":"object","properties":{"key":{"type":"string","description":"Global key of the boss, for example defeated_eikthyr."},"name":{"type":"string","description":"Resolved boss name, or the raw key when unknown."},"order":{"type":"integer","minimum":1,"description":"Position in the boss progression."},"summons":{"type":"integer","minimum":0},"engaged":{"type":"integer","minimum":0},"kills":{"type":"integer","minimum":0,"description":"Kills the plugin observed; zero for a boss defeated before the log began."},"first_kill":{"anyOf":[{"$ref":"#/components/schemas/FirstKill"},{"type":"null"}]},"last_kill_at":{"type":["string","null"],"format":"date-time"},"active":{"type":"boolean","description":"True while an instance of this boss is engaged."},"defeat":{"anyOf":[{"$ref":"#/components/schemas/BossDefeat"},{"type":"null"}],"description":"Null until the world has defeated this boss at least once, whether or not the log saw the kill."}},"required":["key","name","order","summons","engaged","kills","first_kill","last_kill_at","active","defeat"],"additionalProperties":false},"BossList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Boss"},"description":"Ordered by order."}},"required":["items"],"additionalProperties":false},"BossEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Event id."},"kind":{"type":"string","enum":["summoned","engaged","defeated"]},"at":{"type":"string","format":"date-time"},"day":{"type":"integer"},"x":{"type":["number","null"],"description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":["number","null"],"description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"anyOf":[{"$ref":"#/components/schemas/Biome"},{"type":"null"}]},"participants":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]}},"nearby":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]}},"summoner":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]},"first_time":{"type":["boolean","null"],"description":"Set on defeated events; true for the first kill of this boss."}},"required":["id","kind","at","day","x","z","biome","participants","nearby","summoner","first_time"],"additionalProperties":false},"BossDetail":{"type":"object","properties":{"key":{"type":"string","description":"Global key of the boss, for example defeated_eikthyr."},"name":{"type":"string","description":"Resolved boss name, or the raw key when unknown."},"order":{"type":"integer","minimum":1,"description":"Position in the boss progression."},"summons":{"type":"integer","minimum":0},"engaged":{"type":"integer","minimum":0},"kills":{"type":"integer","minimum":0,"description":"Kills the plugin observed; zero for a boss defeated before the log began."},"first_kill":{"anyOf":[{"$ref":"#/components/schemas/FirstKill"},{"type":"null"}]},"last_kill_at":{"type":["string","null"],"format":"date-time"},"active":{"type":"boolean","description":"True while an instance of this boss is engaged."},"defeat":{"anyOf":[{"$ref":"#/components/schemas/BossDefeat"},{"type":"null"}],"description":"Null until the world has defeated this boss at least once, whether or not the log saw the kill."},"events":{"type":"array","items":{"$ref":"#/components/schemas/BossEvent"},"maxItems":50,"description":"The last 50 events, newest first."}},"required":["key","name","order","summons","engaged","kills","first_kill","last_kill_at","active","defeat","events"],"additionalProperties":false},"BossEventPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BossEvent"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"Raid":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","description":"Raw random event name, for example army_eikthyr."},"label":{"type":"string","description":"Resolved label, for example Eikthyr rallies the creatures of the forest."},"biome":{"$ref":"#/components/schemas/Biome"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"day":{"type":"integer"},"started_at":{"type":"string","format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"},"duration_s":{"type":["number","null"],"minimum":0},"planned_duration_s":{"type":"number","minimum":0},"participants":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]}},"deaths_during":{"type":"integer","minimum":0}},"required":["id","name","label","biome","x","z","day","started_at","ended_at","duration_s","planned_duration_s","participants","deaths_during"],"additionalProperties":false},"RaidPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Raid"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"RaidDeath":{"type":"object","properties":{"player":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]},"at":{"type":"string","format":"date-time"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."}},"required":["player","at","x","z"],"additionalProperties":false},"RaidDetail":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","description":"Raw random event name, for example army_eikthyr."},"label":{"type":"string","description":"Resolved label, for example Eikthyr rallies the creatures of the forest."},"biome":{"$ref":"#/components/schemas/Biome"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"day":{"type":"integer"},"started_at":{"type":"string","format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"},"duration_s":{"type":["number","null"],"minimum":0},"planned_duration_s":{"type":"number","minimum":0},"participants":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]}},"deaths_during":{"type":"integer","minimum":0},"deaths":{"type":"array","items":{"$ref":"#/components/schemas/RaidDeath"}}},"required":["id","name","label","biome","x","z","day","started_at","ended_at","duration_s","planned_duration_s","participants","deaths_during","deaths"],"additionalProperties":false},"ProgressionKey":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":["string","null"]},"category":{"type":"string","enum":["boss","modifier","other"]},"first_set_at":{"type":"string","format":"date-time"},"day":{"type":"integer"}},"required":["key","value","category","first_set_at","day"],"additionalProperties":false},"ProgressionList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ProgressionKey"}}},"required":["items"],"additionalProperties":false},"WorldSaves":{"type":"object","properties":{"last_at":{"type":["string","null"],"format":"date-time"},"count_24h":{"type":"integer","minimum":0},"avg_duration_ms":{"type":["number","null"],"minimum":0}},"required":["last_at","count_24h","avg_duration_ms"],"additionalProperties":false},"WorldRollback":{"type":"object","properties":{"detected_at":{"type":"string","format":"date-time"},"from_net_time":{"type":"number"},"to_net_time":{"type":"number"}},"required":["detected_at","from_net_time","to_net_time"],"additionalProperties":false},"WorldMap":{"type":"object","properties":{"available":{"type":"boolean"},"image_url":{"type":["string","null"],"description":"Path of the map image, /api/v1/world/map.png when available."},"size_px":{"type":["integer","null"],"minimum":1},"radius_m":{"type":["number","null"],"minimum":1},"generated_at":{"type":["string","null"],"format":"date-time"}},"required":["available","image_url","size_px","radius_m","generated_at"],"additionalProperties":false},"World":{"type":"object","properties":{"name":{"type":"string"},"uid":{"type":"integer"},"day":{"type":"integer"},"net_time":{"type":"number"},"day_length_s":{"type":"number","minimum":1},"saves":{"$ref":"#/components/schemas/WorldSaves"},"rollbacks":{"type":"array","items":{"$ref":"#/components/schemas/WorldRollback"}},"map":{"anyOf":[{"$ref":"#/components/schemas/WorldMap"},{"type":"null"}]}},"required":["name","uid","day","net_time","day_length_s","saves","rollbacks","map"],"additionalProperties":false},"Save":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"duration_ms":{"type":"integer","minimum":0}},"required":["at","duration_ms"],"additionalProperties":false},"SavePage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Save"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"ChatMessage":{"type":"object","properties":{"id":{"type":"integer"},"at":{"type":"string","format":"date-time"},"day":{"type":"integer"},"kind":{"type":"string","enum":["shout","ping","say"]},"player":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]},"text":{"type":["string","null"]},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"}},"required":["id","at","day","kind","player","text","x","z","biome"],"additionalProperties":false},"ChatPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"StructuresSeriesPoint":{"type":"object","properties":{"date":{"type":"string","format":"date"},"built":{"type":"integer","minimum":0},"destroyed":{"type":"integer","minimum":0}},"required":["date","built","destroyed"],"additionalProperties":false},"StructuresByBuilder":{"type":"object","properties":{"player":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]},"built":{"type":"integer","minimum":0}},"required":["player","built"],"additionalProperties":false},"Structures":{"type":"object","properties":{"built_total":{"type":"integer","minimum":0},"destroyed_total":{"type":"integer","minimum":0},"series":{"type":"array","items":{"$ref":"#/components/schemas/StructuresSeriesPoint"}},"by_builder":{"type":"array","items":{"$ref":"#/components/schemas/StructuresByBuilder"}},"by_prefab":{"type":"array","items":{"$ref":"#/components/schemas/StructuresByPrefab"}}},"required":["built_total","destroyed_total","series","by_builder","by_prefab"],"additionalProperties":false},"StructureEvent":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"kind":{"type":"string","enum":["built","destroyed"]},"prefab":{"type":"string"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"player":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]}},"required":["at","kind","prefab","x","z","biome","player"],"additionalProperties":false},"StructureEventPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/StructureEvent"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"ActivityLinks":{"type":"object","properties":{"raid_id":{"type":["integer","null"]},"boss_key":{"type":["string","null"]},"run_id":{"type":["string","null"],"format":"uuid"},"session_id":{"type":["integer","null"]}},"required":["raid_id","boss_key","run_id","session_id"],"additionalProperties":false},"ActivityItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The event id."},"at":{"type":"string","format":"date-time"},"day":{"type":"integer"},"type":{"$ref":"#/components/schemas/EventType"},"player":{"anyOf":[{"$ref":"#/components/schemas/PlayerRef"},{"type":"null"}]},"summary":{"type":"object","description":"The display fields of the event: the same names as the event data plus resolved names (boss_name, raid_label, cause). Raw platform ids are replaced by player references.","additionalProperties":true},"links":{"$ref":"#/components/schemas/ActivityLinks"}},"required":["id","at","day","type","player","summary","links"],"additionalProperties":false},"ActivityPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ActivityItem"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"Health":{"type":"object","properties":{"ok":{"type":"boolean"},"db":{"type":"boolean","description":"True when the database answered."},"version":{"type":"string","description":"The web package version."},"mock":{"type":"boolean","description":"True when API_MOCK=1 serves fixtures."}},"required":["ok","db","version","mock"],"additionalProperties":false},"LoginRequest":{"type":"object","properties":{"password":{"type":"string"}},"required":["password"],"additionalProperties":false},"AdminSession":{"type":"object","properties":{"authenticated":{"type":"boolean"},"expires_at":{"type":["string","null"],"format":"date-time"}},"required":["authenticated","expires_at"],"additionalProperties":false},"AdminPlayer":{"type":"object","properties":{"id":{"type":"integer"},"display_name":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"display_id":{"type":"string","description":"Display form used by the F2 panel and the list files, for example V_76561198012345678."},"online":{"type":"boolean"},"current_biome":{"anyOf":[{"$ref":"#/components/schemas/Biome"},{"type":"null"}]},"first_seen":{"type":"string","format":"date-time"},"last_seen":{"type":"string","format":"date-time"},"playtime_s":{"type":"number","minimum":0},"sessions":{"type":"integer","minimum":0},"deaths":{"type":"integer","minimum":0},"kills":{"type":"integer","minimum":0,"description":"Creature kills, credited and by proximity together."},"boss_kills":{"type":"integer","minimum":0},"structures_built":{"type":"integer","minimum":0},"distance_m":{"type":"number","minimum":0},"characters":{"type":"array","items":{"type":"string"}},"hidden":{"type":"boolean"},"display_name_override":{"type":["string","null"]},"aliases":{"type":"array","items":{"type":"string"}}},"required":["id","display_name","platform","platform_user_id","display_id","online","current_biome","first_seen","last_seen","playtime_s","sessions","deaths","kills","boss_kills","structures_built","distance_m","characters","hidden","display_name_override","aliases"],"additionalProperties":false},"AdminPlayerPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminPlayer"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"PlayerPatch":{"type":"object","description":"Fields to change; omitted fields keep their value.","properties":{"display_name_override":{"type":["string","null"],"minLength":1,"maxLength":64},"hidden":{"type":"boolean"}},"required":[],"additionalProperties":false},"MergeRequest":{"type":"object","properties":{"into":{"type":"integer","description":"Id of the surviving player."}},"required":["into"],"additionalProperties":false},"JobAccepted":{"type":"object","properties":{"job_id":{"type":"integer"}},"required":["job_id"],"additionalProperties":false},"Backup":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"file":{"type":"string"},"size_bytes":{"type":"integer","minimum":0},"ok":{"type":"boolean"}},"required":["at","file","size_bytes","ok"],"additionalProperties":false},"BackupList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Backup"}}},"required":["items"],"additionalProperties":false},"Job":{"type":"object","properties":{"id":{"type":"integer"},"kind":{"type":"string","enum":["projections_rebuild","backup"]},"state":{"type":"string","enum":["queued","running","done","failed"]},"started_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"progress":{"type":["number","null"],"minimum":0,"maximum":1},"error":{"type":["string","null"]}},"required":["id","kind","state","started_at","finished_at","progress","error"],"additionalProperties":false},"AdminHealthA2s":{"type":"object","properties":{"last_ok_at":{"type":["string","null"],"format":"date-time"},"last_error":{"type":["string","null"]},"online":{"type":["boolean","null"]},"player_count":{"type":["integer","null"],"minimum":0}},"required":["last_ok_at","last_error","online","player_count"],"additionalProperties":false},"AdminHealthIngest":{"type":"object","properties":{"last_batch_at":{"type":["string","null"],"format":"date-time"},"batches_24h":{"type":"integer","minimum":0},"events_24h":{"type":"integer","minimum":0},"duplicates_24h":{"type":"integer","minimum":0},"rejected_24h":{"type":"integer","minimum":0}},"required":["last_batch_at","batches_24h","events_24h","duplicates_24h","rejected_24h"],"additionalProperties":false},"AdminHealthDb":{"type":"object","properties":{"events_total":{"type":"integer","minimum":0},"size_mb":{"type":"number","minimum":0}},"required":["events_total","size_mb"],"additionalProperties":false},"AdminHealthBackup":{"type":"object","properties":{"last_at":{"type":["string","null"],"format":"date-time"},"size_mb":{"type":["number","null"],"minimum":0},"kept":{"type":"integer","minimum":0}},"required":["last_at","size_mb","kept"],"additionalProperties":false},"AdminHealthMap":{"type":"object","properties":{"available":{"type":"boolean"},"generated_at":{"type":["string","null"],"format":"date-time"}},"required":["available","generated_at"],"additionalProperties":false},"AdminHealthJob":{"type":"object","properties":{"name":{"type":"string"},"last_run_at":{"type":["string","null"],"format":"date-time"},"last_ok":{"type":["boolean","null"]},"last_error":{"type":["string","null"]}},"required":["name","last_run_at","last_ok","last_error"],"additionalProperties":false},"AdminHealth":{"type":"object","properties":{"run":{"anyOf":[{"$ref":"#/components/schemas/Run"},{"type":"null"}]},"last_heartbeat_at":{"type":["string","null"],"format":"date-time"},"heartbeat_age_s":{"type":["number","null"],"minimum":0},"plugin_version":{"type":["string","null"]},"game_version":{"type":["string","null"]},"missing_hooks":{"type":"array","items":{"type":"string"}},"queue_depth":{"type":["integer","null"],"minimum":0},"dropped_events":{"type":["integer","null"],"minimum":0},"a2s":{"$ref":"#/components/schemas/AdminHealthA2s"},"ingest":{"$ref":"#/components/schemas/AdminHealthIngest"},"db":{"$ref":"#/components/schemas/AdminHealthDb"},"backup":{"$ref":"#/components/schemas/AdminHealthBackup"},"map":{"$ref":"#/components/schemas/AdminHealthMap"},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/AdminHealthJob"}}},"required":["run","last_heartbeat_at","heartbeat_age_s","plugin_version","game_version","missing_hooks","queue_depth","dropped_events","a2s","ingest","db","backup","map","jobs"],"additionalProperties":false},"ServerStartedData":{"type":"object","properties":{"game_version":{"type":"string"},"network_version":{"type":"integer"},"plugin_version":{"type":"string"},"bepinex_version":{"type":"string"},"unity_version":{"type":"string"},"world_name":{"type":"string"},"world_uid":{"type":"integer"},"net_time":{"type":"number"},"world_day":{"type":"integer"},"global_keys":{"type":"array","items":{"type":"string"}},"missing_hooks":{"type":"array","items":{"type":"string"}}},"required":["game_version","network_version","plugin_version","bepinex_version","unity_version","world_name","world_uid","net_time","world_day","global_keys","missing_hooks"],"additionalProperties":false},"ServerStoppingData":{"type":"object","properties":{"uptime_s":{"type":"number","minimum":0},"online_count":{"type":"integer","minimum":0}},"required":["uptime_s","online_count"],"additionalProperties":false},"HeartbeatPlayer":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"name":{"type":"string"},"character_id":{"type":"integer"},"biome":{"$ref":"#/components/schemas/Biome"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"distance_since_last_m":{"type":"number","minimum":0}},"required":["platform_user_id","name","character_id","biome","x","z","distance_since_last_m"],"additionalProperties":false},"ServerHeartbeatData":{"type":"object","properties":{"uptime_s":{"type":"number","minimum":0},"net_time":{"type":"number"},"world_day":{"type":"integer"},"last_save_age_s":{"type":["number","null"],"minimum":0},"queue_depth":{"type":"integer","minimum":0},"dropped_events":{"type":"integer","minimum":0},"players":{"type":"array","items":{"$ref":"#/components/schemas/HeartbeatPlayer"}}},"required":["uptime_s","net_time","world_day","last_save_age_s","queue_depth","dropped_events","players"],"additionalProperties":false},"ServerLostData":{"type":"object","description":"Synthetic, written by the watchdog when a run stops sending heartbeats.","properties":{"last_heartbeat_at":{"type":"string","format":"date-time"}},"required":["last_heartbeat_at"],"additionalProperties":false},"WorldSaveStartedData":{"type":"object","description":"No fields.","properties":{},"required":[],"additionalProperties":false},"WorldSavedData":{"type":"object","properties":{"duration_ms":{"type":"integer","minimum":0}},"required":["duration_ms"],"additionalProperties":false},"WorldRollbackDetectedData":{"type":"object","description":"Synthetic, written by the ingest when net_time regresses by more than 60 s.","properties":{"from_net_time":{"type":"number"},"to_net_time":{"type":"number"}},"required":["from_net_time","to_net_time"],"additionalProperties":false},"PlayerJoinedData":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"display_id":{"type":"string"},"platform":{"$ref":"#/components/schemas/Platform"},"name":{"type":"string"},"peer_uid":{"type":"integer"},"playfab_id":{"type":["string","null"]}},"required":["platform_user_id","display_id","platform","name","peer_uid","playfab_id"],"additionalProperties":false},"PlayerSpawnedData":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"name":{"type":"string"},"character_id":{"type":"integer"},"respawn":{"type":"boolean"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"}},"required":["platform_user_id","name","character_id","respawn","x","z","biome"],"additionalProperties":false},"ObservedCause":{"type":"object","description":"The last damage RPC to the player relayed through the server within the 10 s before the death.","properties":{"hit_type":{"$ref":"#/components/schemas/HitType"},"attacker_prefab":{"type":["string","null"]},"attacker_platform_user_id":{"type":["string","null"],"description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"at":{"type":"string","format":"date-time"}},"required":["hit_type","attacker_prefab","attacker_platform_user_id","at"],"additionalProperties":false},"PlayerDiedData":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"name":{"type":"string"},"character_id":{"type":"integer"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"observed_cause":{"anyOf":[{"$ref":"#/components/schemas/ObservedCause"},{"type":"null"}]}},"required":["platform_user_id","name","character_id","x","z","biome","observed_cause"],"additionalProperties":false},"PlayerLeftData":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"name":{"type":"string"},"session_s":{"type":"number","minimum":0},"reason":{"type":"string","enum":["disconnect","timeout","kicked","server_stop"]}},"required":["platform_user_id","name","session_s","reason"],"additionalProperties":false},"PlayerBiomeChangedData":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"from":{"$ref":"#/components/schemas/Biome"},"to":{"$ref":"#/components/schemas/Biome"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."}},"required":["platform_user_id","from","to","x","z"],"additionalProperties":false},"PlayerPositionData":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"}},"required":["platform_user_id","x","z","biome"],"additionalProperties":false},"BossSummonedData":{"type":"object","properties":{"prefab":{"type":"string"},"name_key":{"type":"string"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"summoner_platform_user_id":{"type":["string","null"],"description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"method":{"type":"string","enum":["spawn_rpc","zdo"]}},"required":["prefab","name_key","x","z","biome","summoner_platform_user_id","method"],"additionalProperties":false},"BossEngagedData":{"type":"object","properties":{"prefab":{"type":"string"},"name_key":{"type":"string"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"alert_message":{"type":"string"},"nearby":{"type":"array","items":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."}}},"required":["prefab","name_key","x","z","biome","alert_message","nearby"],"additionalProperties":false},"BossDefeatedData":{"type":"object","properties":{"key":{"type":"string"},"first_time":{"type":"boolean"},"sender_platform_user_id":{"type":["string","null"],"description":"The owner peer of the boss, not necessarily the killer."},"nearby":{"type":"array","items":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"description":"Platform user ids within 200 m of the sender."},"prefab":{"type":["string","null"]},"name_key":{"type":["string","null"]},"participants":{"type":"array","items":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"description":"Platform ids of players whose attackers flag is set on the boss ZDO; empty when the ZDO was not located."}},"required":["key","first_time","sender_platform_user_id","nearby","prefab","name_key","participants"],"additionalProperties":false},"GlobalKeySetData":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":["string","null"]},"first_time":{"type":"boolean"}},"required":["key","value","first_time"],"additionalProperties":false},"RaidStartedData":{"type":"object","properties":{"name":{"type":"string"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"duration_s":{"type":"number","minimum":0},"nearby":{"type":"array","items":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."}}},"required":["name","x","z","biome","duration_s","nearby"],"additionalProperties":false},"RaidEndedData":{"type":"object","properties":{"name":{"type":"string"},"elapsed_s":{"type":"number","minimum":0}},"required":["name","elapsed_s"],"additionalProperties":false},"StructureBuiltData":{"type":"object","properties":{"prefab":{"type":"string"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"creator_character_id":{"type":"integer"},"creator_platform_user_id":{"type":["string","null"],"description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."}},"required":["prefab","x","z","biome","creator_character_id","creator_platform_user_id"],"additionalProperties":false},"StructureDestroyedData":{"type":"object","properties":{"prefab":{"type":"string"},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"creator_character_id":{"type":["integer","null"]}},"required":["prefab","x","z","biome","creator_character_id"],"additionalProperties":false},"CreatureDiedData":{"type":"object","properties":{"prefab":{"type":"string"},"level":{"type":"integer","minimum":1},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"},"credited":{"type":"array","items":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."}},"nearby":{"type":"array","items":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."}}},"required":["prefab","level","x","z","biome","credited","nearby"],"additionalProperties":false},"ChatMessageData":{"type":"object","properties":{"platform_user_id":{"type":"string","description":"Raw platform user id as the game formats it, for example Steam_76561198012345678."},"kind":{"type":"string","enum":["shout","ping","say"]},"text":{"type":["string","null"]},"x":{"type":"number","description":"World x coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"z":{"type":"number","description":"World z coordinate in metres; the world is a disc of radius 10000 m centred on 0,0."},"biome":{"$ref":"#/components/schemas/Biome"}},"required":["platform_user_id","kind","text","x","z","biome"],"additionalProperties":false},"ServerStartedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"server.started"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/ServerStartedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"ServerStoppingEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"server.stopping"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/ServerStoppingData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"ServerHeartbeatEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"server.heartbeat"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/ServerHeartbeatData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"ServerLostEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"server.lost"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/ServerLostData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"WorldSaveStartedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"world.save_started"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/WorldSaveStartedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"WorldSavedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"world.saved"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/WorldSavedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"WorldRollbackDetectedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"world.rollback_detected"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/WorldRollbackDetectedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"PlayerJoinedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"player.joined"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/PlayerJoinedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"PlayerSpawnedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"player.spawned"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/PlayerSpawnedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"PlayerDiedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"player.died"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/PlayerDiedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"PlayerLeftEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"player.left"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/PlayerLeftData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"PlayerBiomeChangedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"player.biome_changed"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/PlayerBiomeChangedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"PlayerPositionEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"player.position"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/PlayerPositionData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"BossSummonedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"boss.summoned"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/BossSummonedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"BossEngagedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"boss.engaged"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/BossEngagedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"BossDefeatedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"boss.defeated"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/BossDefeatedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"GlobalKeySetEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"global_key.set"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/GlobalKeySetData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"RaidStartedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"raid.started"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/RaidStartedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"RaidEndedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"raid.ended"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/RaidEndedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"StructureBuiltEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"structure.built"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/StructureBuiltData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"StructureDestroyedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"structure.destroyed"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/StructureDestroyedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"CreatureDiedEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"creature.died"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/CreatureDiedData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"ChatMessageEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"UUID v4 generated by the plugin."},"seq":{"type":"integer","minimum":0,"description":"Monotonic per run."},"run_id":{"type":"string","format":"uuid","description":"Identifies one server process start."},"ts":{"type":"string","format":"date-time","description":"UTC time from the game host clock."},"type":{"type":"string","const":"chat.message"},"world_day":{"type":"integer"},"data":{"$ref":"#/components/schemas/ChatMessageData"},"received_at":{"type":"string","format":"date-time","description":"When the ingest endpoint accepted the event; present on stored events, absent in batches."}},"required":["id","seq","run_id","ts","type","world_day","data"],"additionalProperties":false},"TelemetryEvent":{"description":"One event as sent by the plugin: the envelope with the data shape of its type.","oneOf":[{"$ref":"#/components/schemas/ServerStartedEvent"},{"$ref":"#/components/schemas/ServerStoppingEvent"},{"$ref":"#/components/schemas/ServerHeartbeatEvent"},{"$ref":"#/components/schemas/WorldSaveStartedEvent"},{"$ref":"#/components/schemas/WorldSavedEvent"},{"$ref":"#/components/schemas/PlayerJoinedEvent"},{"$ref":"#/components/schemas/PlayerSpawnedEvent"},{"$ref":"#/components/schemas/PlayerDiedEvent"},{"$ref":"#/components/schemas/PlayerLeftEvent"},{"$ref":"#/components/schemas/PlayerBiomeChangedEvent"},{"$ref":"#/components/schemas/PlayerPositionEvent"},{"$ref":"#/components/schemas/BossSummonedEvent"},{"$ref":"#/components/schemas/BossEngagedEvent"},{"$ref":"#/components/schemas/BossDefeatedEvent"},{"$ref":"#/components/schemas/GlobalKeySetEvent"},{"$ref":"#/components/schemas/RaidStartedEvent"},{"$ref":"#/components/schemas/RaidEndedEvent"},{"$ref":"#/components/schemas/StructureBuiltEvent"},{"$ref":"#/components/schemas/StructureDestroyedEvent"},{"$ref":"#/components/schemas/CreatureDiedEvent"},{"$ref":"#/components/schemas/ChatMessageEvent"}],"discriminator":{"propertyName":"type","mapping":{"server.started":"#/components/schemas/ServerStartedEvent","server.stopping":"#/components/schemas/ServerStoppingEvent","server.heartbeat":"#/components/schemas/ServerHeartbeatEvent","world.save_started":"#/components/schemas/WorldSaveStartedEvent","world.saved":"#/components/schemas/WorldSavedEvent","player.joined":"#/components/schemas/PlayerJoinedEvent","player.spawned":"#/components/schemas/PlayerSpawnedEvent","player.died":"#/components/schemas/PlayerDiedEvent","player.left":"#/components/schemas/PlayerLeftEvent","player.biome_changed":"#/components/schemas/PlayerBiomeChangedEvent","player.position":"#/components/schemas/PlayerPositionEvent","boss.summoned":"#/components/schemas/BossSummonedEvent","boss.engaged":"#/components/schemas/BossEngagedEvent","boss.defeated":"#/components/schemas/BossDefeatedEvent","global_key.set":"#/components/schemas/GlobalKeySetEvent","raid.started":"#/components/schemas/RaidStartedEvent","raid.ended":"#/components/schemas/RaidEndedEvent","structure.built":"#/components/schemas/StructureBuiltEvent","structure.destroyed":"#/components/schemas/StructureDestroyedEvent","creature.died":"#/components/schemas/CreatureDiedEvent","chat.message":"#/components/schemas/ChatMessageEvent"}}},"EventEnvelope":{"description":"Raw event envelope as stored: every plugin event type plus the two synthetic ones.","oneOf":[{"$ref":"#/components/schemas/ServerStartedEvent"},{"$ref":"#/components/schemas/ServerStoppingEvent"},{"$ref":"#/components/schemas/ServerHeartbeatEvent"},{"$ref":"#/components/schemas/ServerLostEvent"},{"$ref":"#/components/schemas/WorldSaveStartedEvent"},{"$ref":"#/components/schemas/WorldSavedEvent"},{"$ref":"#/components/schemas/WorldRollbackDetectedEvent"},{"$ref":"#/components/schemas/PlayerJoinedEvent"},{"$ref":"#/components/schemas/PlayerSpawnedEvent"},{"$ref":"#/components/schemas/PlayerDiedEvent"},{"$ref":"#/components/schemas/PlayerLeftEvent"},{"$ref":"#/components/schemas/PlayerBiomeChangedEvent"},{"$ref":"#/components/schemas/PlayerPositionEvent"},{"$ref":"#/components/schemas/BossSummonedEvent"},{"$ref":"#/components/schemas/BossEngagedEvent"},{"$ref":"#/components/schemas/BossDefeatedEvent"},{"$ref":"#/components/schemas/GlobalKeySetEvent"},{"$ref":"#/components/schemas/RaidStartedEvent"},{"$ref":"#/components/schemas/RaidEndedEvent"},{"$ref":"#/components/schemas/StructureBuiltEvent"},{"$ref":"#/components/schemas/StructureDestroyedEvent"},{"$ref":"#/components/schemas/CreatureDiedEvent"},{"$ref":"#/components/schemas/ChatMessageEvent"}],"discriminator":{"propertyName":"type","mapping":{"server.started":"#/components/schemas/ServerStartedEvent","server.stopping":"#/components/schemas/ServerStoppingEvent","server.heartbeat":"#/components/schemas/ServerHeartbeatEvent","server.lost":"#/components/schemas/ServerLostEvent","world.save_started":"#/components/schemas/WorldSaveStartedEvent","world.saved":"#/components/schemas/WorldSavedEvent","world.rollback_detected":"#/components/schemas/WorldRollbackDetectedEvent","player.joined":"#/components/schemas/PlayerJoinedEvent","player.spawned":"#/components/schemas/PlayerSpawnedEvent","player.died":"#/components/schemas/PlayerDiedEvent","player.left":"#/components/schemas/PlayerLeftEvent","player.biome_changed":"#/components/schemas/PlayerBiomeChangedEvent","player.position":"#/components/schemas/PlayerPositionEvent","boss.summoned":"#/components/schemas/BossSummonedEvent","boss.engaged":"#/components/schemas/BossEngagedEvent","boss.defeated":"#/components/schemas/BossDefeatedEvent","global_key.set":"#/components/schemas/GlobalKeySetEvent","raid.started":"#/components/schemas/RaidStartedEvent","raid.ended":"#/components/schemas/RaidEndedEvent","structure.built":"#/components/schemas/StructureBuiltEvent","structure.destroyed":"#/components/schemas/StructureDestroyedEvent","creature.died":"#/components/schemas/CreatureDiedEvent","chat.message":"#/components/schemas/ChatMessageEvent"}}},"StoredEvent":{"description":"One raw event with received_at.","allOf":[{"$ref":"#/components/schemas/EventEnvelope"},{"type":"object","properties":{"received_at":{"type":"string","format":"date-time"}},"required":["received_at"]}]},"EventPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/EventEnvelope"}},"next_cursor":{"type":["string","null"],"description":"Opaque cursor for the next page; null on the last page."}},"required":["items","next_cursor"],"additionalProperties":false},"IngestBatch":{"type":"object","description":"Signed batch posted by the plugin. The HMAC-SHA256 signature is computed over timestamp + \".\" + body.","properties":{"plugin":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"}},"required":["name","version"],"additionalProperties":false},"game":{"type":"object","properties":{"version":{"type":"string"},"network_version":{"type":"integer"}},"required":["version","network_version"],"additionalProperties":false},"server":{"type":"object","properties":{"name":{"type":"string"},"world":{"type":"string"},"world_uid":{"type":"integer"}},"required":["name","world","world_uid"],"additionalProperties":false},"events":{"type":"array","items":{"$ref":"#/components/schemas/TelemetryEvent"},"maxItems":200,"description":"Sorted by seq before processing. At most 200 events and 512 KB per request."}},"required":["plugin","game","server","events"],"additionalProperties":false},"IngestResult":{"type":"object","properties":{"accepted":{"type":"integer","minimum":0},"duplicates":{"type":"integer","minimum":0},"last_seq":{"type":["integer","null"],"minimum":0,"description":"Highest seq in the batch, null for an empty batch."}},"required":["accepted","duplicates","last_seq"],"additionalProperties":false},"StreamFrame":{"type":"object","description":"One server-sent event as the stream serializes it: an event line with the event name, an id line for activity frames and a data line holding the JSON document.","properties":{"event":{"type":"string","enum":["status","online","activity"]},"id":{"type":["string","null"],"description":"The event id for activity frames, null otherwise."},"data":{"description":"Status for status frames, OnlineList for online frames, ActivityItem for activity frames.","oneOf":[{"$ref":"#/components/schemas/Status"},{"$ref":"#/components/schemas/OnlineList"},{"$ref":"#/components/schemas/ActivityItem"}]}},"required":["event","id","data"],"additionalProperties":false},"ZoneRating":{"type":"string","enum":["excellent","strong","acceptable","weak","poor"],"description":"Band of the overall score, 90, 75, 60 and 40 being the lower bounds of the first four."},"ZoneRecommendation":{"type":"string","enum":["primary","backup","avoid"],"description":"Whether the guild should hand this player a zone."},"ZoneTestStatus":{"type":"string","enum":["ok","failed","partial","skipped"]},"ZoneValueSource":{"type":"string","enum":["measured","reported","unavailable"],"description":"Whether a system value was measured, reported by the browser or unavailable."},"ZonePenaltyId":{"type":"string","enum":["net-fail-severe","net-fail-high","net-fail-moderate","jitter-extreme","jitter-high","latency-extreme","latency-high","cpu-failed","network-failed","unstable-bench"]},"ZoneTarget":{"type":"object","description":"The probe the network figures were measured against.","properties":{"label":{"type":"string","minLength":1,"maxLength":80},"endpoint":{"type":"string","minLength":1,"maxLength":500}},"required":["label","endpoint"],"additionalProperties":false},"ZoneSystem":{"type":"object","description":"What the browser reports about the machine.","properties":{"logicalProcessors":{"type":["integer","null"],"minimum":1},"logicalProcessorsSource":{"$ref":"#/components/schemas/ZoneValueSource"},"deviceMemoryGB":{"type":["number","null"]},"deviceMemorySource":{"$ref":"#/components/schemas/ZoneValueSource"},"gpuRenderer":{"type":["string","null"],"maxLength":200},"gpuVendor":{"type":["string","null"],"maxLength":200},"gpuSource":{"$ref":"#/components/schemas/ZoneValueSource"},"browser":{"type":["string","null"],"maxLength":80},"browserSource":{"$ref":"#/components/schemas/ZoneValueSource"},"platform":{"type":["string","null"],"maxLength":80},"platformSource":{"$ref":"#/components/schemas/ZoneValueSource"},"hardwareConcurrency":{"type":["integer","null"],"minimum":1},"userAgentDataBrands":{"type":["array","null"],"items":{"type":"string"}}},"required":["logicalProcessors","logicalProcessorsSource","deviceMemoryGB","deviceMemorySource","gpuRenderer","gpuVendor","gpuSource","browser","browserSource","platform","platformSource","hardwareConcurrency","userAgentDataBrands"],"additionalProperties":false},"ZoneCpu":{"type":"object","description":"Throughput of the fixed integer kernel in iterations per millisecond.","properties":{"singleThread":{"type":["number","null"]},"multiThread":{"type":["number","null"]},"variance":{"type":["number","null"],"description":"Coefficient of variation of the single-thread samples."},"samples":{"type":"array","items":{"type":"number"},"maxItems":32},"workersUsed":{"type":["integer","null"],"minimum":0},"kernel":{"type":"string","const":"vzd-cpu-1.0.0"}},"required":["singleThread","multiThread","variance","samples","workersUsed","kernel"],"additionalProperties":false},"ZoneNetwork":{"type":"object","description":"Round trips and transfers against the probe.","properties":{"latencyMedianMs":{"type":["number","null"]},"latencyP95Ms":{"type":["number","null"]},"jitterMs":{"type":["number","null"],"description":"Mean absolute successive difference of the round trips."},"uploadMbps":{"type":["number","null"]},"downloadMbps":{"type":["number","null"]},"failureRate":{"type":["number","null"],"description":"Failed requests over total requests, 0 to 1."},"latencySamplesMs":{"type":"array","items":{"type":"number"},"maxItems":40},"failedRequests":{"type":"integer","minimum":0},"totalRequests":{"type":"integer","minimum":0},"endpointReachable":{"type":"boolean"}},"required":["latencyMedianMs","latencyP95Ms","jitterMs","uploadMbps","downloadMbps","failureRate","latencySamplesMs","failedRequests","totalRequests","endpointReachable"],"additionalProperties":false},"ZoneStability":{"type":"object","description":"Frame timing on the page and a GPU fill probe.","properties":{"frameTimeP95Ms":{"type":["number","null"]},"frameTimeMedianMs":{"type":["number","null"]},"stallCount":{"type":["integer","null"],"minimum":0,"description":"Frames longer than 50 ms during the sample."},"gpuFrameMs":{"type":["number","null"]},"gpuApi":{"type":"string","enum":["webgl2","webgl","none"]}},"required":["frameTimeP95Ms","frameTimeMedianMs","stallCount","gpuFrameMs","gpuApi"],"additionalProperties":false},"ZoneMeasurements":{"type":"object","properties":{"cpu":{"$ref":"#/components/schemas/ZoneCpu"},"network":{"$ref":"#/components/schemas/ZoneNetwork"},"stability":{"$ref":"#/components/schemas/ZoneStability"}},"required":["cpu","network","stability"],"additionalProperties":false},"ZoneScores":{"type":"object","description":"Component scores and the weighted overall, 0 to 100 integers.","properties":{"network":{"type":"integer","minimum":0,"maximum":100},"cpu":{"type":"integer","minimum":0,"maximum":100},"stability":{"type":"integer","minimum":0,"maximum":100},"secondary":{"type":"integer","minimum":0,"maximum":100},"overall":{"type":"integer","minimum":0,"maximum":100}},"required":["network","cpu","stability","secondary","overall"],"additionalProperties":false},"ZonePenalty":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/ZonePenaltyId"},"amount":{"type":"number","minimum":0,"description":"Points subtracted from the overall score."},"message":{"type":"string"}},"required":["id","amount","message"],"additionalProperties":false},"ZoneCompletion":{"type":"object","properties":{"cpu":{"$ref":"#/components/schemas/ZoneTestStatus"},"network":{"$ref":"#/components/schemas/ZoneTestStatus"},"stability":{"$ref":"#/components/schemas/ZoneTestStatus"},"tabLostFocus":{"type":"boolean"},"interrupted":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"string"}}},"required":["cpu","network","stability","tabLostFocus","interrupted","warnings"],"additionalProperties":false},"ZoneResult":{"type":"object","description":"One zone-leader measurement, schema version 1 of the zone-leader diagnostic: the same document the browser downloads.","properties":{"schemaVersion":{"type":"integer","const":1},"diagnosticVersion":{"type":"string","minLength":1,"description":"Semantic version of the scoring model; major and minor must match the site's."},"player":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":48}},"required":["name"],"additionalProperties":false},"testedAt":{"type":"string","format":"date-time"},"diagnosticTarget":{"$ref":"#/components/schemas/ZoneTarget"},"system":{"$ref":"#/components/schemas/ZoneSystem"},"measurements":{"$ref":"#/components/schemas/ZoneMeasurements"},"scores":{"$ref":"#/components/schemas/ZoneScores"},"rating":{"$ref":"#/components/schemas/ZoneRating"},"penalties":{"type":"array","items":{"$ref":"#/components/schemas/ZonePenalty"}},"completion":{"$ref":"#/components/schemas/ZoneCompletion"}},"required":["schemaVersion","diagnosticVersion","player","testedAt","diagnosticTarget","system","measurements","scores","rating","penalties","completion"],"additionalProperties":false},"ZoneExplanation":{"type":"object","description":"Deterministic sentences derived from the measurements.","properties":{"summary":{"type":"string"},"strongest":{"type":"array","items":{"type":"string"}},"limiting":{"type":"array","items":{"type":"string"}},"reason":{"type":"string","description":"Why the recommendation is what it is."}},"required":["summary","strongest","limiting","reason"],"additionalProperties":false},"ZoneRankedResult":{"type":"object","properties":{"rank":{"type":"integer","minimum":1},"name":{"type":"string","description":"The normalised character name the result is stored under."},"tested_at":{"type":"string","format":"date-time"},"rating":{"$ref":"#/components/schemas/ZoneRating"},"recommendation":{"$ref":"#/components/schemas/ZoneRecommendation"},"scores":{"$ref":"#/components/schemas/ZoneScores"},"explanation":{"$ref":"#/components/schemas/ZoneExplanation"},"result":{"$ref":"#/components/schemas/ZoneResult"}},"required":["rank","name","tested_at","rating","recommendation","scores","explanation","result"],"additionalProperties":false},"ZoneResultList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ZoneRankedResult"},"description":"Ranked best first."}},"required":["items"],"additionalProperties":false},"ProbeHealth":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"},"version":{"type":"string","description":"The diagnostic version the site scores with."}},"required":["ok","service","version"],"additionalProperties":false},"ProbePing":{"type":"object","properties":{"t":{"type":"integer","description":"Server clock in milliseconds since the epoch."}},"required":["t"],"additionalProperties":false},"ProbeUpload":{"type":"object","properties":{"received":{"type":"integer","minimum":0,"description":"Bytes received."}},"required":["received"],"additionalProperties":false}}}}