WebSocket
The WebSocket provides real-time bidirectional communication between the server and its clients (the Creature Console, Creature Controller, etc.).
GET /api/v1/websocket — Upgrade to a WebSocket connection.
Client → Server Messages
- Notice — General notice messages from clients
- StreamFrame — DMX frame data for streaming playback
- BoardSensorReport — Board-level sensor data from a Raspberry Pi (temperature, voltage, etc.)
- MotorSensorReport — Motor sensor data from a Raspberry Pi (current draw, position feedback, etc.)
- DynamixelSensorReport — Dynamixel servo telemetry from a Raspberry Pi, one entry per servo on the bus (servo ID, temperature, present load, voltage, position)
Server → Client Messages
- Database — Database change notifications
- LogMessage — Server log messages
- ServerCounters — Periodic system metrics
- VirtualStatusLights — Status light state updates (the virtual version of the physical LEDs from the Pi hat era)
- UpsertCreature — Creature configuration change notifications
- CacheInvalidation — Cache invalidation signals. The
cache_typefield is one ofcreature,animation,playlist,sound-list,ad-hoc-animation-list,ad-hoc-sound-list,fixture,dialog-script-list, orstoryboard-list - PlaylistStatus — Playlist state changes
- JobProgress — Progress updates for async jobs (lip sync generation, ad-hoc animations, dialog renders)
- JobComplete — Job completion notifications with results
- IdleStateChanged — Idle loop enable/disable notifications
- CreatureActivity — Creature activity reports (what each creature is currently doing)
Metrics
GET /api/v1/metric/counters — Get system performance counters — frames processed, events dispatched, WebSocket messages sent, etc.
Debug
Utility endpoints for development and debugging. These trigger cache invalidation messages on connected clients.
GET /api/v1/debug/cache-invalidate/creature — Broadcast a creature cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/animation — Broadcast an animation cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/playlist — Broadcast a playlist cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/sound-list — Broadcast a sound-list cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/ad-hoc-animation-list — Broadcast an ad-hoc-animation-list cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/ad-hoc-sound-list — Broadcast an ad-hoc-sound-list cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/fixture — Broadcast a fixture cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/dialog-script-list — Broadcast a dialog-script-list cache invalidation to all connected clients.
GET /api/v1/debug/cache-invalidate/storyboard-list — Broadcast a storyboard-list cache invalidation to all connected clients.
GET /api/v1/debug/playlist/update — Test playlist update broadcast to connected clients.
System
GET /api/v1/health — Health check endpoint. Returns the canonical envelope: {"status": "ok", "code": 200, "message": "Server is operational", "session_id": null}. See Error Envelope for the shape used by every non-entity JSON response.
Status Codes
The server uses these HTTP status codes consistently:
- 200 — Success
- 202 — Accepted (async job started, check WebSocket for progress)
- 400 — Bad Request (invalid input — client’s fault)
- 403 — Forbidden (path traversal attempt on file endpoints)
- 404 — Not Found
- 409 — Conflict (e.g., creature not registered to a universe)
- 422 — Unprocessable Entity (missing required fields for processing)
- 500 — Internal Server Error
Error Envelope
Every JSON response that isn’t a typed entity — every 4xx, every 5xx, and a few 2xx (DELETE confirmations, health) — uses the canonical StatusDto shape:
{
"status": "ok", // "ok" for 2xx, "not_found" for 404, "error" otherwise
"code": 200, // matches the HTTP status code
"message": "Storyboard deleted",
"session_id": null // only set for playback endpoints that returned a session
}
The status field is one of "ok", "error", or "not_found" (all lowercase). Clients can use it as a cheap discriminator without parsing the numeric code.