Skip to content

Headless mode and REST API

When to use headless mode

Headless mode runs the saved Controll3r hardware session and REST server without opening the desktop interface. It is useful for:

  • lab automation
  • scheduled or unattended macro playback
  • screenshot collection
  • health monitoring
  • integration with orchestration systems

Only one process can own the capture device and Controll3r Interface at a time.

Start headless mode

From the installation directory:

.\Controll3r.exe --headless

Headless mode loads the saved settings/session and forces the REST server on. It writes operational logs under:

%LocalAppData%\Controll3r\logs\

Install per-user autostart

.\Controll3r.exe --install-service

Despite the command name, the current implementation is per-user autostart, not a Windows service. It uses a current-user scheduled task when allowed and falls back to a Startup-folder command file.

Remove it with:

.\Controll3r.exe --uninstall-service

UI takeover

Launching the desktop UI while headless mode owns the hardware presents a takeover choice.

If you accept:

  1. the headless host stops its REST listener
  2. it releases video, audio, and input hardware
  3. the UI acquires the hardware
  4. on UI exit, you can choose whether to restart the previous headless launch mode

The handoff is exclusive; Controll3r does not stream one capture session to multiple processes.

Enable the API in the UI

The REST server is disabled by default in normal UI mode.

  1. open Preferences > Webserver
  2. enable the server
  3. choose loopback-only or LAN access
  4. confirm the port, initially 7421
  5. copy or regenerate the bearer token
  6. save Preferences

Token changes take effect when the server restarts.

Address and transport

Loopback mode:

http://127.0.0.1:7421

LAN mode:

https://<operator-computer-address>:7421

LAN mode uses a locally generated self-signed certificate. Clients must trust that certificate or explicitly handle the expected self-signed-certificate warning. Do not disable certificate validation in production automation.

Authentication

GET /v1/health is intentionally unauthenticated as a liveness probe.

Every other /v1 endpoint requires:

Authorization: Bearer <token>

Missing or incorrect tokens return 401 Unauthorized and a JSON error.

PowerShell examples

$base = "http://127.0.0.1:7421"
$token = "<copy from Preferences > Webserver>"

curl.exe "$base/v1/health"
curl.exe -H "Authorization: Bearer $token" "$base/v1/macros"
curl.exe -H "Authorization: Bearer $token" `
  --output target.png `
  "$base/v1/screenshot"

Upload a macro:

curl.exe -X POST `
  -H "Authorization: Bearer $token" `
  -H "Content-Type: application/vnd.controll3r.macro+zip" `
  --data-binary "@C:\Macros\wake-host.c3rm" `
  "$base/v1/macros?name=wake-host"

Play it:

curl.exe -X POST `
  -H "Authorization: Bearer $token" `
  "$base/v1/macros/wake-host/play"

Endpoint summary

Method and path Purpose Auth
GET /v1/health Server and hardware readiness No
GET /v1/screenshot Current target PNG Bearer
GET /v1/macros List stored macros Bearer
POST /v1/macros Upload a new .c3rm Bearer
GET /v1/macros/{name} Metadata or bundle download Bearer
PUT /v1/macros/{name} Replace/store a named macro Bearer
POST /v1/macros/{name}/rename Rename a macro Bearer
DELETE /v1/macros/{name} Delete a macro Bearer
POST /v1/macros/{name}/play Run a macro Bearer
POST /v1/script Not available; always returns 410 Gone Bearer

Request a raw .c3rm from GET /v1/macros/{name} with Accept: application/octet-stream, the Controll3r macro media type, or ?download=1. Macro uploads are limited to 8 MiB per bundle.

Health response

{
  "status": "ok",
  "video": true,
  "audio": true,
  "interface": true
}

status: ok means the server is responding. The other fields independently report active video, audio, and Controll3r Interface state.

Macro playback response

A successful play request returns the macro name and any repeat safety limits reached:

{
  "status": "ok",
  "macro": "wake-host",
  "loopCaps": []
}

An empty loopCaps array means no repeat safety limit stopped the run.

Common API failures

HTTP status / code Meaning
401 unauthorized Bearer token missing or wrong
400 invalid_bundle Uploaded .c3rm is malformed or unsafe
400 macro_name_invalid Empty or unsafe macro name
404 macro_not_found Named macro is absent
409 macro_exists Create/rename target already exists
409 recording_in_progress Guided recording owns input
409 macro_playback_in_progress Another macro is active
409 pointer_device_disabled Absolute pointer is unavailable
409 operator_step_unavailable Macro requires a person in headless mode
503 interface_disconnected Controll3r Interface unavailable

Error bodies use:

{
  "error": "macro_not_found",
  "message": "Macro 'wake-host' was not found."
}

API safety notes

  • Keep the bearer token secret.
  • Prefer loopback mode unless another computer must connect.
  • Use firewall rules to restrict LAN access.
  • Treat screenshots and .c3rm files as potentially sensitive.
  • Headless macros containing Wait For Operator are rejected.
  • API playback uses the same exclusive hardware and input-safety path as UI playback.

The tables above summarize the complete public API surface for this release.