Skip to main content
Version: main

Unix Socket API

The keylightd daemon exposes a Unix socket interface for local control of Elgato Key Lights. This method is preferable for local automation scripts and command-line tooling, while the HTTP REST API is better suited for remote or web-based integrations.

Socket Location

The Unix socket is located at:

  • $XDG_RUNTIME_DIR/keylightd.sock (default on most systems)
  • Or fallback to /run/user/<uid>/keylightd.sock

You can override this location in the configuration file or through the --socket command-line flag when starting keylightd.

Protocol Overview

The API uses JSON for both request and response messages. Each request requires an action field specifying the operation to perform, and most operations require additional parameters.

Authentication

The Unix socket interface relies on Unix socket permissions for security. Only processes running as the same user as keylightd can access the socket, providing inherent security without additional authentication.

General Response Format

Successful responses have this structure:

{
"status": "ok",
"id": "request-id-if-provided"
}

Error responses look like this:

{
"error": "Error message explaining what went wrong",
"id": "request-id-if-provided"
}

Light Operations

List Lights

Retrieves all discovered lights.

// Request
{
"action": "list_lights",
"id": "optional-request-id"
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"lights": {
"Elgato Key Light ABC1._elg._tcp.local.": {
"id": "Elgato Key Light ABC1._elg._tcp.local.",
"productname": "Elgato Key Light",
"serialnumber": "ABC123456",
"firmwareversion": "1.0.3",
"firmwarebuild": 194,
"on": true,
"brightness": 50,
"temperature": 5000,
"ip": "192.168.1.100",
"port": 9123,
"lastseen": "2024-03-20T10:00:00Z"
}
}
}

Get Light

Retrieves information about a specific light.

// Request
{
"action": "get_light",
"id": "optional-request-id",
"data": {
"id": "Elgato Key Light ABC1._elg._tcp.local."
}
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"light": {
"id": "Elgato Key Light ABC1._elg._tcp.local.",
"productname": "Elgato Key Light",
"serialnumber": "ABC123456",
"firmwareversion": "1.0.3",
"firmwarebuild": 194,
"on": true,
"brightness": 50,
"temperature": 5000,
"ip": "192.168.1.100",
"port": 9123,
"lastseen": "2024-03-20T10:00:00Z"
}
}

Set Light State

Changes properties of a specific light. Supports both single-property and multi-property modes.

Single-property mode:

// Request
{
"action": "set_light_state",
"id": "optional-request-id",
"data": {
"id": "Elgato Key Light ABC1._elg._tcp.local.",
"property": "on",
"value": true
}
}

// Response
{
"status": "ok",
"id": "optional-request-id"
}

Multi-property mode — set multiple properties in a single request:

// Request
{
"action": "set_light_state",
"id": "optional-request-id",
"data": {
"id": "Elgato Key Light ABC1._elg._tcp.local.",
"on": true,
"brightness": 80,
"temperature": 3200
}
}

// Response
{
"status": "ok",
"id": "optional-request-id"
}

Light Properties

PropertyTypeValid RangeDescription
onbooleantrue or falsePower state of the light
brightnessinteger0-100Brightness percentage
temperatureinteger2900-7000Color temperature in Kelvin

Group Operations

List Groups

// Request
{
"action": "list_groups",
"id": "optional-request-id"
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"groups": [
{
"id": "group-123451",
"name": "office",
"lights": [
"Elgato Key Light ABC1._elg._tcp.local.",
"Elgato Key Light XYZ2._elg._tcp.local."
]
}
]
}

Get Group

// Request
{
"action": "get_group",
"id": "optional-request-id",
"data": {
"id": "group-123451"
}
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"group": {
"id": "group-123451",
"name": "Office Lights",
"lights": ["Elgato Key Light ABC1._elg._tcp.local.", "Elgato Key Light XYZ2._elg._tcp.local."]
}
}

Create Group

// Request
{
"action": "create_group",
"id": "optional-request-id",
"data": {
"name": "Office Lights",
"lights": ["Elgato Key Light ABC1._elg._tcp.local.", "Elgato Key Light XYZ2._elg._tcp.local."]
}
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"group": {
"id": "group-123451",
"name": "Office Lights",
"lights": ["Elgato Key Light ABC1._elg._tcp.local.", "Elgato Key Light XYZ2._elg._tcp.local."]
}
}

Delete Group

// Request
{
"action": "delete_group",
"id": "optional-request-id",
"data": {
"id": "group-123451"
}
}

// Response
{
"status": "ok",
"id": "optional-request-id"
}

Set Group Lights

// Request
{
"action": "set_group_lights",
"id": "optional-request-id",
"data": {
"id": "group-123451",
"lights": ["Elgato Key Light ABC1._elg._tcp.local.", "Elgato Key Light XYZ2._elg._tcp.local."]
}
}

// Response
{
"status": "ok",
"id": "optional-request-id"
}

Set Group State

Supports both single-property and multi-property modes. The id field supports comma-separated values to target multiple groups by ID or name.

Single-property mode:

// Request
{
"action": "set_group_state",
"id": "optional-request-id",
"data": {
"id": "group-123451",
"property": "on",
"value": true
}
}

// Response
{
"status": "ok",
"id": "optional-request-id"
}

Multi-property mode:

// Request
{
"action": "set_group_state",
"id": "optional-request-id",
"data": {
"id": "group-123451",
"on": true,
"brightness": 80,
"temperature": 3200
}
}

