Skip to main content

HTTP and WebSocket

Route tables below are generated from crates/booth-api/src/{lib,lab,lab_learning,lab_packs,live_dj}.rs. The Implemented sections list every route the daemon actually serves; the Proposed section keeps the target contract that has no implementation yet. See current status and the software wire contract for exact DTOs.

Every route is mounted under /api/v1 except GET /healthz, which is unauthenticated and used by the Kubernetes probes. All other routes require Authorization: Bearer <token> matching the daemon's configured booth token; a missing or wrong token returns 401 with {"error": "Authentication required"}. CORS allows only the origins in BOOTH_UI_ORIGINS (default http://localhost:3000,http://127.0.0.1:3000) and only GET/POST.

In deployment the browser never holds this token: aidj-ui keeps it server-side and exposes scoped routes such as /api/live-clubs/{club}/autopilot. Ownership and role checks (owner / DJ / listener) are enforced per request inside the handlers, not by the router.

Booth state and commands​

Method / pathPurpose
GET /healthzLiveness/readiness probe. Unauthenticated, returns ok
GET /api/v1/stateMetadata booth snapshot
POST /api/v1/commandsSubmit a CommandEnvelope
GET /api/v1/wsWebSocket upgrade for the metadata playground

The four-deck metadata booth behind these routes is a developer harness. It does not control the audible offline renderer or the live club runtime.

Library​

Method / pathPurpose
GET /api/v1/labLab capability and configuration summary
GET /api/v1/libraryWorkspace tracks
GET /api/v1/library/catalogPaged, filterable catalog view
GET /api/v1/library/compatibilityTempo/key compatibility view
POST /api/v1/library/importUpload and import an asset (150 MB body limit)
POST /api/v1/library/demoCreate the procedural demo library
GET /api/v1/library/{id}Track detail
GET /api/v1/library/{id}/audioTrack audio stream
POST /api/v1/library/{id}/reviewSubmit reviewed BPM, first beat, phrase length and key
POST /api/v1/library/{id}/analyzeRecompute native descriptors without changing reviewed values
GET /api/v1/library/{id}/musical-analysisStored deep analysis report
GET/POST /api/v1/library/{id}/annotationsHuman reference labels for downbeats, phrases and vocals
POST /api/v1/library/{id}/similarQdrant similarity with Mongo revalidation
GET/POST /api/v1/library/jobsList or enqueue processing jobs
POST /api/v1/library/jobs/{id}/controlPause, resume, cancel or retry a job
GET /api/v1/library/sourcesConfigured folder sources
GET /api/v1/library/sources/{id}/filesFiles discovered under a source
POST /api/v1/library/sources/{id}/controlPause or resume a source scan
GET/POST /api/v1/library/packsList or create library packs
GET/PUT /api/v1/library/packs/{id}Read or update one pack

Annotations are stored and served, but no planner or grid-review path reads them yet. Submitting a human phrase label does not currently make a grid verified.

Offline B2B sessions​

Method / pathPurpose
GET/POST /api/v1/sessionsList sessions, or start a render job
GET /api/v1/sessions/{id}Progress, decisions and metrics
POST /api/v1/sessions/{id}/controlPause, resume or cancel
POST /api/v1/sessions/{id}/replayRe-render from recorded decisions
GET /api/v1/sessions/{id}/artifacts/{name}Fetch mix.wav, manifest.json, booth.jsonl and similar

Cancelling a render preserves partial artifacts with an incomplete status. Replay verifies execution against the original output hash and does not insert new learning observations.

Transition memory​

Method / pathPurpose
GET/POST /api/v1/transition-recipesList seeded recipes, or save a new immutable id/version
GET /api/v1/transitionsRanked attempts with technical metrics and reviews
POST /api/v1/transition-auditionsRender a controlled pair/recipe experiment
POST /api/v1/transitions/{id}/reviewsSubmit a listening review, including avoid
GET/POST /api/v1/transitions/preferencesList, or record, one blind comparison: winner, loser, tie, reviewer, notes
GET /api/v1/transitions/next-comparisonThe uncompared pairs most worth listening to, fewest differing factors first. Only renders whose mix.wav is still on disk are offered; the response counts the renders left out (skipped_missing_audio) and earlier ratings on now-unplayable pairs (unheard_ratings)
POST /api/v1/transitions/preferences/discard-unheardWithdraw every comparison with a side whose audio is no longer on disk (rated without listening). Archived to preferences_voided with the reason, never deleted; returns discarded and remaining
GET /api/v1/transitions/loop-statusExperiments by provenance, labels, comparisons needed, factor effects against noise, what blocks training

