Skip to content

v0.9.0

Choose a tag to compare

@sagarsuperuser sagarsuperuser released this 28 Oct 20:10
· 63 commits to main since this release
72ca1d4

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 migrate and 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-bootstrap and hardcount-doctor. Settings are HARDCOUNT_*. API keys and ids start hc_. Images are ghcr.io/gethardcount/hardcount and ghcr.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, graduated or package. 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 key is now event_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_status when 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 force is 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.