Configurator API Doc

ClickUp export may have caused formatting errors

The configurator interface uses an HID output interrupt endpoint over USB to communicate with the host. 64-byte raw reports are sent from the host over the output endpoint, and the firmware responds by returning the same 64-byte report, but with some bytes changed as appropriate for returning results.

Conventions


  • All reports are 64 bytes long. If fewer bytes are required, the remainder of the report must be zero-padded to 64 bytes.
  • Byte ordering is little-endian unless otherwise specified, and values are unsigned unless otherwise specified.
  • Errors are usually indicated by replacing some or all bytes in the response report with 0xFF. Though there are legitimate uses of 0xFF bytes in responses, if unexpected fields in the response are replaced with 0xFF, the sender should assume the report generated an error.

Constructing Reports


Currently (may change; this interface is under active development and suggestions are welcome), all interactions in raw reports are initiated by the host.

Reports are of the form:

command byte - argument bytes - zero-padding

Command bytes currently implemented:

  • 0x01 - Get Interface Version (no args)
  • 0x02 - Set LED (two args - LED number, LED state)
  • 0x03 - Get Keymap Length (no args) - returns number of physical keys
  • 0x04 - Get Layers (see below)
  • 0x05 - Get Behaviors
  • 0x06 - Remap Key
  • 0x07 - Get Map for Key
  • 0x08 - Get number of keymaps
  • 0x09 - switch active keymap

API should match the functional spec:

  • Device Settings
  • Layers and Keymaps
  • Macros
  • Lighting
  • Reserved

Example


To get the interface version supported by the attached keyboard, the host would

send a report containing the following bytes:

01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

And the keyboard would respond with this report:

01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

…indicating that the version supported is Version 01.

Similarly, the following report would tell the keyboard to set led 7 to on (0x01):

02 07 01 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

In this case, the command is 0x02, the first arg (LED number) is 0x07, and

the second arg (state) is 0x01 - the rest of the bytes are ignored. The keyboard

should respond with the exact same report:

02 07 01 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

…and switch on LED 7. NOTE: the LED mapping of the keyboard for this test

command is strictly according to how the LED matrix chip is wired, and does not

correspond to any particular key. LED “7” in this case, for the V3 keyboard,

turns out to be the Blue LED on the key in the lower left-hand corner.

Command documentation


CommandArgumentsresponseNotes
0x01nonebyte 1 changed - version numberThis command guaranteed not to change
0x022 bytesunchanged reportbyte 1 == LED, byte 2 == state
0x03nonebyte 1 changed - number of keys
0x041 byte1+ bytessee below
0x051 byte1+ bytessee below
0x0611 bytesposition, layer, behavior index, param1 (4), param2 (4)
0x071 byte1 byte + (num layers * 10) bytessee below
0x08none1 bytenumber of keymaps supported
0x091 bytebyte unchanged or 0xFFswitch active keymap

Device Settings


0x01 - GET protocol version

Description:

This command takes no arguments, and returns a version number. Right now,

that will be a single byte representing what version of this interface the caller

should expect to deal with. Version 1 is currently the ONLY version, but that

may change in the future. The returned report will be identical to the sent

report, except for byte 1, which will be the version number.

Arguments: none

Response Format:

Request Example:

0xXX - GET model SKU

Description: Returns the device’s model number

Arguments: none

Response Format:

Example:

Riven Non-Split Non-RGB v0 Black: 00-00-00-FF

Riven Split RGB v2 White: 00-32-01-FF

0xXX - GET serial number

Description: Returns the device’s serial number

Arguments: none

Response Format:

Example:

00-32-01-FF-00-00-0B-44-22-11-85-51-57-F8-A1

0xXX - GET firmware version

Description: Returns the currently running firmware version

Arguments: none

Response Format:

Example:

1.0.1 non split: 01-00-01

Left 1.0.1 Right 1.0.2 01-00-01-01-00-02

0xXX - GET battery info

Description: Returns battery charge status and voltage in millivolts

Arguments:

Response Format: x bytes - ADC value

Example:

Full battery at 4.05V 0x01-0x00-0x00-0x0F-0xD2

Good battery at 3.98V 0x01-0x00-0x00-0x0F-0x8C

Layers and Keymaps

User Cases: in each of these cases, we demonstrate the Web Configurator querying the Keyboard for which version of the interface it supports. In reality, this only needs to be done once per session, or if the Web Configurator has some reason to believe it has changed since the last time. Same with queries for the number of physical keys, or the number of layers, or the number of keymaps.

User Case 1: When the Keyboard is connected to the Web Configurator, the Web Configurator is able to set the current active keymap

Configurator sends:

01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[Version 1 of protocol - update this doc for version 2]

Configurator sends:

08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

08 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[4 keymaps supported]

Configurator sends:

09 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

09 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[Keymap 02 is active]

User Case 2: When the Keyboard is connected to the Web Configurator, the Web Configurator is able to set the active layer of the active keymap

“Active layer” does not make sense - multiple layers can be active at a time. Not clear that this is a thing (which layers are active) which needs to be communicated to configurator. I’m currently thinking this one through

User Case 3: When the Keyboard is connected to the Web Configurator, the Web Configurator is able to display the key bindings (behaviors) of a specific key for each layer

Configurator sends:

01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[Version 1 of protocol - update this doc for version 2]

Configurator sends:

03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

03 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[0x48 physical keys - 72 keys. This is a V3 prototype board]

Configurator sends:

04 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

04 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[keymaps have 5 layers]

Configurator sends:

05 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

05 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[firmware supports 6 behaviors]