// Response
{
"status": "ok",
"id": "optional-request-id"
}

Multi-group targeting — target multiple groups with comma-separated IDs or names:

// Request
{
"action": "set_group_state",
"id": "optional-request-id",
"data": {
"id": "group-123451,office-lights",
"on": true,
"brightness": 75
}
}

Partial failure response — if some groups or lights fail:

{
"status": "partial",
"id": "optional-request-id",
"errors": [
"group group-123451: failed to set brightness: device unavailable"
]
}

API Key Operations

List API Keys

// Request
{
"action": "apikey_list",
"id": "optional-request-id"
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"keys": [
{
"key": "api-key-value",
"name": "My API Key",
"created_at": "2024-03-20T10:00:00Z",
"expires_at": "2024-03-21T10:00:00Z",
"last_used_at": "2024-03-20T10:00:00Z",
"disabled": false
}
]
}

Create API Key

// Request
{
"action": "apikey_add",
"id": "optional-request-id",
"data": {
"name": "My New API Key",
"expires_in": "86400"
}
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"key": {
"key": "actual-key-value",
"name": "My New API Key",
"created_at": "2024-03-20T10:00:00Z",
"expires_at": "2024-03-21T10:00:00Z",
"last_used_at": "2024-03-20T10:00:00Z",
"disabled": false
}
}

Delete API Key

// Request
{
"action": "apikey_delete",
"id": "optional-request-id",
"data": {
"key": "api-key-value"
}
}

// Response
{
"status": "ok",
"id": "optional-request-id"
}

Set API Key Disabled Status

// Request
{
"action": "apikey_set_disabled_status",
"id": "optional-request-id",
"data": {
"key_or_name": "api-key-value or key-name",
"disabled": "true"
}
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"key": {
"key": "api-key-value",
"name": "My API Key",
"created_at": "2024-03-20T10:00:00Z",
"expires_at": "2024-03-21T10:00:00Z",
"last_used_at": "2024-03-20T10:00:00Z",
"disabled": true
}
}

System Operations

Ping

Simple health check that returns a pong response.

// Request
{
"action": "ping",
"id": "optional-request-id"
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"message": "pong"
}

Health

Returns the service health status.

// Request
{
"action": "health",
"id": "optional-request-id"
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"health": "ok"
}

Version

Returns the running daemon's version, commit, and build date.

// Request
{
"action": "version",
"id": "optional-request-id"
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"version": "0.1.1",
"commit": "abc1234",
"build_date": "2024-03-20T10:00:00Z"
}

Subscribe to Events

Subscribes the connection to real-time state change events. After subscribing, the server will stream events as newline-delimited JSON (NDJSON) until the client disconnects.

// Request
{
"action": "subscribe_events",
"id": "optional-request-id"
}

// Initial Response
{
"status": "ok",
"id": "optional-request-id",
"subscribed": true
}

// Subsequent event messages (NDJSON stream)
{"type": "light_state_changed", "data": {"id": "Elgato Key Light ABC1._elg._tcp.local.", "on": true, "brightness": 80}}
{"type": "group_state_changed", "data": {"id": "group-123451", "property": "brightness", "value": 75}}
note

After subscribing, the connection enters streaming mode. No further request/response interactions are possible on this connection — it is dedicated to receiving events until disconnected.

Logging Operations

List Filters

Returns the current global log level and all active log filters.

// Request
{
"action": "list_filters",
"id": "optional-request-id"
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"level": "info",
"filters": [
{
"type": "source",
"pattern": "internal/server/*",
"level": "debug",
"enabled": true
}
]
}

Set Filters

Validates and replaces all active log filters. Invalid filters are rejected entirely.

// Request
{
"action": "set_filters",
"id": "optional-request-id",
"data": {
"filters": [
{
"type": "source",
"pattern": "internal/server/*",
"level": "debug",
"enabled": true
}
]
}
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"level": "info",
"filters": [
{
"type": "source",
"pattern": "internal/server/*",
"level": "debug",
"enabled": true
}
]
}

Each filter object supports:

FieldTypeDescription
typestringFilter type (e.g., "source")
patternstringGlob pattern to match
levelstringMinimum level for matching entries
output_levelstring(Optional) Override output level
enabledbooleanWhether this filter is active
expires_atstring(Optional) RFC3339 expiration timestamp

Set Level

Changes the global log level at runtime. Valid values: debug, info, warn, error.

// Request
{
"action": "set_level",
"id": "optional-request-id",
"data": {
"level": "debug"
}
}

// Response
{
"status": "ok",
"id": "optional-request-id",
"level": "debug"
}

Error Codes

Common error messages:

Error MessageDescription
"Invalid action"The specified action doesn't exist
"Missing required parameter: X"A required parameter is missing
"Light not found: X"The specified light doesn't exist
"Group not found: X"The specified group doesn't exist
"API key not found: X"The specified API key doesn't exist
"Device unavailable"The light device couldn't be reached
"Invalid input: X"The provided input is invalid

Example Usage

Using netcat

echo '{"action": "list_lights"}' | nc -U /run/user/1000/keylightd.sock

Using Python

import socket
import json

sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect('/run/user/1000/keylightd.sock')

request = {
'action': 'set_light_state',
'data': {
'id': 'Elgato Key Light ABC1._elg._tcp.local.',
'property': 'on',
'value': True
}
}

sock.sendall(json.dumps(request).encode('utf-8'))
response = sock.recv(4096).decode('utf-8')
print(json.loads(response))
sock.close()