With JSON, it's a trade-off. You're either doing the heavy lifting on device side or you're doing it on the client side.
This was my first project where I worked with binary and I learned some neat tricks. For example, the simulator that runs on the Arduino has to downsample the colors to work within the constraints of the 3-bit color that the "Ansiterm" library offers. When I first approached the problem, I was envisioning a complicated series of "if" statements to map the 8-bit color to 3-bit. Then it hit me: I could simply mask all but the highest bit of each of the 8-bit R/G/B colors and use that to generate my ANSI color blocks. This is something that I might not have learned if I was using JSON to pass the data.
Match on opening bracket, skip forward to third double-quote, ingest string until hit unescaped double-quote, process string.
EDIT: You're looking at up to like 6 bytes of overhead:
{"a":"<blob>"}