HazR Documentation
HazR is a real-time MIDI-driven visual performance tool. Connect a MIDI controller, play notes, and watch a Three.js generative visual engine respond — live, in your browser, on any screen.
The name reflects the neurological phenomenon where stimulation of one sense triggers automatic experience of another. Here, sound becomes light.
Architecture at a glance
When you play a MIDI note, the signal travels through four stages:
- Browser — Web MIDI API captures the raw MIDI message
- Socket.IO — the note is forwarded to the server in real time
- Python engine — on Artist / Venue tiers, an algorithmic pattern is generated from the note and velocity
- Three.js renderer — the pattern is applied to a particle grid and rendered at 60 fps
System Requirements
Browser
HazR requires a browser with Web MIDI API support. The Web MIDI API is currently supported in:
| Browser | MIDI Support | Notes |
|---|---|---|
| Google Chrome 43+ | ✅ Full | Recommended |
| Microsoft Edge 79+ | ✅ Full | Chromium-based |
| Opera 30+ | ✅ Full | |
| Firefox | ❌ None | Not supported natively |
| Safari | ❌ None | Not supported |
MIDI Device
- Any USB class-compliant MIDI controller (keyboard, pad controller, drum machine)
- Connect directly via USB — no drivers required on modern operating systems
- Bluetooth MIDI works on macOS/iOS; performance may vary
- Virtual MIDI (DAW output) is supported on macOS and Windows
Hardware
- GPU: any dedicated or integrated GPU from 2015 onwards (WebGL 2.0 required)
- RAM: 4 GB minimum, 8 GB recommended for large screens
- Network: stable connection required for real-time pattern generation (Artist / Venue)
Quick Start
1. Create an account
Click Launch App on the product page. You will be redirected to the NXPRM identity provider. Register with your email address. A verification email will be sent — click the link to activate your account.
2. Log in to the dashboard
After registration, you land on your HazR dashboard. From here you can access the app, manage your subscription, and view usage analytics.
3. Connect your MIDI device
Plug in your MIDI controller via USB before or after opening the app. Chrome will prompt for MIDI access — click Allow. The status display at the top of the app will confirm when a device is detected.
4. Launch the app
Click Launch App from the dashboard or the nav bar. The Three.js canvas will load and the app will connect to the server. When the MIDI status shows "MIDI Input Connected", you are ready.
5. Play
Strike any key or pad on your controller. You will see the visual grid respond immediately — particle geometry shifts, colours rotate, and patterns evolve in sync with your playing. Computer keyboard keys A–L (home row) also trigger notes if no MIDI controller is connected.
MIDI Setup
Device detection
The browser requests MIDI access once on page load. If you plug in a device after the page loads, it will be detected automatically via the onstatechange callback — no reload required.
MIDI message types
HazR responds to Note On messages (MIDI command byte 0x90) and ignores Note Off (0x80). Two values from each Note On are used:
| Field | Range | Effect in HazR |
|---|---|---|
| Note number | 0 – 127 | Selects colour scheme, drives pattern generator |
| Velocity | 1 – 127 | Controls pattern density, brightness, and amplitude |
CC messages (Control Change, command byte 0xBN) are also read when MIDI CC Mapping is configured — see MIDI CC Mapping. The MIDI channel (1–16) is extracted from the status byte and used for channel-specific mappings.
Note-to-colour mapping
Colour schemes cycle through notes within each octave. Notes 36–84 (C2–C6) are the primary range. Notes outside this range are wrapped modulo 12 to the same scheme cycle. The active colour mode (0–50) determines the overall palette — see Color Modes.
Active notes
The app tracks all simultaneously held notes. Chords cause multiple colour scheme updates, with the last note received taking priority for pattern selection. Custom Modes (Artist+) receive the full active note list on every event.
Rate limiting
MIDI messages are forwarded to the server at a maximum rate of once every 50 ms to prevent flooding. Fast passages still trigger smooth visual changes — only the server pipeline is throttled, not the local Three.js response.
Visual Controls
The control panel appears on the right side of the app. All sliders update the visual in real time. Parameters are grouped into collapsible panels.
Pattern (0 – 19)
Selects the generative algorithm used to build the particle grid. Patterns 0–9 run in the browser (instant, no network). Patterns 10–19 are generated server-side by the Python engine and require Artist or Venue tier.
| Index | Name | Engine |
|---|---|---|
| 0 | Random | JavaScript |
| 1 | Checkerboard | JavaScript |
| 2 | Vertical Bars | JavaScript |
| 3 | Symmetric Triangle | JavaScript |
| 4 | Cascading Waves | JavaScript |
| 5 | Alternating Stripes | JavaScript |
| 6 | Noise Field | JavaScript |
| 7 | Spiral | JavaScript |
| 8 | Stacked Clusters | JavaScript |
| 9 | Circular Field | JavaScript |
| 10 | Perlin Flow | Python / NumPy |
| 11 | Voronoi Field | Python / NumPy |
| 12 | Reaction Diffusion | Python / NumPy |
| 13 | Lissajous Grid | Python / NumPy |
| 14 | Fibonacci Spiral | Python / NumPy |
| 15 | Cellular Automata | Python / NumPy |
| 16 | Interference Pattern | Python / NumPy |
| 17 | Fractal Tree Density | Python / NumPy |
| 18 | Harmonic Series | Python / NumPy |
| 19 | Gravity Wells | Python / NumPy |
Shape (0 – 9)
Selects the geometry applied to each particle. 10 distinct forms are available:
| Index | Shape |
|---|---|
| 0 | Rectangle |
| 1 | Circle |
| 2 | Triangle |
| 3 | Pentagon |
| 4 | Hexagon |
| 5 | Heptagon |
| 6 | Octagon |
| 7 | Parabola |
| 8 | Hyperbola |
| 9 | Star |
Shape changes are debounced at 100 ms to prevent flicker during rapid sliding.
Size (10 – 50)
Controls the camera zoom level. A lower value zooms out, showing the full grid at small scale. A higher value zooms in, creating a tighter, more abstract composition. For large projection screens, values of 12–18 are recommended.
Speed X / Speed Y (−2 to +2)
Scrolls the particle field along the X and Y axes. Zero freezes the field. Negative values reverse direction. Run both axes at different rates for diagonal or rotational motion.
Speed Z (−2 to +2)
Controls depth-axis movement in the Particle canvas mode. In other modes this parameter has no visual effect but is stored in templates and setlist cues.
Color Mode (0 – 50)
Selects from 51 colour palettes. Each palette maps note and velocity values to a distinct set of hues. See Color Modes for the full reference.
Opacity (0 – 1)
Controls the overall opacity of the visual canvas. At 1, the canvas is fully opaque. At 0, the canvas is invisible — useful for a clean blackout transition. Can be mapped to a MIDI CC for live fade-in/out control.
Particle Size (1 – 50)
Controls the size of individual particles in the Particle canvas mode. In other modes, this adjusts the scale of visual elements.
Visual Position X / Y (−100% to +100%)
Shifts the visual canvas position horizontally and vertically within its container. At 0/0 the canvas is centred. Useful for offset compositions or multi-screen setups where the visual should be off-centre.
Background
The Background panel allows uploading a static image (JPEG, PNG, WebP) or video (MP4, WebM) as a backdrop behind the particle canvas. Separate opacity sliders control the image and video overlay independently (0–1).
Text Overlay
Displays a text string on top of the visual canvas. Configurable font size, colour, X/Y position, and opacity. Rendered above the particle layer and below the logo overlay.
Fullscreen
The Fullscreen button enters browser fullscreen mode. The canvas resizes automatically. Press Esc to exit. Recommended for live performance projection.
Canvas Modes
HazR provides twenty-two distinct rendering modes (plus ten split-screen variants), selectable via the tab bar at the top of the app. Each mode uses a different visual engine and responds differently to MIDI.
Original modes
| Mode | Engine | Description |
|---|---|---|
| Abstract | Three.js grid | The default mode. A rectangular geometric grid where each cell's size and margin are set by the active pattern algorithm. All 20 patterns (0–19) apply here. |
| Cloud | Canvas 2D | Soft organic particles rendered across depth layers, producing a volumetric cloud-like atmosphere that reacts to MIDI velocity and note position. |
| Particle | Three.js Points | A physics simulation mode. MIDI notes and keyboard presses emit bursts of particles with velocity, gravity, and wind. Supports all 10 shapes and 51 colour modes. Speed X/Y control wind; Speed Z controls gravity. |
| Curvic | DOM (CSS) | CSS-based curvilinear elements with perspective transforms. The grid wraps across a cylindrical surface, creating depth and parallax. |
| Quadrat | DOM (CSS) | CSS-based rectangular and bar elements with 3D transforms and different aspect ratio constraints. |
Extended modes
| Mode | Engine | Description |
|---|---|---|
| Fusion | Canvas 2D | Animated nebula with multi-level Gaussian bloom, a ring-of-fire effect with rotating rays and orbiting hot-spots. Slider-driven ring count, amplitude, and glow. |
| Matrix | Canvas 2D | Digital rain effect with customizable character sets including binary, katakana, hexadecimal, Greek, math symbols, and more. Font size, fall speed, and trail intensity are all configurable. |
| Vector | Vanta.js NET | Animated node network with connecting lines. Fully slider-driven — points count, speed, max distance, spacing, and zoom are all mapped to the standard slider set. |
| Feedback | Canvas 2D | A feedback loop effect with zoom, rotation, and mirror transforms combined with continuous hue shifting. Each frame feeds back into the next, creating evolving recursive visuals. |
| Flowfield | Canvas 2D | Particles driven by noise-based flow fields. Direction and turbulence shift with MIDI input, producing organic stream-like motion across the canvas. |
| Metaballs | Canvas 2D | Organic merging blob shapes that combine and separate fluidly. MIDI velocity influences blob size and movement speed. |
| Wireframe | Canvas 2D | 3D wireframe primitives rendered with multiple line styles. Geometric solids rotate and transform in response to MIDI input. |
| Scope | Canvas 2D | Oscilloscope-style waveform display with multiple wave patterns. Amplitude and frequency respond to MIDI velocity and note number. |
| HUD | Canvas 2D | Heads-up display featuring radar sweeps, compass dials, and schematic layouts. A data-driven aesthetic that reacts to MIDI events. |
| Topograph | Canvas 2D | Terrain contour map using marching-squares isolines. MIDI input shifts elevation data, redrawing the topographic landscape in real time. |
| Lidar | Canvas 2D | A rotating scan beam that builds persistent point clouds. Beam angle, point density, and fade rate are controlled by sliders and MIDI. |
| Datamosh | Canvas 2D | Glitch art mode with RGB channel shifting and slice displacement. MIDI triggers intensify the corruption effect. |
Split modes (Datamosh patterns)
Ten additional split-screen variants derived from the Datamosh engine, each applying a different spatial partitioning to the glitch effect:
| Mode | Engine | Description |
|---|---|---|
| Bars | Canvas 2D | Vertical bar slices with independent RGB displacement per strip. |
| Grid | Canvas 2D | Uniform grid cells, each offset and colour-shifted independently. |
| Blocks | Canvas 2D | Randomly sized rectangular blocks with glitch displacement. |
| Sweep | Canvas 2D | A horizontal sweep line that progressively corrupts the image. |
| Rings | Canvas 2D | Concentric ring segments with radial RGB shifting. |
| Tile | Canvas 2D | Tiled mosaic pattern with per-tile channel offsets. |
| Wave | Canvas 2D | Sinusoidal wave distortion applied across scan lines. |
| Dots | Canvas 2D | Halftone-style dot pattern with variable size and colour separation. |
| Ribbons | Canvas 2D | Horizontal ribbon strips with staggered displacement and hue rotation. |
| Mosaic | Canvas 2D | Irregular mosaic fragments with per-fragment glitch transforms. |
Color Modes (0 – 50)
There are 51 colour palettes, indexed 0–50. Each maps the incoming note and velocity to a specific hue range. The Color Mode slider cycles through them in real time.
| Index | Name / Character |
|---|---|
| 0 | Rainbow — full HSL wheel cycling with note |
| 1 | Warm — reds, oranges, deep yellows |
| 2 | Cool — blues, cyans, teals |
| 3 | Neon — high-saturation electric colours |
| 4 | Pastel — soft, desaturated tones |
| 5 | Monochrome — white on black, pure luminance |
| 6 | Violet — purple to magenta spectrum |
| 7 | Amber — gold to deep orange |
| 8 | Emerald — deep greens with teal accents |
| 9 | Crimson — deep reds to coral |
| 10 | Ice — pale blues with white highlights |
| 11 | Lava — black, red, orange, bright yellow |
| 12 | Cyber — electric blue and cyan on black |
| 13 | Dusk — purple and pink sunset tones |
| 14 | Forest — earthy greens and browns |
| 15 | Ocean — deep navy to turquoise |
| 16–50 | Extended palette — further hue combinations and hybrid spectrums |
The note number and velocity together determine which specific hue within the active palette is used for each particle. Lower notes select lower-indexed hues; higher velocities push toward brighter values.
Audio Engine
HazR includes a polyphonic software synthesiser built with Tone.js. Each MIDI note triggers a synthesis voice in addition to generating visuals.
Synth pool
There are 10 synthesis voices, selected randomly per note event:
| Voice | Type | Character |
|---|---|---|
| Sine | Tone.Synth | Soft, pure tone |
| Square | Tone.Synth | Bright, buzzy |
| Triangle | Tone.Synth | Warm, hollow |
| Sawtooth | Tone.Synth | Rich, bright |
| Membrane | Tone.MembraneSynth | Kick-drum style |
| Metal | Tone.MetalSynth | Metallic clang |
| FM | Tone.FMSynth | Electric, complex |
| AM | Tone.AMSynth | Tremolo-like |
| Duo | Tone.DuoSynth | Detuned dual oscillator |
| Noise | Tone.NoiseSynth | White noise burst |
All voices are routed through a shared reverb effect (3 second decay, 30% wet mix).
Velocity sensitivity
Velocity (0–127) is normalised to 0–1 and applied to the synth's attack amplitude. A soft touch produces a quiet, delicate voice; a hard strike is loud and pronounced.
Keyboard trigger
Computer keyboard keys also trigger synthesis voices — see Keyboard Shortcuts below.
Keyboard Shortcuts
These shortcuts work within the app (/hazr/dashboard/app):
| Key | Action |
|---|---|
a | Note trigger — synth voice 1 |
s | Note trigger — synth voice 2 |
d | Note trigger — synth voice 3 |
f | Note trigger — synth voice 4 |
g | Note trigger — synth voice 5 |
h | Note trigger — synth voice 6 |
j | Note trigger — synth voice 7 |
k | Note trigger — synth voice 8 |
l | Note trigger — synth voice 9 |
; | Note trigger — synth voice 10 |
z | Membrane synth (kick) |
x | Metal synth (hat) |
c | Noise synth (snare) |
AI Patterns (10–19) Artist+
Artist and Venue subscribers unlock 10 additional generative patterns produced by a Python engine running on the server. These patterns are computed per MIDI note — note number and velocity modulate their parameters.
How it works
- Your MIDI note is published to a Redis channel (
midi_events) - The Python worker receives the event and selects a generator based on the active pattern index
- The generator produces a 40 × 30 grid of
{width, margin}values - The result is published to the
predictionschannel and forwarded to your browser via Socket.IO - Three.js applies the new grid, updating all particle positions in one frame
Activating
Move the Pattern slider past 9. A purple Artist+ badge appears confirming the Python engine is active. Play a MIDI note to trigger the first generation. Typical server round-trip latency is 50–150 ms.
Fallback behaviour
If a Python pattern has not yet arrived, the last received grid is shown as a static preview. Play any note to trigger a fresh generation.
Templates Artist+
Templates capture a complete snapshot of all visual parameters and allow instant recall. Every slider position — pattern, shape, size, speed, color mode, opacity, visual position, background, text overlay, and logo (Venue) — is saved in a single template record.
Saving a template
In the app, open the Templates panel and click Save Current as Template. Give it a name. The snapshot is saved immediately to the server and persists across sessions and devices. You can also save templates manually from the Templates dashboard page by entering values numerically.
Loading a template
Click a template name in the Templates panel. All sliders jump to the saved values instantly. Background images and logo images stored with the template are fetched from the server and applied automatically.
Background and logo images in templates
When a template is saved, any currently loaded background image or logo image is stored as base64 in the database alongside the parameter values. Loading that template retrieves and restores the image. Image data is stored server-side and never exposed to the browser except during template load.
Managing templates
The Templates dashboard page lists all saved templates with their parameter summaries. Individual templates can be deleted from this page. Template names can be updated by deleting and re-saving.
MIDI CC Mapping Artist+
MIDI CC (Control Change) messages are sent by knobs, faders, and expression pedals on MIDI controllers. HazR can route any CC message to any visual parameter, allowing hands-on hardware control of the visual engine.
Adding a mapping
Go to Dashboard → MIDI Mapping. Select the parameter to control, enter the CC number (0–127) your knob sends, optionally select a MIDI channel (All / 1–16), and click Add. Two separate mapping tables exist — one for the main App, one for the Multi-display screen.
MIDI channel filtering
Each mapping can be channel-specific or respond to all channels. Set All Channels (0) for controllers that send on a single channel; set a specific channel (1–16) when you use a controller that sends different controls on different channels, or to prevent one controller from interfering with another.
Uniqueness constraint
Each combination of CC number + MIDI channel + display target (App or Multi) is unique per user. You cannot map the same CC on the same channel to two different parameters for the same target. Attempting to do so returns a 409 conflict error with a descriptive message.
Mappable parameters
| Group | Parameters |
|---|---|
| Background | bg_image_opacity, bg_video_opacity |
| Visuals | pattern, shape, size, color_mode, opacity, speed_x, speed_y, speed_z, visual_x, visual_y |
| Logo | logo_size, logo_x, logo_y, logo_opacity |
| Text | disp_text_opacity, disp_text_size, disp_text_x, disp_text_y |
| Particle | particle_size, emission, velocity |
The Reference section at the bottom of the MIDI Mapping page lists every parameter with its value range and a description.
CC value scaling
Incoming CC values (0–127) are linearly scaled to each parameter's native range automatically. A CC value of 0 maps to the parameter minimum; 127 maps to the maximum. No additional configuration is required.
Setlist Artist+
A Setlist is an ordered sequence of visual cues. Each cue stores a complete set of visual parameters that are applied instantly when the cue is triggered. Setlists allow a performance to be pre-composed and executed during a live set with minimal interaction.
Creating a setlist
Open Dashboard → Setlist. Click Create Setlist, give it a name, then add cues using the Add Cue form. Each cue stores: pattern, shape, size, speed X/Y/Z, color mode, opacity, visual position X/Y, background opacity, text overlay, and logo parameters (Venue).
Triggering cues live
In the app, open the Setlist panel, load a setlist, and use Next Cue to advance through the sequence. You can also click any cue directly to jump to it non-linearly. All slider values jump to the cue's stored values instantly.
Cue display
Each cue row in the Setlist dashboard shows parameter badges — coloured indicators for text, logo, background, and other non-default values — so you can quickly scan the visual state of each cue without expanding it.
Custom Generators Artist+
Custom Generators let you write your own Python pattern algorithm that runs server-side on every MIDI note. The function receives note and velocity and must return a 40 × 30 grid of values. NumPy is available.
Function signature
Your function must be named generate and accept exactly two arguments:
| Parameter | Type | Range | Description |
|---|---|---|---|
note | int | 0 – 127 | MIDI note number |
velocity | int | 0 – 127 | MIDI velocity |
The function must return a list of 40 columns, each a list of 30 dicts with a value key (float 0–1):
[[{"value": 0.5}, ...], ...]
Sandbox restrictions
- Allowed imports:
numpyandmathonly - No file I/O, no network access, no
__builtins__that could affect system state - Execution is limited to 5 seconds per call — algorithms that exceed this are terminated
- Code is AST-validated before saving to prevent unsafe constructs
Testing
Click Test on the Modes page code editor. A preview canvas renders the grid output for a sample note and velocity. Adjust and re-test before saving.
Activating in-app
In the app, open the Custom Mode panel, select your generator from the list, and click Activate. When active, every MIDI note bypasses the Redis pipeline and is sent directly to your generator. The result renders as pattern index 20, distinct from the 10 built-in Python patterns. Clear the generator to return to standard pattern routing.
Custom Modes Artist+
Custom Modes differ from Custom Generators in what they control. Rather than generating a particle grid, a Custom Mode controls HazR's visual sliders directly by returning a dictionary of parameter names and values. The respond() function runs on every MIDI note and can read the full set of currently active notes.
Function signature
| Parameter | Type | Description |
|---|---|---|
note | int | Most recent MIDI note number (0–127) |
velocity | int | Most recent velocity (0–127) |
active_notes | list[int] | All currently held notes |
Returnable parameters
| Parameter | Range | Description |
|---|---|---|
mode | 'canvas','quadrat','curvic','dom','particle','cloud','fusion','matrix','vector','feedback','flowfield','metaballs','wireframe','scope','hud','topograph','lidar','datamosh' | Canvas mode |
pattern | 0 – 19 | Pattern index |
shape | 0 – 9 | Shape index |
color_mode | 0 – 50 | Color palette index |
particle_size | 1 – 50 | Particle size |
speed_x | −2 to 2 | Horizontal scroll speed |
speed_y | −2 to 2 | Vertical scroll speed |
speed_z | −2 to 2 | Depth axis speed (Particle mode) |
opacity | 0 – 1 | Canvas opacity |
emission | 0 – 1 | Particle emission rate |
velocity | 0 – 1 | Particle velocity scale |
All returned values are server-side clamped to their valid ranges. Returning a subset of parameters is valid — omitted parameters remain at their current slider values.
Activating
Save the mode from the Modes page. In the app, open the Custom Mode panel (same control), select the mode from the list, and activate it. MIDI input now triggers your respond() function and applies the returned parameters to the visual engine in real time.
Multi-Display Venue
Multi-Display lets you mirror your HazR visuals to any number of remote screens — projectors, TVs, tablets, phones — without a second computer running the app. Any device with a browser can display the mirrored canvas.
Going live
In the app, open the Mirror Screen panel and click Go Live. A unique display URL is generated for your session. Open this URL on any device to receive the mirrored visuals. Multiple devices can connect simultaneously to the same display URL.
What is mirrored
All visual parameter changes are broadcast to display screens in real time — pattern, shape, color mode, speed, opacity, visual position, background, text overlay, and logo. Python-generated pattern grids are also forwarded. The display screen renders a full Three.js canvas identical to the app.
Display screen
The display URL (/display) shows only the visual canvas — no controls or interface. It requires no authentication. Share it safely — the URL is session-specific and expires when you click Stop.
Multi-display app
The Multi-Display app is a standalone version of the visual canvas that can receive mirrored parameters independently of the main app. It supports the same control panel and is intended for a second operator running a separate visual on a separate screen.
Stopping
Click Stop in the Mirror Screen panel. All connected display screens go dark and the session ends. The URL becomes invalid.
Logo Overlay Venue
The Logo panel lets Venue subscribers overlay a transparent PNG image on top of the visual canvas. Use it for venue branding, artist name, event artwork, or any visual element that should persist over the generative output.
Uploading a logo
In the Logo panel, click Upload PNG and select an image file. The image must be a PNG with a transparent background. Once uploaded, it appears on the canvas immediately.
Logo controls
| Control | Range | Description |
|---|---|---|
| Size | 10 – 1000 px | Width of the logo in pixels, scaled responsively with the canvas |
| Position X | 0 – 100% | Horizontal position (0 = left edge, 50 = centre, 100 = right edge) |
| Position Y | 0 – 100% | Vertical position (0 = top edge, 50 = centre, 100 = bottom edge) |
| Opacity | 0 – 1 | Logo transparency (0.2–0.4 gives a watermark effect; 1 = fully opaque) |
Z-order
The logo renders above the particle canvas and background but below the text overlay. If you need the logo behind text, reduce the logo Z-order via the opacity rather than position.
Templates and setlists
Logo parameters and the image itself are saved with templates (image stored as base64). Setlist cues store logo size, X, Y, and opacity — but not the image, which must already be loaded in the Logo panel.
MIDI CC mapping
All four logo parameters can be mapped to MIDI CC for live hardware control. See MIDI CC Mapping.
Streaming Venue
Venue subscribers can stream their HazR visual performance live to multiple platforms simultaneously — Facebook, YouTube, Instagram, TikTok, Twitch, X, and any custom RTMP destination — all from a single session. Three streaming modes are available: OBS/encoder via RTMP, OBS/encoder via SRT, and in-browser mode.
Accessing the stream management page
Navigate to Dashboard → Stream. The page is exclusive to Venue plan subscribers.
Your personal stream key
Every Venue account has a unique, cryptographically generated stream key used for both RTMP and SRT ingest. Reveal, copy, or regenerate the key from the Stream page. Regenerating creates a new key immediately — any active encoder using the old key will disconnect.
RTMP ingest endpoint
Use this URL when configuring OBS or any RTMP-capable encoder:
rtmp://nxprm.io:1935/hazr/{your-stream-key}
SRT ingest endpoint
SRT (Secure Reliable Transport) offers lower latency and better recovery over lossy networks compared to RTMP. Paste the full URL below into your encoder's Server field — no separate stream key field is needed:
srt://nxprm.io:8890?streamid=hazr/{your-stream-key}
In OBS: Settings → Stream → Service: Custom → Server: paste the full SRT URL above → leave Stream Key empty.
hazr2 instead of hazr in the path — both RTMP and SRT variants are shown on the Stream page.Platform destination setup
| Platform | What to enter | Where to find it |
|---|---|---|
| Facebook Live | Stream key only (starts with FB-) | Facebook page → Professional Dashboard → Go Live → Stream Setup |
| YouTube Live | Full RTMP URL (server + key combined) | YouTube Studio → Go Live → Stream → copy Server URL and append Stream Key |
| Instagram Live | Full RTMP URL from Instagram | Instagram app → Profile → Live → Advanced → Stream to external software |
| TikTok Live | Full RTMP URL from TikTok Studio | TikTok Live Studio → Settings → Streaming → Server URL |
| Twitch | Stream key only | Twitch Dashboard → Settings → Stream → Primary Stream Key |
| X (Twitter) | Full RTMP URL (server + key combined) | X Media Studio → Go Live → copy Server URL + Stream Key |
| Custom RTMP | Any full rtmp:// URL | Your own media server, Restream, Castr, etc. |
OBS / encoder mode (RTMP)
- Open OBS → Settings → Stream
- Set Service to Custom
- Set Server to
rtmp://nxprm.io:1935/hazr - Set Stream Key to your personal stream key
- Add a Window Capture or Browser Source pointing at the HazR App tab
- Click Start Streaming in OBS
The server detects the incoming stream and starts an FFmpeg relay to all configured platform destinations. The relay stops automatically when OBS disconnects.
OBS / encoder mode (SRT)
- Open OBS → Settings → Stream
- Set Service to Custom
- Set Server to the full SRT URL from the Stream page (e.g.
srt://nxprm.io:8890?streamid=hazr/{your-key}) - Leave Stream Key empty
- Add a Window Capture or Browser Source pointing at the HazR App tab
- Click Start Streaming in OBS
SRT streams are received by the MediaMTX relay server and forwarded to nginx-rtmp, then on to all configured platform destinations — identical behaviour to RTMP mode.
Browser streaming mode
- Open the HazR App in a separate tab and start your session
- On the Stream page, click Start Browser Stream
- Select the HazR App tab from the screen-share picker
- A Live badge and running timer confirm the stream is active
- Click Stop Stream to end the session
External API Venue
Venue subscribers can control HazR via a REST API. Hardware MIDI controllers, venue automation systems, DAW scripts, or any software capable of making HTTP requests can read and write the visual state of your active session.
API Keys
Generate API keys from Dashboard → API Keys. Keys are prefixed with syn_ followed by 32 hex characters. The full key is shown only once at generation — copy it immediately. Keys are stored server-side as SHA-256 hashes. Give each integration its own key so you can revoke individual access without affecting others.
Authentication
Include your API key in the Authorization header:
Authorization: Bearer syn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /api/external/visual | Update visual parameters of the active session |
| POST | /api/external/stream/start | Start streaming relay (requires saved stream config) |
| POST | /api/external/stream/stop | Stop active streaming relay |
| GET | /api/external/usage | Return current session data (active sessions, notes, uptime) |
Visual update payload
POST to /api/external/visual with a JSON body containing any subset of visual parameters:
{"pattern": 12, "color_mode": 27, "speed_x": 0.8, "opacity": 1}
All parameters are optional. Unspecified parameters retain their current values. Valid parameter names and ranges match those listed in the MIDI CC Mapping section.
Tier Comparison
| Feature | Groupie | Artist | Venue |
|---|---|---|---|
| MIDI input | ✅ | ✅ | ✅ |
| 5 canvas modes | ✅ | ✅ | ✅ |
| 10 local patterns (0–9) | ✅ | ✅ | ✅ |
| 10 shapes | ✅ | ✅ | ✅ |
| 51 color modes | ✅ | ✅ | ✅ |
| Background image / video | ✅ | ✅ | ✅ |
| Text overlay | ✅ | ✅ | ✅ |
| Fullscreen | ✅ | ✅ | ✅ |
| Usage analytics | ✅ | ✅ | ✅ |
| All synth voices | ✅ | ✅ | ✅ |
| AI patterns (10–19) | ❌ | ✅ | ✅ |
| Templates | ❌ | ✅ | ✅ |
| MIDI CC mapping | ❌ | ✅ | ✅ |
| Setlist | ❌ | ✅ | ✅ |
| Custom Generators | ❌ | ✅ | ✅ |
| Custom Modes | ❌ | ✅ | ✅ |
| Session recording | ❌ | ✅ | ✅ |
| Multi-display mirror | ❌ | ❌ | ✅ |
| Logo overlay | ❌ | ❌ | ✅ |
| Live streaming (multi-platform RTMP) | ❌ | ❌ | ✅ |
| Browser streaming (no OBS required) | ❌ | ❌ | ✅ |
| External API | ❌ | ❌ | ✅ |
| Priority support | ❌ | ❌ | ✅ |
| Price | Free | $9 / month | $29 / month |
Troubleshooting
MIDI device not detected
- Confirm you are using Chrome or Edge (Firefox / Safari are not supported)
- Check that the browser has MIDI permission:
chrome://settings/content/midi - Unplug and replug the MIDI device, then wait 5 seconds — the app auto-detects reconnection
- Try a different USB port or USB hub
- Test the device in a MIDI monitor app to confirm it is sending data
Visuals are choppy or laggy
- Close other GPU-intensive tabs or applications
- Reduce the Size slider to lower the zoom level
- Ensure hardware acceleration is enabled: Chrome → Settings → System → Use hardware acceleration
- Try switching from the Particle mode to Canvas mode — Particle mode is more GPU-intensive
AI patterns not appearing (Artist / Venue)
- Confirm your tier is Artist or Venue on the Payments page
- The pattern slider must be set above 9 — confirm the Artist+ badge is visible
- Play a MIDI note to trigger generation — patterns are on-demand, not automatic
- Check your network connection; patterns arrive via WebSocket
Template not restoring correctly
- If background or logo images are missing after loading a template, the image may not have been captured at save time — re-upload the image, re-save the template
- Templates saved before a software update may not include newly added parameters — these default to their baseline values
MIDI CC mapping not responding
- Confirm the CC number matches what your controller actually sends — use a MIDI monitor app to verify
- Check the MIDI channel setting: if your controller sends on channel 1 but the mapping is set to channel 2, it will not match
- Ensure the app is open and your session is active — mappings are only active when the app tab is open
App redirects to login every time
Sessions expire after 24 hours. If you are redirected mid-session, log in again — your settings are not lost. If you are immediately redirected after login, clear your browser cookies for nxprm.io and auth.nxprm.io and try again.
Audio not playing
Browsers require a user gesture before starting audio. Click anywhere on the app page before playing MIDI notes to unlock the audio context. If audio is still absent, check that the browser tab is not muted.
Stream not reaching platforms (Venue)
- Confirm you have saved your platform destinations on the Stream page
- Platform stream keys expire regularly — regenerate the key in the platform's live studio and update it on the Stream page
- For Facebook: your Facebook Live session must be in an active or standby state before the stream key is valid
- For YouTube: your YouTube live stream must be in Created state in YouTube Studio
- Ensure your Venue subscription is active on the Payments page
Multi-display screen not updating (Venue)
- Confirm Go Live is active in the Mirror Screen panel — the button turns lit when broadcasting
- The display URL is session-specific — reload the display screen if you stopped and restarted broadcasting
- Display screens require a stable WebSocket connection; check network stability on the receiving device
Custom Mode error (Artist / Venue)
- Read the error message shown in the Custom Mode panel — it reflects the Python exception from the server
- Confirm your function is named
generateand returns the correct nested list structure - Imports are restricted to
numpyandmath— any other import will fail AST validation - If execution times out (5 s), simplify the algorithm or reduce grid iteration count
Browser streaming not starting (Venue)
- Use Chrome or Edge — Firefox and Safari do not support the required screen-capture APIs
- When the screen-share picker appears, select the correct browser tab showing the HazR App
- Ensure platform destinations are saved — a stream key is required before streaming can begin
Data & Privacy
What we store
- Account data: email address and Keycloak user ID (required for authentication)
- Session data: session start time, duration, and number of MIDI notes played — visible only to you on the Usage page
- Payment data: Stripe handles all payment data. NXPRM stores only your Stripe customer ID and subscription tier
- Templates: all slider values plus background and logo images as base64 strings, stored in the NXPRM database and accessible only to your account
- MIDI mappings, setlists, custom generators, custom modes: stored in the NXPRM database, associated with your account
- API keys: stored as SHA-256 hashes — the plain-text key is never stored and cannot be recovered; only the key prefix (
syn_XXXX) is stored for display
Streaming data (Venue)
- Stream key: stored in the database and used server-side only to route your relay
- Platform credentials: stream keys and RTMP URLs are stored in the database and transmitted only to the respective platforms during an active stream — never shared or sold
- Stream content: video data is relayed in memory to your configured platforms and is never recorded or stored by NXPRM
What we do not store
- MIDI note content (notes are processed in memory and discarded)
- Audio recordings
- Video or screen captures
- Any personally identifiable information beyond email
Data retention
Session records are retained for 12 months. Account data, templates, setlists, and mappings are retained for the lifetime of your account. You may request deletion by contacting support.

