Skip to main content

Elgato Key Light

On-LAN control of the Elgato Key Light family — Key Light (Panel), Key Light Air, Key Light Mini, and the Ring Light — over the on-device HTTP JSON API. Common in home offices, streaming rigs, videoconferencing rooms, podcast studios, and small production suites. No cloud dependency; no authentication.

Prerequisites​

  • On-network. The light and the GEM controller share an L2 segment, or a routed subnet with unicast HTTP allowed. Discovery in the Elgato apps uses mDNS/Bonjour; GEM binds by IP.
  • Reserved IP. Pin the fixture to a specific IP on the DHCP server. The mobile apps rediscover by mDNS after a lease change, but GEM does not.
  • Firmware 1.0.3 or newer for the /elgato/accessory-info endpoint. Older firmware still works; the driver logs the miss and continues.

Setup​

  1. Onboard in the Elgato Control Center app (Windows, macOS, iOS, Android). GEM does not do Wi-Fi provisioning — the fixture has to join a network first via Elgato's app.
  2. Note the IP the light received from DHCP. Pin it via a reservation so the fixture keeps that address.
  3. Add the device row in GEM under Admin → Devices → Add:
    • Driver: elgato_key_light
    • Name: e.g. key_light_desk
    • Attribute ip: the LAN IP from step 2.
  4. Save. The driver connects, reads /elgato/accessory-info, and starts polling /elgato/lights every 5 s. A light that is off the network when GEM starts is still polled, and its identity attributes are read the first time it answers.
  5. Run get_status to confirm the current on/brightness/temperature come back.

Attributes​

Required​

NameTypeDescription
ipstringLAN IP of the light. Pin it via DHCP reservation.

Optional​

NameTypeDefaultDescription
portint9123TCP port for the light's HTTP API. Vendor never changes this in the field. A value that is not a port number (1-65535) falls back to 9123.
status_intervalint5000Milliseconds between status polls. Lower for tighter widget UI; higher to reduce network chatter. Values under 1000 are raised to 1000; an unparseable or out-of-range value means 5000.
request_timeoutint10000Milliseconds to wait for each HTTP reply. An unparseable, zero or negative value means 10000.

Populated by the driver​

The driver writes these attributes on connect and on every poll:

NameSourceDescription
product_name/elgato/accessory-infoe.g. Elgato Key Light
firmware_version/elgato/accessory-infoe.g. 1.0.3
firmware_build/elgato/accessory-infoVendor build number.
hardware_board_type/elgato/accessory-infoBoard revision.
serial_number/elgato/accessory-infoFixture serial.
display_name/elgato/accessory-infoThe label the user set in Control Center.
power_state/elgato/lightson / off.
level/elgato/lightsBrightness 0-100.
temperature_elgato/elgato/lightsRaw Elgato "mireds" 143-344 (143=cool, 344=warm).
temperature_kelvinderivedKelvin equivalent 2900-7000, computed from the mireds value.

Commands​

CommandArgsNotes
on—Sets on=1 on the first light in the array.
off—Sets on=0.
toggle—Reads current, flips it. Toggles sent in quick succession run one after another, so a double tap returns the light to where it started.
set_levellevel (0-100)Also implicitly turns the light on when the level is > 0 (matches Control Center behaviour).
set_cttemperature (Kelvin, 2900-7000)Converted to Elgato's inverted mireds internally. Out-of-band values are clamped.
set_stateon, level, temperature (all optional)One-shot combined write. A blank level or temperature is left unchanged, the same as omitting it. A non-numeric value, or an unfilled placeholder such as [level], is refused without sending anything. A blank on still turns the light off.
get_status—Reads /elgato/lights and reflects the state back onto GEM attributes.
get_info—Reads /elgato/accessory-info.
raw_commandpath, method, bodyEscape hatch for any /elgato/* endpoint the vendor adds in future firmware. A path without its leading / gets one added. A blank body sends no body. An unfilled placeholder in any argument is refused.

Zone address format​

Elgato Key Light devices are single-fixture endpoints — one device row per light. This driver sets supports_zones: false, meaning you typically wire a Control Zone directly at the device (zone.device_id = <this device>) instead of using zone addresses.

If you do bind zones anyway (e.g. for logical grouping in a UI), the driver will fan state and level writes out to every bound zone whenever it polls new state.

Known limitations​

  • No panel identify. The Elgato Control Center's flash-to-identify uses a companion feature not exposed by the local HTTP API. Use get_info and the display_name field for on-network discovery.
  • Multi-light Ring Light. The Ring Light returns an array of lights[]. This driver writes the same payload to lights[0] — Control Center behaves the same for the panel-level API.
  • No software transitions. The firmware ramps its own quick transition; there is no local API to control ramp time. The default_transition attribute is reserved for a future software-side fade and is a no-op today.
  • No colour-temperature units toggle. The Elgato mireds range 143-344 is a fixed inverted mapping to roughly 7000K…2900K. Values outside that band clamp.

Troubleshooting​

ECONNREFUSED on connect. The IP is wrong, or the fixture is off the LAN. Ping it. If ping works but port 9123 refuses, power-cycle the light — the internal HTTP server occasionally locks up on stale firmware.

The light went offline. After three missed polls the driver polls less often, doubling the gap up to once a minute (or your status_interval, if that is longer). Once the light answers a poll or a command, polling goes back to the normal interval from the next poll on. A reply that is not JSON, such as another device's web page after a DHCP change, makes get_status return reply was not json and leaves the light's state attributes unchanged.

get_status returns state but commands don't take. Check the fixture didn't fall back to isolated-AP mode (setup mode). It advertises Elgato Key Light XXXX on Wi-Fi. If it did, re-onboard through Control Center.

Level and temperature snap back after a command. The Elgato mobile app is actively pushing state at the same time. Close Control Center on nearby devices; the last write wins.

404 on /elgato/accessory-info. Firmware older than 1.0.3. Everything else still works; the driver logs the miss and continues without device-identity attributes.

Follow-ups​

  • Bonjour-based auto-discovery on the LAN — surface a "found N Key Lights" step in the network scanner.
  • Software-side transition fade for macros that want a slow ramp.
  • Ring Light per-panel addressing (currently the driver treats the whole ring as one light).