The dashboard reads. The daemon stays the source of truth.
app.haltonmeter.com is the Halton Meter Cloud dashboard: the Next.js
front-end of the paid multi-tenant SaaS. It is a different thing from the
two open-source pieces you may already run. The OSS halton-meter daemon
captures your outbound LLM traffic locally, and the bundled OSS personal
dashboard renders that local store at localhost:3000. The cloud dashboard
is hosted, multi-tenant, and shows a tier-gated copy of the data the daemon
chooses to sync. It reads cost, usage, and analytics from the FastAPI
backend at api.haltonmeter.com (routers under /v1/, backed by
Postgres 16).
The cloud is opt-in. The daemon ships cloud.enabled = false and nothing
syncs until you run halton-meter cloud connect and complete pairing. See
the Cloud overview for the product framing; this page is
the orientation to the dashboard surface itself.
1. How the dashboard relates to the daemon
The daemon and the dashboard are separate programs in separate repos, and they talk over a narrow, one-directional contract.
The daemon's local SQLite at ~/.halton-meter/db.sqlite is the source of
truth for every captured request. The dashboard never reaches into that
store. When you pair a machine, the daemon syncs a metadata batch to the
backend over POST /v1/requests/batch; the dashboard then reads the synced
copy from Postgres. The local data is never moved, never deleted, and never
mirrored back. If you disconnect, your local store and halton-meter report
keep working unchanged.
The two halves use disjoint API surfaces:
| Caller | Talks to |
|---|---|
| Daemon | /v1/pairing/*, /v1/requests/batch, /v1/requests/{id}/body, /v1/daemon/*, /v1/reconciliation/daemon-totals |
| Dashboard | the workspace read/analytics routes under /v1/ |
One more honest detail about the synced copy: the cloud does not trust the
daemon's cost figure. On ingest it recomputes cost from its own seeded
pricing_rates and writes the authoritative value. The daemon's submitted
cost is kept alongside for drift audit only. If no rate exists for a
(provider, model) pair, the row is left unpriced rather than guessed, and
rollups exclude-and-flag it instead of summing it as zero.
2. The workspace surfaces
The dashboard surfaces roughly fourteen first-class [workspace]/* pages.
Each one is tier-gated: a tier-locked route returns 403 with body
{error: 'tier_locked', feature, min_tier, current_tier} rather than
silently hiding the data. The wire tier names are solo / team /
enterprise; the dashboard renames enterprise to the display label
Business+.
| Surface | Reads | Lowest tier |
|---|---|---|
| Overview | Aggregated spend rollups by project, model, provider | Solo |
| Traces | Per-request receipts within a tier-bound window | Team |
| Projects | Per-project spend and attribution | Solo |
| Optimisation | Recommendations from realised usage patterns | Solo |
| Reports | Personal-summary and client-invoice report templates | Solo |
| Reconciliation | Logged spend vs provider invoice totals | Business+ |
| Executive | Workspace-wide P&L and departments view | Business+ |
| Audit | Append-only log of state-changing events | Business+ |
| Settings | Workspace config, members, roles, billing | Solo |
The Traces window is bound by tier: Solo sees the last 7 days, Team sees the last 30 days, and Business+ archives older receipts to the Audit surface. The retention numbers shown elsewhere in the product are still being reconciled, so treat the exact per-tier promise as draft.
Per-tier data-retention period as advertised to customers: the repo carries
a 365-day data_retention_days default, a Solo 7-day Traces window, and a
separate "Solo advertises 90-day retention" note for optimisation windows.
These do not yet agree, so no fixed retention promise is stated here.
3. Sign-in and where pairing lands
Sign-up and sign-in happen at cloud.haltonmeter.com. Authentication is
handled by Clerk in production, and billing is Clerk Billing. Once you are
in, the dashboard itself lives at app.haltonmeter.com.
A workspace is the billing and isolation unit. Solo workspaces are user-scoped; Team and Business+ workspaces are backed by a Clerk Organization. Members join through a role they hold per workspace, which the backend resolves as the authoritative role rather than trusting a global token claim. The dashboard collapses the canonical role set to six display names: owner, admin, editor, viewer, and billing. For the full model see Workspaces.
Pairing lands at app.haltonmeter.com/connect. This is the backend's
pairing_dashboard_url default, and it is where you paste or open the
daemon's pairing code to bind a machine to a workspace. Start the flow from
the machine you want to pair:
$ halton-meter cloud connect
The daemon prints an eight-character code and a app.haltonmeter.com/connect
URL, then long-polls for approval. When you approve in the browser, the
backend mints a single-shot hm_sync_… sync key scoped to one workspace and
one machine, and the daemon stores it. The full handshake, the token file
locations, and disconnect are covered in Connect your meter.
See also
- Cloud overview: what Cloud adds and when you don't need it
- Connect your meter: the pairing handshake end-to-end
- Workspaces: workspaces, members, roles, RBAC
- Cloud dashboards: the surfaces in detail
- Sync and retention: what syncs and the retention windows
- Cloud security: auth, encryption, data handling