TL;DR: I made this API for programming the Corsair K70 RGB keyboard. See the unit test project for sample code. Have fun!
Introduction
Over the past year I’ve explored my taste in mechanical keyboards. Initially satisfied with the affordable Rosewill Apollo with Cherry MX browns, I moved on to the popular Corsair K70 with reds at the recommendation of friends. Pleased by the media keys but disappointed in the red switches, I pulled the trigger on a Cyber Monday sale of the K70 RGB with browns.
Partially due to negligent research, I was excited to get the new keyboard. Corsair’s software is generally bad but I vaguely remembered you could script the keyboard lighting. Obviously, this would open up the possibilities for programmable lighting on the keyboard, such as reactive coloring based the state of an application. Unfortunately, I remembered wrong.
Well… I had to justify the purchase somehow! I looked for existing solutions but, as a Windows user and stubborn C# developer, none were satisfying. So I started from scratch.
The Payload Format
The first step was to determine how the Corsair Utility Engine (CUE) controls the lighting. To see the messages being sent to the keyboard, I downloaded USBPCap to sniff the packets being sent to the keyboard.
Most of my devices were grouped under a single root hub and the keyboard did not have an obvious label, so I captured on the entire hub (“\\.\USBPcap3”) intending to filter the results. During the capture I used CUE to set the keyboard LEDs to see what that behavior looks like on the wire.
After capturing, the results needed massive filtering. The mouse movement had flooded the interface, so that was the first to get removed. The last packets, which represented the “Ctrl-C” key press to stop the capture, were from device 5. After filtering to device 5, there was only one set of packets going from the PC to the device.
I’m skipping some steps, but after several captures I was able to determine the payload format for this type of command:
Header (27 bytes)
Prefix (1 byte) = 0x7F for data packets, 0x07 for final packet
Sequence Number (1 byte) = 0x1 - 0x4 for data packets, 0x27 for final packet
Data Length (1 byte) = 0x3C for first 3 packets, 0x24 for last data packet, 0x2 for final packet
Suffix (1 byte) = 0x00
Data (60 bytes)
A payload with total size of 216 bytes is spread out over 5 packets. Investigating the contents after setting several different colors reveals the following format.
Red (72 bytes)
Green (72 bytes)
Blue (72 bytes)
You may have noticed in the Wireshark screenshot that the values in the payload never exceed 0x7. Evidently, each key has 4 bits representing each color with one always set to zero, for a total of 3 bits per color. Some may be reminded of the controversy surrounding the keyboard’s color range, and this confirms 9 bits representing 512 total colors.
The Device
Next up was determining how CUE’s behavior could be replicated in other software and exactly where the packets should be sent. Using some Device Manager pseudoscience, I sorted by type to list the USB devices together. This revealed a composite device with two keyboard devices. Disabling the “HID-compliant” siblings, shown below, betrayed the device as the keyboard when they completely broke CUE.
Inspecting the devices’ properties exposed additional information; fortuitously, they use the generic HID driver which all but confirmed the ability to influence the keyboard independently of CUE. The properties also revealed the vendor and product ID, which would be useful later.
The Code
Finally, it was time to send a test command. With little interest in wrapping the native methods myself, I discovered HidLibrary, a convenient C# wrapped for HID communication. Using the vendor and product IDs from earlier, the keyboard devices were easily enumerated. One had the capability of a 65 byte report size, which matched our 64 byte packet with a one byte prefix for HID report ID. After divvying up a synthesized payload into the set of packets expected by the device, the keyboard responded as it had to the CUE software.
From here I fleshed out the API and made some fun tests that can be used as example code. The methods allow setting of keys individually or providing a picture to be displayed to the device, which sounds nicer that it is. The project only supports the K70 but should be extensible to other Corsair RGB keyboards which likely use the same packet format.





I’m looking to use the K70 with my Razer Deathadder chroma, so pressing the m4 and m5 keys can effect my lighting as well as making a key press change lighting modes while still actually functioning as a key press. I’m just wondering if you could help me with setting up the API or sending me some resources as to where I could implement something to track key presses. (I used to program a lot in C++ and Java, mostly on Arduino and Processing, but I’m a little rusty)
Sorry for the delayed response – I don’t read these messages often since I have to filter through all the spam 🙂
The only way I’ve done this, and surprisingly a common way to do this, is to use a hidden Windows Form. Windows Forms have built in key listening capability, which you can use to execute code (for instance code to change the keyboard lightning) in response to a key press.
As for a “less hacky” way to do this by directly listening or subscribing to events, I’m not sure – sorry. If you already have a solution, I would love to hear what you came up with!
Do you know how I would use this to display the time on my keyboard
That is a great idea! But the resolution might be a little lacking…
In order to do this you would need to program the key lighting such that they would display the time. If I get the time someday I might implement some extensions like your suggestion, but until then folks are unfortunately on their own for implementing this type of thing.
And how can i program my keyboard with this now? And is it possible to set the light that it shows a health bar from a game for example? Because it looks like no one knows how to program these things….. And im from germany so sorry for bad english^^ Oh and can there be bugs or can i “break” something with this?
Yeah, you could do that type of thing (health bar) assuming the game has some sort of API for retrieving that information. Alternatively, you could have it capture part of the screen and display it (at a very low resolution), effectively mocking the health bar.
Unfortunately you need to understand C# to program the API, which means it’s not suitable for the non-programmer like CUE (the Corsair Utility Engine). And, like mentioned before, I don’t have time to implement extensions right now – even people have suggested some great ideas!