18-LAB / Documentation

Developer API

vosu serves HTTP and WebSocket APIs at http://127.0.0.1:24050 by default. Installed counters are served from that same origin, for example /my-counter/. vosu supplies telemetry; vosulay handles in-game rendering. vosu is not affiliated with tosu or ppy.

Choose an API

Family HTTP WebSocket Use
gosuMemory v1 /json /ws Existing v1 counters
streamCompanion /json/sc /tokens Existing token consumers
v2 /json/v2 /websocket/v2 New overlays and structured game state
Precise v2 /json/v2/precise /websocket/v2/precise Keys and timing-error data
Selected fields vosu only — /websocket/v2/subscribe Only the v2 fields your overlay needs
Commands Counter settings GET /websocket/commands Settings reads and compatibility filters

For new overlays, use v2 and precise v2. Prefer the selected-field stream when available; it selects from the regular v2 document, including vosu's added keys. For tosu fallback, regular v2 does not include keys: use its precise stream. See extensions and feature detection.

The selected-field stream is change-only: after its initial baseline, each update is an event naming exactly which selected fields changed or disappeared. If nothing changed, vosu sends no update. Overlays can react to those events without client-side diffing, polling, or parsing the full document; compatibility streams republish the whole document every poll interval.

Readiness and delivery

State HTTP requests return 500 {"error":"osu is not ready/running"} until a focused ready instance is published. Treat this as readiness, not evidence of a broken HTTP server. Compatibility streams can also carry error documents; do not assume every received object has beatmap or play.

WebSocket frames and assembled inbound messages are limited to 1 MiB. Slow clients receive latest-state delivery, not an unbounded replay of every sample. Subscription revisions are snapshots, not an event log; arrays and counts must be interpreted accordingly.

Start building

Source: published README.

Minimal selected-field example

Ask for three fields. Get three fields. vosu speaks tosu's APIs, so overlays you write today run on both. When vosu is the backend, the selected-field stream sends only the JSON Pointers you subscribe to, and only when they change. The tutorial starts there and falls back to tosu cleanly. In this excerpt, render is your overlay's rendering function:

// vosu: stream only the fields this overlay draws
const fields = ["/play/pp/current", "/play/accuracy", "/play/combo/current"];
const url = "ws://127.0.0.1:24050/websocket/v2/subscribe";
const ws = new WebSocket(url);

ws.onopen = () => ws.send(JSON.stringify(fields));
ws.onmessage = ({ data }) => {
  // [0, rev, pairs] once, then [1, rev, pairs, removed]
  const [kind, , pairs] = JSON.parse(data);
  if (kind > 1) return; // [2, code, message] is an error
  for (const [i, value] of pairs) render(fields[i], value);
};

Edit this page on GitHub