Elgato Key Lights
Making the lamp trust you instead of the vendor.
The Key Light Air MK.2 dropped the old open HTTP API. What replaced it is a JSON-RPC WebSocket that will not talk to a client without a certificate the lamp trusts — and a lamp paired with the vendor app trusts only the vendor’s chain.
lume’s answer is to make the lamp trust you. lume pki generates your own
certificate authority; onboarding installs it on a factory-reset lamp over
Bluetooth LE, together with your Wi-Fi credentials. After that the lamp is
yours — locally, permanently, with no vendor key material involved anywhere.
Onboarding
Onboarding is a one-time, hardware-proximate ritual, and this build hands the Bluetooth half to a tested Python companion rather than shipping a second, less proven BLE stack. Control and PKI are fully native.
lume pki # your own certificate authority
pipx install keylight-local
keylight-local onboard "MyWiFi" # factory-reset the lamp first
Then point lume at the certificates:
{ "type": "elgato", "host": "192.168.1.29", "certs": "~/.config/lume" }
certs may be a directory holding client.crt and client.key, or a path
prefix naming one pair — ~/.config/lume/cc-client — which is how two lamps
with different certificates live in one config.
What “not trusted” means
lume setup tells three failures apart, because they need different answers:
| state | what it means |
|---|---|
ready | usable now |
no certificate | run lume pki first |
not trusted | the lamp is there but refuses you — almost always still paired with the Elgato app |
unreachable | nothing answered on port 9123 |
While you are experimenting: a malformed request can crash the firmware’s JSON parser and reboot the lamp. If that lamp is the one lighting your face on a call, this is not a theoretical concern. lume always sends the shape the firmware expects — hand-rolled requests may not.
Limits
The Key Lights are white only, 2900–7000 K, so color returns a clear “not
supported” rather than pretending. watch shows what other clients do: the
lamp broadcasts state to every connection except the one that caused the change.