Skip to content

WebSocket

Pavel Erokhin edited this page Oct 19, 2026 · 1 revision

The live feed: subscribe once, get a snapshot of the current state, then every change. It's one endpoint, /api/v1/ws.

1. Connect

Connect to wss://<your-domain>/worldapi/api/v1/ws, or ws://localhost:8110/api/v1/ws on the server itself. Send the token in the Authorization header, or as the first message if your client can't set headers. Never put it in the URL. Visitors without a token may subscribe to the topics in websocket.anonymousTopics.

2. Subscribe

{ "op": "auth", "token": "…" }
{ "op": "subscribe", "topics": ["player.join", "player.death", "world.time"], "filter": { "player": "Steve" } }
{ "op": "unsubscribe", "topics": ["world.time"] }
{ "op": "ping" }

3. Read what comes back

The server answers with hello (the heartbeat interval, your permissions, and the topics you may use), authenticated, subscribed, then a snapshot of the current state for topics that have one, then event messages as things happen. heartbeat arrives every 20 seconds.

{ "op": "event", "topic": "player.death", "event": {
    "type": "player.death", "at": "2026-10-11T15:46:27Z", "atMillis": 1791733587000,
    "player": { "uuid": "…", "name": "Steve" }, "world": "world",
    "data": { "message": "Steve was slain by Zombie", "cause": "minecraft:mob_attack", "level": 12 } } }

In the browser:

const ws = new WebSocket("wss://mc.example.com/worldapi/api/v1/ws");
ws.onopen = () => ws.send(JSON.stringify({ op: "subscribe", topics: ["player.join", "player.death"] }));
ws.onmessage = (message) => {
  const data = JSON.parse(message.data);
  if (data.op === "event") console.log(data.topic, data.event.player?.name, data.event.data);
};

Topics

Topic When
player.join, player.leave, player.kick Someone joins, leaves, or gets kicked. Snapshot: who's online
player.death, player.respawn Deaths with the message, cause, and killer; respawns with the bed or anchor
player.advancement An advancement with its title and frame (task, goal, challenge)
player.chat Chat messages, only when events.chat is on; chat:read only
player.command Commands players run; logs:read only
player.move Positions, at most once a second per player, only when they moved. Hidden from visitors by default
player.health, player.damage Health with its maximum, food, absorption, active effects, and whether the player is frozen, when any of them change; damage with its cause, at most four a second
player.inventory The full inventory when it changes
player.gamemode, player.level_up, player.sleep, player.world_change, player.portal What the names say
player.kill, player.fish, player.enchant, player.trade, player.craft Mob kills, catches, enchanting, villager trades, and crafting (added up over a few seconds)
world.time The clock once a second, with ticks until night, whether beds work, and jumped: true after a skipped night or a /time command
world.weather, world.lightning, world.night_skipped Weather changes, strikes, and nights everyone slept through
world.load, world.unload Worlds coming and going
entity.boss_killed The dragon, the wither, elder guardians, and wardens, with who was there
entity.death, entity.explode Mob deaths per type over a few seconds; explosions with their size
raid.start, raid.finish Raids, with the winners
block.break, block.place Blocks per player and type, added up over websocket.blockWindowSeconds
server.performance TPS, tick times, memory, and CPU every five seconds
server.status, server.plugin Start, stop, saves; plugins enabled and disabled
server.console Console lines as they're printed, colors stripped and tokens blanked; logs:read only
script.log Lines Java scripts log; code only
ext.<namespace>.<event> Other plugins' events (see Extensions)

Joins, leaves, kicks, deaths, advancements, chat, skipped nights, boss kills, raids, and server status also go to the history behind GET /events.

Privacy

Events about a vanished player, and their state in snapshots, reach clients with players:moderate only. Counts inside events (online in player.join, player.leave, and server.status; sleepers in player.sleep and world.night_skipped; players per world in server.performance) leave vanished players out for everyone.

Slow clients

Each client has its own queue. State topics (time, weather, positions, health, inventories, performance) keep only the newest value per player or world, so a slow client catches up instead of lagging behind. Other events queue up to websocket.queueSize; past that, the oldest are dropped and the client gets { "op": "dropped", "count": n }. A slow client never holds up the server or anyone else.

Next: Extensions.

Clone this wiki locally