HTTP API & viewer URLs
The engine exposes a small HTTP surface in addition to its WebSocket. The
most useful piece for third-party integrations is the set of browser-ready
HTML viewer URLs — you get a live panel stream in an <iframe> with zero
SDK code.
Default base: http://<lan-ip>:8787.
GET /status
Engine snapshot — useful for health checks, third-party dashboards, and for scripts that just want to know what's running.
{
"ok": true,
"version": "0.8.3",
"buildTime": "2026-04-21T09:15:32.104Z",
"pid": 18412,
"port": 8787,
"uptime": 1247,
"state": { "isAdmin": true, "msfsConnection": "connected", "directX": { "version": 12, "supported": true }, "markerInjection": { "status": "ok", "injectedCount": 8 }, ... },
"panels": [ { "id": "PFD_Captain", "name": "PFD (Captain)", "width": 1024, "height": 1024 }, ... ],
"clients": [ { "name": "GlassOut Desktop", "connectedAt": "2026-04-21T09:15:35.000Z" }, ... ],
"configs": [ { "ownerName": "GlassOut Desktop", "profiles": [ ... ] } ],
"logs": { "directory": "C:\\Users\\me\\AppData\\Local\\GlassOutEngine\\logs", "current": "session-2026-04-21T09-15-32-104Z.log" }
}
GET /panel/{id}
A self-contained HTML page that:
- Opens a WebSocket to the engine.
- Subscribes to the given panel.
- Decodes each incoming JPEG via the browser's native
createImageBitmap(hardware-accelerated where available). - Renders to a
<canvas>at real frame rate. - Forwards clicks back to MSFS via the WebSocket.
- Shows a "Disconnected from GlassOut" overlay on WebSocket drop, then auto-reconnects.
Query params:
| Param | Values | Default | Meaning |
|---|---|---|---|
fit | native / anything | scale-to-fit | native → 1:1 panel pixels, no scaling. |
clickDelay | ms (0–5000) | 300 (engine-side) | Hover duration before the synthesised click fires. |
fps | int (10–60) | 30 | Per-viewer frame rate; clamped to [10, 60]. |
debug | 1 / true | off | Show a corner overlay with delivered FPS, skipped ticks, current quality bucket, pending-frame age, and WS buffered bytes. Subscribes with debug: true. |
forceEveryFrame | 1 / true | off | Bypass the static-frame fingerprint skip — useful on a wired local viewer where bandwidth is free and you want every gauge update visible. Affects all subscribers of the panel. |
Example:
<iframe
src="http://192.168.1.42:8787/panel/PFD_Captain?fit=native&clickDelay=500&fps=60"
width="1024"
height="1024"
frameborder="0"
></iframe>
GET /canvas
A compositor endpoint — build a custom canvas by baking items into the URL. This is what the desktop app uses for templates and fragments when you click Copy Configuration URL.
Query params:
| Param | Description |
|---|---|
w, h | Canvas size in pixels. |
bg | Background CSS colour (URL-encoded). Default #000000. |
panel[i][name] | Source panel ID. |
panel[i][x], [y], [w], [h] | Destination rect on the canvas. |
panel[i][srcX], [srcY], [srcW], [srcH] | Crop rect in the source panel (omit for full panel). |
clickDelay | Same as /panel/{id}. |
fps | Same as /panel/{id}. |
debug | Same as /panel/{id} — single overlay with per-panel breakdown. |
The SDK's buildFragmentConfigUrl(origin, fragment) and
buildTemplateConfigUrl(origin, template) generate these URLs for you.
Clicks are hit-tested against entries and translated back into the source panel's pixel coordinates, so fragments and templates stay interactive.
GET /instance/{profileId}/{elementId}
Resolves a fragment or template by ID from in-memory profile bundles. The HTML wrapper re-renders whenever those profiles change — perfect for an editor workflow where the end-user viewer should update automatically as you edit.
Fragment and template IDs are disambiguated server-side, so the URL shape is the same for both.
Query params: clickDelay, fps, debug — same semantics as
/panel/{id}. clickDelay falls back to the profile's
settings.touchClickDelayMs when omitted.
Example:
http://192.168.1.42:8787/instance/fenix-a320/nd-capt?fps=60
POST /shutdown
Cooperative shutdown. Used by the unelevated Electron main process to ask
the elevated engine to exit cleanly (plain process.kill() fails across
privilege levels).
No body; returns { ok: true }.
GET /health (legacy)
301 redirect to /status. Kept around so older clients still work.
Click delay in URLs
/panel/{id}, /canvas, and /instance/... all honour ?clickDelay=N. Good
defaults:
- 0 ms — instantly responsive gauges (most PFDs/NDs).
- 300–500 ms — WT G3000 GTC, other touch instruments that expect a hover before the click. This is also the engine-side default when no value is supplied at all.
- max — clamped to 5000 ms.
The per-profile setting in the desktop app sets the same parameter for every
viewer of that profile, and /instance/... reads it from
profile.settings.touchClickDelayMs automatically when the URL omits
clickDelay.