Repository navigation
v0.9.0
The first release named Hardcount (the project was called Velox). Usage prices belong to the plan, a usage event says when it will not be billed, prepaid credit carries its currency, and migrations run with goose.
Before you install
- v0.9.0 installs fresh only. It cannot upgrade a database made by Velox (v0.8.x or a build of
main).hardcount migrateand start-up refuse such a database and change nothing in it. Start a new install: quick start or one VM. - Every name changed once. Commands are
hardcount,hardcount-bootstrapandhardcount-doctor. Settings areHARDCOUNT_*. API keys and ids starthc_. Images areghcr.io/gethardcount/hardcountandghcr.io/gethardcount/hardcount-dashboard. Headers, metrics and cookies use the new name. The full list is in the CHANGELOG. - Code that calls the API must change. Key prefixes, header names and several fields changed, and publishable API keys are removed. The CHANGELOG lists each change and its replacement.
What changed
Pricing
- Usage prices are set per plan, so two plans can charge different rates for one meter. A price is
per_unit,graduatedorpackage. A price change applies from each subscriber's next billing period, on a test clock too. - A meter has one aggregation, fixed once it has a usage event. Its
keyis nowevent_name. - The base fee stays locked while a subscription uses the plan. To change it, make a new plan.
Usage
- A usage event's answer carries
billing_statuswhen Hardcount finds a reason it will not be billed: no price takes it, the plan does not price its meter, no subscription covers its time, or its period was already invoiced. - LiteLLM: Claude Code,
/v1/responses, Gemini and pass-through calls are billed, cache writes bill under their own token types, and new Claude models arrive under their own names.
Payments and credit
- A card payment the bank wants the customer to confirm (3-D Secure) is no longer treated as a declined card.
- Prepaid credit carries its own currency and pays only invoices in that currency.
- Card disputes are recorded, and a refund whose result Stripe did not confirm reads
unknown.
API and operations
- One shape for the API: lists answer
{data, total}, every error uses one envelope, and a request body with an unknown field is refused. - Migrations run with goose. A failed migration leaves nothing to repair, and
hardcount migrate forceis gone. - The commands in the first-invoice guide run in CI on every pull request.
Images are signed with cosign (keyless). Every change, with its reasoning: CHANGELOG.