Files
OmniRoute/src/lib
Diego Rodrigues de Sa e Souza 3ef54fc55b feat(api): return every connection's snapshot under providers[] in om-usage json (#11192)
* feat(api): structured ?format=json for the self-service usage endpoint

GET /api/usage/om-usage already let any key read its own usage — personal
daily/weekly USD limits and the provider quota snapshot — but only as
text/plain, which a UI cannot parse safely. OmniCopilot issue #8 asks exactly
for this surface.

Adds ?format=json, returning the ApiKeyUsageLimitStatus + UsageSnapshot the
text is rendered from. Text and JSON share the same collectors
(collectUsageSnapshots, getApiKeyUsageLimitStatus), so the two can never
disagree about a number. The response is a discriminated union: a key without
allowUsageCommand (403) or an invalid key (401) returns
{ allowed:false, error:{message} }, distinct from allowed:true with empty
sections — the state a panel must render as "nothing learned yet", not a
refusal. Text form unchanged; without ?format the contract is untouched.

The endpoint was previously missing from API_REFERENCE.md; it now has a
section documenting both forms, the allowUsageCommand gate, and the
self-service auth model (caller's own key, not requireManagementAuth).

Regression guards in tests/unit/usage-command-json-format.test.ts (4 tests:
json shape, text default preserved, structured 403, sanitized 401 with no
stack trace). Existing internal-usage-command suite still 12/12.

* chore(changelog): correct the fragment to the real PR number (#11190)

* feat(api): return every connection's snapshot under providers[] in om-usage json

Closes #11191. buildUsageCommandJson picked a single snapshot via selectUsageSnapshot, so a panel could only ever show one provider. The collector already had them all — the single-pick is a presentation choice for a terminal. The JSON form now also returns the full UsageSnapshot[] alongside the selected provider, so a UI can render Codex / Claude / OpenCode side by side. The text form is untouched.

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-22 22:39:56 -03:00
..
2026-06-19 06:49:01 -03:00
2026-06-30 06:54:29 -03:00
2026-07-02 10:47:13 -03:00
2026-06-30 06:54:29 -03:00
2026-06-29 16:51:03 -03:00
2026-07-13 09:12:40 -03:00
2026-07-13 09:12:40 -03:00
2026-06-27 09:07:12 -03:00
2026-07-04 13:00:30 -03:00
2026-07-29 15:18:55 -03:00
2026-06-29 16:51:03 -03:00
2026-07-07 13:14:06 -03:00
2026-07-29 15:18:55 -03:00
2026-08-05 21:43:16 -03:00
2026-07-29 15:18:55 -03:00
2026-07-29 15:18:55 -03:00
2026-07-02 10:47:13 -03:00
2026-06-30 06:54:29 -03:00
2026-06-30 06:54:29 -03:00
2026-07-29 15:18:55 -03:00
2026-07-29 15:18:55 -03:00
2026-06-20 14:55:24 -03:00
2026-05-29 12:44:29 -03:00
2026-06-17 02:43:21 -03:00
2026-07-29 15:18:55 -03:00
2026-05-29 12:44:29 -03:00
2026-05-29 12:44:29 -03:00
2026-06-29 08:40:06 -03:00
2026-06-29 08:40:06 -03:00
2026-07-29 15:18:55 -03:00
2026-07-29 15:18:55 -03:00
2026-04-30 01:27:03 -03:00
2026-06-29 08:40:06 -03:00
2026-07-29 15:18:55 -03:00
2026-06-13 17:27:40 -03:00
2026-07-02 10:47:13 -03:00
2026-06-09 15:56:24 -03:00
2026-07-29 15:18:55 -03:00