I get the usage numbers I trust today by adding input_tokens, cache_creation_input_tokens and cache_read_input_tokens by hand from --output-format json on single non-interactive runs, which works for a lab and is useless for a day of real sessions. If the per-model chart carried the split between those two cache fields, it would show where the bytes go for Claude Code, since input_tokens on its own hides it. I would have got the SSE parsing wrong first, so I would start reading at the streaming support.
I get the usage numbers I trust today by adding input_tokens, cache_creation_input_tokens and cache_read_input_tokens by hand from --output-format json on single non-interactive runs, which works for a lab and is useless for a day of real sessions. If the per-model chart carried the split between those two cache fields, it would show where the bytes go for Claude Code, since input_tokens on its own hides it. I would have got the SSE parsing wrong first, so I would start reading at the streaming support.