Learning studio​

Method / pathPurpose
GET/POST /api/v1/learningLearning state, or update settings
GET /api/v1/learning/jobsQueued and completed practice experiments
GET /api/v1/learning/catalogExternal research catalog
GET /api/v1/learning/techniquesVersioned technique concept catalog
POST /api/v1/learning/linksLink a catalog entry to a local recording
GET /api/v1/llm/usageModel request counts and budget state

Training itself is not served over HTTP. analyzerd dj-learn fits the pairwise model on stored comparisons and saves it unapproved; analyzerd dj-learn approve LABEL deploys it only if held-out accuracy beat the coin flip. Both rankers load the approved model at planning time. analyzerd dj-priors refreshes the per-genre human-practice prior.

Live booth​

Method / pathPurpose
GET/POST /api/v1/live-djLive session status, or a control action
GET /api/v1/live-dj/recipesRecipes the live executor can run

POST /api/v1/live-dj accepts a tagged action: start, stop, mode, energy, skip_next, refresh_advice, model_budget, recipe, mixing, takeover, execute, manual, manual_loaded and roster (save the AI DJ roster; refused during a set). The status payload includes the current and next track, position, phase, ranked alternatives, region evidence, the selected plan and mix_point (the planned exit position and section, entry cue and section, technique and overlap).

Live sets​

Method / pathPurpose
GET/POST /api/v1/live-setsRecorded and edited sets; create a mix from a recording or from tracks
GET/POST /api/v1/live-sets/{id}A set with its offline schedule; edit actions (rename, reorder, settings, seam_options, seam_apply, seam_clear, seam_edit, step_cue, paste, auto_fill, delete)
GET/POST /api/v1/live-sets/{id}/renderRender progress; start an offline render (no model)
GET /api/v1/live-sets/{id}/render/mix.wavThe rendered mix
GET /api/v1/live-sets/{id}/render/peaksWaveform overview of the rendered mix (peaks per column)
POST/GET /api/v1/live-sets/{id}/preview[/{session}[/mix.wav]]Render and fetch a short clip of one seam

See Set studio.

Runtime engine endpoints are server-owned and never accepted from a client: BOOTH_LIVE_MIXER_URL, BOOTH_LIVE_PLAYER_URLS and BOOTH_LIVE_MEDIA_PREFIX.

Proposed, not implemented​

These appeared in earlier revisions of this page as though they existed. They do not.

Method / pathIntentStatus
GET /api/v1/devicesDevice identities, modes, freshness, capabilitiesHardware adapters are post-MVP
GET /api/v1/tracksRegistered track metadataSuperseded by /api/v1/library
GET /api/v1/configEffective non-secret configurationNot implemented
POST /api/v1/simulator/startInstantiate a scenarioNo simulator lifecycle route exists
POST /api/v1/simulator/stopStop simulation explicitlyNo simulator lifecycle route exists
POST /api/v1/sessions/{id}/stopFinalize a recordingUse POST /api/v1/sessions/{id}/control

There is also no route that returns a track's derived arrangement — its phrase-aligned mix-in and mix-out candidates. The planner computes them and the live status exposes the chosen one, but no client can list them for a track.

Recording lifecycle and simulation lifecycle are intended to stay distinct: stopping a recording must not stop playback.

Illustrative command exchange​

{
"schema_version": 1,
"session_id": "demo",
"command_id": "cmd-001",
"ownership_generation": 1,
"payload": { "type": "Play", "deck_id": 1 }
}

The server derives actor identity from the authenticated connection. It first returns a receipt tied to command_id; an applied event later supplies the sequence, output frame, and resulting state revision. Rejected commands carry stable reason codes such as unsupported, not_owner, stale_revision, or invalid_value.

Use JSON initially. A stream starts with a versioned snapshot and cursor; subscription setup must avoid a race between snapshot capture and subsequent events. Bound outbound queues, coalesce meters, and force resynchronization rather than silently dropping authoritative events. Reject incompatible schema versions explicitly.

Bind to loopback by default. For LAN operation, define authentication, allowed browser origins, viewer/controller roles, and transport protection. Require authentication on control-plane HTTP routes as well as WebSocket upgrades. Avoid logging credentials or raw track filesystem paths.