Configurator sends:

05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Keyboard returns:

05 00 4B 45 59 5F 50 52 45 53 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[behavior 0 is “KEY_PRESS”]

05 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

05 01 54 52 41 4E 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[behavior 1 is “TRANS”]

05 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

05 02 4D 4F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[behavior 2 is “MO”]

05 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

05 03 54 4F 47 47 4C 45 5F 4C 41 59 45 52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[behavior 3 - “TOGGLE_LAYER”]

05 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

05 04 42 4C 55 45 54 4F 4F 54 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[behavior 4 - “BLUETOOTH”]

05 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

05 05 4C 45 44 5F 54 4F 47 47 4C 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[behavior 5 - “LED_TOGGLE”]

Configurator sends:

07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[“get map for physical key 0”]

Keyboard returns:

07 00 00 03 01 00 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 02 01 00 00 00 00 00 00 00 00 03 01 00 00 00 00 00 00 00 00 04 05 63 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[07 00 - answer for “get map” “key 0”

NOTE: “param0” and “param1” are 32-bit (4 byte) little-endian values.

00 03 01 00 00 00 00 00 00 00 - layer=0, behavior=3, param0=1, param1=0

01 01 00 00 00 00 00 00 00 00 - layer=1, behavior=1, param0=0, param1=0

02 01 00 00 00 00 00 00 00 00 - layer=2, behavior=1, param0=0, param1=0

03 01 00 00 00 00 00 00 00 00 - layer=3, behavior=1, param0=0, param1=0

04 05 63 00 00 00 00 00 00 00 - layer=4, behavior=5, param0=99, param1=0

00 00 00 00 00 00 00 00 00 00 00 00 - PADDING

]

User Case 4: When the Keyboard is connected to the Web Configurator, the Web Configurator is able to remap the current key binding (behavior) to another key code

0xXX - GET keymap name based on index

Description: Returns keymap name string based on index

Arguments: index

Response Format:

Request Example:

0xXX - GET keymap

Description: Returns keymap data object by ID

Arguments:

Response Format:

Request Example:

0x03 - get keymap length

This command returns the number of physical key positions in the keymap in the

first byte. All other byte positions left unchanged.

0x04 - get layers

Depending on the contents of byte 1, this command returns either the number

of layers built into the firmware (if byte 1 is 0xFF, byte 1 gets replaced

with the number of layers) or a null-terminated string representing the

name of the layer of that index. If there is no such layer, the report

is returned unchanged. XXX - this is currently broken - the number

of layers gets returned, but the layer names don’t

0x05 - get behaviors

Depending on the contents of byte 1, this command returns either the number

of ZMK “behaviors” built into

the firmware (if byte 1 is 0xFF, byte 1 is replaced with the number of

behaviors) or a null-terminated string representing the name of the behavior

at that index number.

0x06 - remap key

Note: key remapping affects the currently-active map.

This command affects the active keymap, and takes the following arguments:

  • byte 1: key position to remap
  • byte 2: layer of map to change for position
  • byte 3: index of behavior to assign to key
  • byte 4-7: little-endian 32-bit value for param1 of behavior
  • byte 8-11: little-ending 32-bit value for param2 of behavior

See ZMK behavior documentation for

more information on behaviors and values for the parameters.

If any parameters are invalid (bad position, layer, or index value), the

report returned will have all 11 bytes replaced with 0xFF. Otherwise,

the report is returned unchanged.

0x07 - get key map

Note: this can only retrieve info for the currently-active map

This command takes one byte as input - the key position to retrieve mapping information from. If the key position is invalid, a report with all bytes except the command replaced with 0xFF is returned. Otherwise, 10 bytes per layer is returned (keeping the key position in byte 1):

  • 1 byte for layer number
  • 1 byte for behavior index number
  • 4 bytes for little-endian 32-bit param1 value
  • 4 bytes for little-endian 32-bit param2 value

To know how many layers to expect, use command 0x04 - “get layers”.

0x08 - get maps

This command takes no arguments, and returns the number of keymaps supported

by this firmware in byte 1.

0x09 - switch active keymap

This command expects the number of the map to make active in byte 1. If

the map number supplied is invalid, it is replaced with 0xFF, otherwise

the report is returned unchanged.

0xXX - SET keymap definition

Description: Set keymap definition

Arguments: keymap data object

Response Format:

Request Example:

0xXX - SET active keymap

Description: Set active keymap by ID

Arguments:

Response Format:

Request Example:

Macros

Definition of Macro Behavior

0xXX - GET list of macros

Description: Returns list of macro IDs

Arguments:

Response Format:

Request Example:

0xXX - GET macro definition

Description: Returns macro data object by ID

Arguments:

Response Format:

Request Example:

0xXX - SET macro definition

Description: Persist macro definition, returns macro ID

Arguments:

Response Format:

Request Example:

0xXX - DELETE macro definition

Description: Remove macro by ID

Arguments:

Response Format:

Request Example:

Lighting

RGB LED behavior

0x30 - GET list of lighting patterns

Description: Returns list of lighting patterns IDs

Arguments:

Response Format:

Request Example:

0x31 - SET lighting pattern

Description: Persist lighting pattern and return pattern ID

Arguments:

Response Format:

Request Example:

0x32 - SET active lighting pattern

Description: Set active lighting pattern

Arguments:

Response Format:

Request Example:

0x02 - set led

This is primarily an example, testing-only command. You can turn individual LEDs

off or on by setting the state to zero or non-zero, respectively. The returned

report will ALWAYS be identical to the sent report.

#Keyboard Configurator