71 documented routes · iOS, Mac & Apple TV · Android & Android TV
LiveDeck control API
Every LiveDeck app runs a small local HTTP server so a Stream Deck, Bitfocus Companion, a browser remote, or your own script can switch, cue skins, run PTZ and start outputs — all on your own network, with nothing passing through our servers. This page documents every route, traced directly to the app's own source, with the platform differences called out rather than hidden.
API reference (PDF)Companion module (free) ↗ Download the standalone tester
Both apps already send Access-Control-Allow-Origin: * on every /api/* route, so the standalone tester works even opened straight from disk (file://) — no server in between, nothing to install.
Try it on your device
This opens the device's own API console in a new tab — nothing is sent to manarlabs.com. Your browser blocks a secure website like this one from calling devices on your local network directly, but the device's own page runs calls straight from your browser to the device.
Find the token and the exact IP in the app under Output → Control API.
Pairing
The only two /api routes that don't need a token — but they only answer a peer on the same local network. Use this to get a token into a browser or a Companion install without ever showing the token on screen.
/api/pairNo token (local network only)| Param | Where | Required | Description |
|---|---|---|---|
| name | body (JSON) | Yes | Label shown in the app's pairing prompt, ≤40 characters. |
Example request
curl -s -X POST http://192.168.1.42:8088/api/pair \
-H 'Content-Type: application/json' \
-d '{"name":"My browser"}'Example response
{ "requestID": "a1b2c3", "code": "4821", "expiresIn": 60 }Rate-limited to 5 requests/min per peer (429 past that), one pending pair at a time (409), and 503 if the app has no token configured yet (API fully closed). The app shows the 4-digit code for the operator to approve or deny on-screen.
/api/pair/<requestID>No token (local network only)| Param | Where | Required | Description |
|---|---|---|---|
| requestID | path | Yes | The id returned by POST /api/pair. |
Example request
curl -s http://192.168.1.42:8088/api/pair/a1b2c3Example response
{ "state": "waiting", "expiresIn": 42 }
// then, once approved:
{ "state": "approved", "token": "<48-char hex token>" }
// or: { "state": "denied" } / { "state": "expired" }Poll this every couple of seconds. The token is handed over exactly once — the server destroys the pairing record right after a successful "approved" read, so a second poll after that returns "expired".
State & monitoring
Read-only. Everything here works with GET and never changes anything in the app.
/api/stateBearer tokenExample request
curl -s http://192.168.1.42:8088/api/state?token=YOUR_TOKENExample response
Full state JSON — the same object the browser remote polls as /state.json./api/programBearer tokenExample request
curl -s http://192.168.1.42:8088/api/program?token=YOUR_TOKENExample response
{ "program": "...", "liveLayout": "...", "cuedLayout": "...", "takeStyle": "cut", "portrait": false, "programPtz": {...} }Android's response additionally includes "preview" and "monMuted" keys that iOS does not return here.
/api/layoutsBearer tokenExample request
curl -s http://192.168.1.42:8088/api/layouts?token=YOUR_TOKENExample response
Array of layout objects (id, name, sources, skins…)./api/sourcesBearer tokenExample request
curl -s http://192.168.1.42:8088/api/sources?token=YOUR_TOKENExample response
Array of source objects currently known to the mixer (NDI, cameras, satellites, test patterns)./api/sources/<id>/removeBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id, from /api/sources. |
Example request
curl -s -X POST http://192.168.1.42:8088/api/sources/cam1/remove?token=YOUR_TOKENExample response
{ "ok": true }/api/skinsBearer tokenExample request
curl -s http://192.168.1.42:8088/api/skins?token=YOUR_TOKENExample response
iOS: { skins, skinKinds, skinEffects, skinTriggers, skinGroups, layouts }Android's response is narrower: only { skins, skinKinds }. The skinEffects/skinTriggers/skinGroups/per-layout skin list are iOS-only on this route.
/api/transitionsBearer tokenExample request
curl -s http://192.168.1.42:8088/api/transitions?token=YOUR_TOKENExample response
Array of available transition styles (cut, dissolve, …)./api/audioBearer tokenExample request
curl -s http://192.168.1.42:8088/api/audio?token=YOUR_TOKENExample response
Per-source audio state: gain, mute, solo, delay, follow mode, master level./api/healthBearer tokenExample request
curl -s http://192.168.1.42:8088/api/health?token=YOUR_TOKENExample response
{ "ok": true }Cheap liveness check — good for a Companion "device reachable" indicator.
/api/statsBearer tokenExample request
curl -s http://192.168.1.42:8088/api/stats?token=YOUR_TOKENExample response
Engine stats: frame rate, dropped frames, CPU/thread load, output bitrates./api/eventsSSE streamBearer tokenExample request
curl -N http://192.168.1.42:8088/api/events?token=YOUR_TOKENExample response
text/event-stream. `event: state` with a compact state payload on every change, plus a `: ping` comment every ~15s to keep the connection alive.iOS's compact payload includes isLive/liveSince/liveSelection; Android's compact-key set omits those three fields. Not fetch-able from the standalone tester (EventSource keeps the connection open) — use curl -N or a Companion feedback instead.
/api/thumb/<id>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
Example request
curl -s http://192.168.1.42:8088/api/thumb/cam1?token=YOUR_TOKEN -o thumb.jpgExample response
image/jpegHitting this also counts as "someone is watching" and keeps that source's thumbnail refreshing.
/api/program.jpgBearer tokenExample request
curl -s http://192.168.1.42:8088/api/program.jpg?token=YOUR_TOKEN -o program.jpgExample response
image/jpeg — a snapshot of the current Program output./api/outputsBearer tokenExample request
curl -s http://192.168.1.42:8088/api/outputs?token=YOUR_TOKENExample response
iOS: { out: { ndi, rtmp, record, hls, rtmpSrv, … }, isLive, liveSince, liveSelection, goLiveRemembered, lastGoLiveFailures }
Android: { out: { ndi, rec, rtmp, rtmpStatus, fb, fbStatus, fbConfigured, hls, hlsURL, viewers } }The two platforms' output objects genuinely differ: Android exposes native Facebook Live fields (fb/fbStatus/fbConfigured) that iOS does not have via this API; iOS exposes GO LIVE bookkeeping (isLive/liveSince/liveSelection/goLiveRemembered) that Android's table doesn't list here.
Run a Show
Starts, steps through and ends a saved rundown (intro/outro, cued segments).
/api/show/startBearer token| Param | Where | Required | Description |
|---|---|---|---|
| record | query | No | Default true. |
| stream | query | No | Default true. |
Example request
curl -s -X POST 'http://192.168.1.42:8088/api/show/start?token=YOUR_TOKEN&record=true&stream=true'Example response
{ "ok": true }/api/show/nextBearer tokenExample request
curl -s -X POST http://192.168.1.42:8088/api/show/next?token=YOUR_TOKENExample response
{ "ok": true }/api/show/step/<index>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| index | path | Yes | 0-based step index. |
Example request
curl -s -X POST http://192.168.1.42:8088/api/show/step/2?token=YOUR_TOKENExample response
{ "ok": true }/api/show/endBearer tokenExample request
curl -s -X POST http://192.168.1.42:8088/api/show/end?token=YOUR_TOKENExample response
{ "ok": true }Satellite
Controls a connected Satellite (a second phone sending camera/screen/test pattern) from the Studio side.
/api/satellite/talk/<on>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| on | path | Yes | "on" or "off". |
Example request
curl -s -X POST http://192.168.1.42:8088/api/satellite/talk/on?token=YOUR_TOKENExample response
{ "ok": true }/api/satellite/talk/target/<target>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| target | path | Yes | "auto", "all", or a source id. |
Example request
curl -s -X POST http://192.168.1.42:8088/api/satellite/talk/target/auto?token=YOUR_TOKENExample response
{ "ok": true }/api/satellite/camera/<action>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| action | path | Yes | "flip", "torch", or "zoom". |
| value | query | No | Used by "zoom". |
| to | query | No | Target satellite, if more than one. |
Example request
curl -s -X POST 'http://192.168.1.42:8088/api/satellite/camera/flip?token=YOUR_TOKEN'Example response
{ "ok": true }/api/satellite/messageBearer token| Param | Where | Required | Description |
|---|---|---|---|
| text | query/body | Yes | Message text. |
| to | query | No | Target satellite, if more than one. |
Example request
curl -s -X POST 'http://192.168.1.42:8088/api/satellite/message?token=YOUR_TOKEN&text=Go+to+camera+2'Example response
{ "ok": true }Switching
Cue and take layouts — the core vision-mixing actions.
/api/layout/<id>/cueBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Layout id. |
Example request
curl -s http://192.168.1.42:8088/api/layout/lower-third/cue?token=YOUR_TOKENExample response
{ "ok": true }Cues green — does not go to air.
/api/layout/<id>/takeBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Layout id. |
Example request
curl -s http://192.168.1.42:8088/api/layout/lower-third/take?token=YOUR_TOKENExample response
{ "ok": true }Takes to air with the studio's current default transition.
/api/layout/<id>/take/<style>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Layout id. |
| style | path | Yes | Transition style, e.g. cut, dissolve. |
Example request
curl -s http://192.168.1.42:8088/api/layout/lower-third/take/cut?token=YOUR_TOKENExample response
{ "ok": true }/api/takeBearer token| Param | Where | Required | Description |
|---|---|---|---|
| style | query | No | Optional transition style override. |
Example request
curl -s http://192.168.1.42:8088/api/take?token=YOUR_TOKENExample response
{ "ok": true }Takes the currently cued layout.
/api/cutBearer tokenExample request
curl -s http://192.168.1.42:8088/api/cut?token=YOUR_TOKENExample response
{ "ok": true }Shortcut for take with a hard cut.
/api/transition/<style>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| style | path | Yes | New studio default transition style. |
Example request
curl -s http://192.168.1.42:8088/api/transition/dissolve?token=YOUR_TOKENExample response
{ "ok": true }Skins
Lower thirds, tickers, clocks and other overlays played over Program.
/api/skin/<id>/playBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Skin id. |
Example request
curl -s http://192.168.1.42:8088/api/skin/ticker1/play?token=YOUR_TOKENExample response
{ "ok": true }/api/skin/<id>/stopBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Skin id. |
Example request
curl -s http://192.168.1.42:8088/api/skin/ticker1/stop?token=YOUR_TOKENExample response
{ "ok": true }/api/skin/<id>/colorBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Skin id. |
| value | query | Yes | #RRGGBB, or "original" to reset. |
Example request
curl -s -X POST 'http://192.168.1.42:8088/api/skin/ticker1/color?token=YOUR_TOKEN&value=%23FF3366'Example response
{ "ok": true }/api/catalogBearer tokenExample request
curl -s http://192.168.1.42:8088/api/catalog?token=YOUR_TOKENExample response
Merged bundled + remote skin catalogue index.Served directly, not routed through the generic command table.
/api/catalog/<id>/addBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Catalogue item id. |
| layoutId | query | No | Layout to add the skin to. |
Example request
curl -s 'http://192.168.1.42:8088/api/catalog/lower-third-01/add?token=YOUR_TOKEN&layoutId=main'Example response
{ "ok": true }PTZ
Pan/tilt/zoom cameras — presets, direct moves and storing new presets.
/api/ptz/camerasBearer tokenExample request
curl -s http://192.168.1.42:8088/api/ptz/cameras?token=YOUR_TOKENExample response
Array of PTZ-capable camera sources./api/ptz/<target>/preset/<n>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| target | path | Yes | Camera source id. |
| n | path | Yes | Preset number. |
| speed | query | No | Android only — default "1". |
Example request
curl -s http://192.168.1.42:8088/api/ptz/cam1/preset/3?token=YOUR_TOKENExample response
{ "ok": true }Android's handler also sends an optional speed parameter (default "1") that iOS's route does not declare.
/api/ptz/<target>/store/<n>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| target | path | Yes | Camera source id. |
| n | path | Yes | Preset number to store the current position as. |
Example request
curl -s http://192.168.1.42:8088/api/ptz/cam1/store/3?token=YOUR_TOKENExample response
{ "ok": true }/api/ptz/<target>/pantiltBearer token| Param | Where | Required | Description |
|---|---|---|---|
| target | path | Yes | Camera source id. |
| pan | query | Yes | Pan speed/position. |
| tilt | query | Yes | Tilt speed/position. |
Example request
curl -s 'http://192.168.1.42:8088/api/ptz/cam1/pantilt?token=YOUR_TOKEN&pan=0.2&tilt=-0.1'Example response
{ "ok": true }/api/ptz/<target>/zoomBearer token| Param | Where | Required | Description |
|---|---|---|---|
| target | path | Yes | Camera source id. |
| speed | query | Yes | Zoom speed. |
Example request
curl -s 'http://192.168.1.42:8088/api/ptz/cam1/zoom?token=YOUR_TOKEN&speed=0.5'Example response
{ "ok": true }Audio
Per-source gain, mute, solo, delay and master level.
/api/audio/<id>/delay/<ms>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
| ms | path | Yes | 0–500. |
Example request
curl -s http://192.168.1.42:8088/api/audio/cam1/delay/40?token=YOUR_TOKENExample response
{ "ok": true }/api/source/<id>/videodelay/<ms>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
| ms | path | Yes | 0–500. |
Example request
curl -s http://192.168.1.42:8088/api/source/cam1/videodelay/40?token=YOUR_TOKENExample response
{ "ok": true }/api/audio/master/<value>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| value | path | Yes | 0…1 on Android; iOS allows slightly over 1 for makeup gain. |
Example request
curl -s http://192.168.1.42:8088/api/audio/master/0.8?token=YOUR_TOKENExample response
{ "ok": true }/api/audio/mode/<mode>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| mode | path | Yes | "follow" or "manual". |
Example request
curl -s http://192.168.1.42:8088/api/audio/mode/follow?token=YOUR_TOKENExample response
{ "ok": true }/api/audio/<id>/gain/<value>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
| value | path | Yes | Gain level. |
Example request
curl -s http://192.168.1.42:8088/api/audio/cam1/gain/0.9?token=YOUR_TOKENExample response
{ "ok": true }/api/audio/<id>/muteBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
Example request
curl -s http://192.168.1.42:8088/api/audio/cam1/mute?token=YOUR_TOKENExample response
{ "ok": true }Toggles.
/api/audio/<id>/soloBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
Example request
curl -s http://192.168.1.42:8088/api/audio/cam1/solo?token=YOUR_TOKENExample response
{ "ok": true }Toggles.
/api/audio/<id>/deleteBearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
Example request
curl -s http://192.168.1.42:8088/api/audio/cam1/delete?token=YOUR_TOKENExample response
{ "ok": true }/api/audio/<id>/follow/<layoutId>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| id | path | Yes | Source id. |
| layoutId | path | Yes | Layout to follow. |
Example request
curl -s http://192.168.1.42:8088/api/audio/cam1/follow/main?token=YOUR_TOKENExample response
{ "ok": true }/api/monitor/mute/<state>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| state | path | Yes | "on" or "off". |
Example request
curl -s http://192.168.1.42:8088/api/monitor/mute/on?token=YOUR_TOKENExample response
{ "ok": true }Outputs & Go Live
Starts/stops NDI, RTMP, recording and streaming outputs, and the "GO LIVE" shortcut that starts everything ticked at once.
/api/remote/pinBearer tokenExample request
curl -s http://192.168.1.42:8088/api/remote/pin?token=YOUR_TOKENExample response
{ "pin": "4821" }This is the human web-remote's PIN, unrelated to the API bearer token.
/api/remote/pinBearer token| Param | Where | Required | Description |
|---|---|---|---|
| pin | query/body | Yes | 4–8 digits, or "new" for a random one. |
Example request
curl -s -X POST 'http://192.168.1.42:8088/api/remote/pin?token=YOUR_TOKEN&pin=new'Example response
{ "pin": "7310" }/api/output/nasBearer token| Param | Where | Required | Description |
|---|---|---|---|
| host | body | Yes | |
| share | body | Yes | |
| folder | body | No | |
| user | body | No | |
| password | body | No |
Example request
curl -s -X POST http://192.168.1.42:8088/api/output/nas?token=YOUR_TOKEN \
-d host=192.168.1.50 -d share=RecordingsExample response
{ "ok": true }Configures record-to-NAS.
/api/output/nas/clearBearer tokenExample request
curl -s -X POST http://192.168.1.42:8088/api/output/nas/clear?token=YOUR_TOKENExample response
{ "ok": true }/api/output/ndi/name/<name>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| name | path | Yes | New NDI output name. |
Example request
curl -s http://192.168.1.42:8088/api/output/ndi/name/Studio-A?token=YOUR_TOKENExample response
{ "ok": true }/api/output/quality/<quality>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| quality | path | Yes | iOS: 480p | 720p | 1080p. Android: 720p | 1080p. |
Example request
curl -s http://192.168.1.42:8088/api/output/quality/1080p?token=YOUR_TOKENExample response
{ "ok": true }iOS accepts 480p; Android does not offer it.
/api/output/portrait/<on>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| on | path | Yes | "on" or "off". |
Example request
curl -s http://192.168.1.42:8088/api/output/portrait/on?token=YOUR_TOKENExample response
{ "ok": true }/api/output/<name>/<state>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| name | path | Yes | iOS: ndi | rtmp | record | hls | rtmpserver. Android: ndi | record | rtmp | facebook | hls. |
| state | path | Yes | "on" or "off". |
| url | query | No | Android only, for name=rtmp — start with a specific server URL. |
Example request
curl -s http://192.168.1.42:8088/api/output/ndi/on?token=YOUR_TOKENExample response
{ "ok": true }The accepted name vocabulary differs by platform: rtmpserver exists only on iOS, facebook only on Android. Android's own /api/golive/select route (below) uses the iOS vocabulary instead of this one's — see the note there.
/api/goliveBearer tokenExample request
curl -s -X POST http://192.168.1.42:8088/api/golive?token=YOUR_TOKENExample response
{ "ok": true }Starts every output currently ticked in Output settings.
/api/golive/stopBearer tokenExample request
curl -s -X POST http://192.168.1.42:8088/api/golive/stop?token=YOUR_TOKENExample response
{ "ok": true }Confirm before wiring this to a hotkey — it stops every live output at once.
/api/golive/select/<name>/<state>Bearer token| Param | Where | Required | Description |
|---|---|---|---|
| name | path | Yes | ndi | rtmp | record | hls | rtmpserver — the same set on both platforms. |
| state | path | Yes | "on" or "off" — ticks/unticks it for the next GO LIVE. |
Example request
curl -s http://192.168.1.42:8088/api/golive/select/rtmp/on?token=YOUR_TOKENExample response
{ "ok": true }On Android this route's name vocabulary (rtmpserver, no facebook) differs from /api/output/<name>/<state>'s own vocabulary (facebook, no rtmpserver) on the same device — flagged to engineering, not something this page can paper over.
NDI network
Configures how this device finds NDI sources — a discovery server address and/or a list of direct IPs. Answers on every device regardless of mode.
/api/ndi/networkBearer tokenExample request
curl -s http://192.168.1.42:8088/api/ndi/network?token=YOUR_TOKENExample response
{ "discoveryServer": "", "directIPs": [] }/api/ndi/networkBearer token| Param | Where | Required | Description |
|---|---|---|---|
| discoveryServer | body | No | |
| directIPs | body | No | Comma-separated. Either/both fields; empty clears. |
Example request
curl -s -X POST http://192.168.1.42:8088/api/ndi/network?token=YOUR_TOKEN \
-d directIPs=192.168.1.21,192.168.1.22Example response
{ "ok": true }Raw command
The generic forwarder behind the browser remote's own control panel. Covers everything that doesn't have a dedicated shortcut route above.
/api/commandBearer token| Param | Where | Required | Description |
|---|---|---|---|
| action | body or query, plus any action-specific fields | Yes | e.g. addLayout, renameLayout, duplicateLayout, removeLayout, addSkin, updateSkin, removeSkin, playSkin, stopSkin, camZoom, testPattern, addInput, addCamera, … |
Example request
curl -s -X POST http://192.168.1.42:8088/api/command?token=YOUR_TOKEN \
-H 'Content-Type: application/json' \
-d '{"action":"testPattern","on":true}'Example response
{ "ok": true }GET is also accepted with the same params on the query string. This is the same JSON shape the browser remote's own POST /cmd uses.
TV routes
Only answered when the device is running in TV box mode (Apple TV / Android TV). On a phone, tablet or Mac these fall through to the generic 404.
/api/tvBearer tokenExample request
curl -s http://192.168.1.42:8088/api/tv?token=YOUR_TOKENExample response
Current TV mode + status./api/tv/modeBearer token| Param | Where | Required | Description |
|---|---|---|---|
| mode | query/body | Yes | watch | studio | choose (iOS also documents "choose" explicitly to return to the chooser screen). |
Example request
curl -s -X POST http://192.168.1.42:8088/api/tv/mode?token=YOUR_TOKEN&mode=watchExample response
{ "ok": true }/api/tv/fullscreenBearer token| Param | Where | Required | Description |
|---|---|---|---|
| on | query/body | Yes |
Example request
curl -s -X POST http://192.168.1.42:8088/api/tv/fullscreen?token=YOUR_TOKEN&on=trueExample response
{ "ok": true }/api/tv/autostartBearer token| Param | Where | Required | Description |
|---|---|---|---|
| on | query/body | Yes |
Example request
curl -s -X POST http://192.168.1.42:8088/api/tv/autostart?token=YOUR_TOKEN&on=trueExample response
{ "ok": true }/api/tv/qualityBearer token| Param | Where | Required | Description |
|---|---|---|---|
| auto | query/body | Yes |
Example request
curl -s -X POST http://192.168.1.42:8088/api/tv/quality?token=YOUR_TOKEN&auto=trueExample response
{ "ok": true }/api/tv/sourcesBearer tokenExample request
curl -s http://192.168.1.42:8088/api/tv/sources?token=YOUR_TOKENExample response
Sources the TV box can watch./api/tv/watchBearer token| Param | Where | Required | Description |
|---|---|---|---|
| source | query/body | Yes | Source id to watch. |
Example request
curl -s -X POST http://192.168.1.42:8088/api/tv/watch?token=YOUR_TOKEN&source=cam1Example response
{ "ok": true }Bonjour/mDNS: both platforms advertise the API as _livedeck-api._tcp, with the port in a TXT record — that's how Companion and the "Try it" console above find a device automatically on the same network.
Pairing without typing a token: use POST /api/pair and GET /api/pair/<id> above — the only two unauthenticated routes, and only answered to a peer already on your network.