Skip to main content

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:

ParamValuesDefaultMeaning
fitnative / anythingscale-to-fitnative → 1:1 panel pixels, no scaling.
clickDelayms (0–5000)300 (engine-side)Hover duration before the synthesised click fires.
fpsint (10–60)30Per-viewer frame rate; clamped to [10, 60].
debug1 / trueoffShow a corner overlay with delivered FPS, skipped ticks, current quality bucket, pending-frame age, and WS buffered bytes. Subscribes with debug: true.
forceEveryFrame1 / trueoffBypass 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:

ParamDescription
w, hCanvas size in pixels.
bgBackground 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).
clickDelaySame as /panel/{id}.
fpsSame as /panel/{id}.
debugSame 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.