anomalyco / anomalyco/opencode
Zen API: expose credit balance in GET /zen/go/v1/usage (or /zen/v1/balance)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 7h 2m
- Merged PRs (30d)
- 384
Description
Summary
The Zen API does not expose the workspace's credit wallet balance. GET /zen/go/v1/usage returns only Go-subscription usage windows (rolling/weekly/monthly), while the credit balance — shown on the console billing page and backed by BillingTable.balance — is only retrievable from the web console through a SolidStart server function (billing.get → Billing.get()), which requires an authenticated browser session. API-key callers have no way to read it.
Today the only key-authenticated balance signal is the error thrown at $0:
Insufficient balance. Manage your billing here: https://opencode.ai/workspace/<id>/billing
i.e. binary, no number, and only after the money is gone.
Request
Add the credit balance to the existing usage endpoint:
GET /zen/go/v1/usage (same Authorization: Bearer key auth)
{
"usage": {
"rolling": { "status": "ok", "percent": 12, "resetsAt": "..." },
"weekly": { "status": "ok", "percent": 34, "resetsAt": "..." },
"monthly": { "status": "ok", "percent": 56, "resetsAt": "..." }
},
"balance": {
"usd": 4.10,
"currency": "USD",
"asOf": "2026-08-22T17:00:00Z"
}
}
A dedicated GET /zen/v1/balance returning the same balance object would also work. Returning it as part of the current usage endpoint keeps one polling endpoint for everything a monitor needs.
Use cases
- Programmatic monitoring (status-bar widgets, dashboards, budget alerts) without scraping the console in a logged-in browser.
- Early warnings before requests start failing with
Insufficient balance— e.g. notify at $5 remaining. - Workspaces that enable "Use balance" as a Go fallback: knowing the remaining balance tells you how much headroom the fallback actually has.
Notes
- Keys are workspace-scoped and the balance is the same workspace's balance, so this adds no new exposure surface.
- The console already shows this exact value to the same user at
opencode.ai/workspace/<id>/billing(formatBalance=balance / 1e8, seepackages/console/app/src/routes/workspace/common.tsx).
Relevant sources:
packages/console/app/src/routes/zen/go/v1/usage.tspackages/console/app/src/routes/zen/util/handler.ts(balance check +CreditsError)packages/console/core/src/billing.ts(BillingTable.balance)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/console/app/src/routes/zen/go/v1/usage.ts to trace the existing authenticated usage response, then read packages/console/app/src/routes/zen/util/handler.ts and packages/console/core/src/billing.ts for balance access and workspace scoping. Confirm how the console formats BillingTable.balance in packages/console/app/src/routes/workspace/common.tsx. Done means API-key callers receive the workspace balance alongside usage, with the documented fields and without changing existing usage data.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, payments
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100