Summary
Cost-tracking is wired across the engine (verified in #526). Whalescale's Settings → Usage page needs a single rollup endpoint instead of computing aggregates client-side from individual turn events.
Proposal
`GET /v1/usage?since=&until=&group_by=<day|model|provider|thread>` returning:
```json
{
"since": "...",
"until": "...",
"group_by": "day",
"totals": { "input_tokens": ..., "output_tokens": ..., "cached_tokens": ..., "cost_usd": ... },
"buckets": [
{ "key": "2026-05-04", "input_tokens": ..., "output_tokens": ..., "cached_tokens": ..., "cost_usd": ... }
]
}
```
Source data: existing per-turn cost records in `runtime_threads.rs` / `session_manager.rs`.
Tracks
- whalescale#261 — Settings → Usage (no aggregation endpoint)
- Umbrella: whalescale#228
Acceptance
- New endpoint added to `runtime_api.rs` route table; documented in `docs/RUNTIME_API.md`.
- `group_by` supports at minimum `day` and `model`; thread/provider can be follow-ups if scope creeps.
- Returns empty `buckets` (not 404) when the time range has no data.
Summary
Cost-tracking is wired across the engine (verified in #526). Whalescale's Settings → Usage page needs a single rollup endpoint instead of computing aggregates client-side from individual turn events.
Proposal
`GET /v1/usage?since=&until=&group_by=<day|model|provider|thread>` returning:
```json
{
"since": "...",
"until": "...",
"group_by": "day",
"totals": { "input_tokens": ..., "output_tokens": ..., "cached_tokens": ..., "cost_usd": ... },
"buckets": [
{ "key": "2026-05-04", "input_tokens": ..., "output_tokens": ..., "cached_tokens": ..., "cost_usd": ... }
]
}
```
Source data: existing per-turn cost records in `runtime_threads.rs` / `session_manager.rs`.
Tracks
Acceptance