Status and health
GET /api/session/status for a session summary and GET /api/health for a bare liveness check.
Status
curl -H "X-Broker-Secret: $BROKER_SECRET" http://localhost:3000/streaming/api/session/statusSend the broker secret as X-Broker-Secret when one is set, since the answer
names players and ROMs. If no session is running, it answers
{"active": false, "last_exit": ...}. If one is running, you get:
| Field | Meaning |
|---|---|
active | Whether a session is currently running. |
session_id, emulator, rom, rom_file | Which session, emulator, and ROM were activated, and the exact file the broker chose to boot. |
multiplayer | Whether multiplayer is on. This is set once, when the session is activated, and doesn't change after that. |
emulator_alive | Whether the emulator process is still running. |
boot_failed | True when an emulator can tell its own process is alive but never actually reached a running game, for example because it's stuck on a boot-error dialog. This is a passive signal: the broker only reports it and doesn't act on it. |
extraction_phase | null, "extracting_archive", or "extracting_pkg". Set while shadPS4, RPCS3, PPSSPP or ScummVM is unpacking an archived ROM (extracting_archive), or shadPS4 a .pkg (extracting_pkg), and cleared back to null once unpacking ends. At that point the emulator still hasn't started yet, so null here doesn't mean the game is running; check emulator_alive for that. Like boot_failed, this is a passive signal: poll it to show a plain loading spinner while it isn't null. There's no percentage to show. |
supports_states | Whether save and load states work at all for this emulator, so the parent (usually RomM) doesn't need to keep its own list of which emulators support them. |
state_slot | The one slot this emulator uses. Every save and load echoes this same number back. |
started_at | Unix time (seconds since January 1, 1970) marking when the session was created. |
user | The controller's info (the person playing), exactly as it was given when the session was activated. |
viewers | Everyone who joined: username, user_id, and permission. |
last_exit | How the most recent exit ended, in both shapes, or null before the first exit since the broker started: session_id, ended_at (Unix time), duration_s, state_saved, dump_error (null unless the save dump failed), upload (uploaded, skipped, failed or report-only in dev mode) and archive_path (where a copy was kept on the container, if one was). It survives the next activate, so a save archive that never reached RomM stays visible until another exit replaces it. |
RomM polls this to know whether a session it launched is still running, to decide whether to offer save and load, and to show the player a boot failure instead of leaving them staring at a frozen frame.
Health
curl http://localhost:3000/streaming/api/healthAnswers {"status": "ok"} as soon as the broker is up and serving requests.
Inside the container, svc-broker waits for selkies (the video streaming
piece) to answer before it starts the broker at all, so a healthy broker also
means selkies is up and reachable.
Room context
curl "http://localhost:3000/streaming/api/session/context?token=<personal token>"This is what the room UI reads when it loads: who the token belongs to, what
that person is allowed to do, and the session's rom and emulator. It doesn't
say who else is in the room; that roster arrives separately, over the room's
websocket state_update broadcast. It answers 409 when there's no session,
and 401 for a token that isn't part of it. Opened with ?invite=...
instead, it seats the arrival first, so it can also answer 429 when the
room is full, or 409 when another session operation is already running. It's documented here because
it's useful when you're troubleshooting a room that shows "Session Ended",
but it isn't part of the parent-facing API (the endpoints meant for the
parent, usually RomM, to call).