Meter every paid call.
Usagekit reserves budget before every paid API call and settles the exact cost from its receipt. Build it into your product, or put it in front of your agents.
Monthly spend
Sample workspace, October 2026Used $18.12
of $25.0072.48% used
Exact to a ten-thousandth of a cent.
- Used
- $18.12
- Reserved
- $0.00
- Remaining
- $6.88
0 of 3 in flight
Operation log
No requests yet. Send one to watch $1.50 reserved, then settled from its receipt.
Two ways to use it.
One runtime meters both: the calls your product makes for its users, and the calls your agents make.
In your product
Show your users their usage, provider costs and budgets with shadcn blocks for Radix or Base UI, or with headless React hooks.
The runtime is on npm. The React layer runs from the repository checkout.
Monthly spend
Resets Nov 1
$18.12of $25.00
- Requests
- 11
- Reserved
- $0.00
- Remaining
- $6.88
For your agents
A local API proxy keeps provider keys in an encrypted vault. Budgets answer 429 before a call is sent, and a dashboard tracks usage.
Runs from the repository checkout, with SerpApi and DataForSEO built in.
GET /proxy/c1/search?q=aiIllustration- 200OKX-Usagekit-Accounting: metered
- 429Too Many Requests{"error":
"allowance_exceeded"}
Every paid call follows one lifecycle.
Admit only with headroom, grant exactly one dispatch, settle from evidence. Unknown outcomes stay reserved.
import type { AccessContext, MeterReserveInput } from "@usagekit/core";
import { loadBudgetsView } from "@usagekit/views";
import { callProvider, meter } from "./server";
export async function meteredCall(
access: AccessContext,
input: MeterReserveInput,
) {
const reserved = await meter.reserve(input);
if (reserved.outcome !== "reserved") return reserved;
if (reserved.replayed) return reserved; // A replay never dispatches.
const { namespace, principal } = input.scope;
const ref = { namespace, principal, operationId: input.operationId };
const grant = await meter.markDispatchIntent({
...ref,
commandId: `dispatch:${ref.operationId}`,
expectedVersion: reserved.operation.version,
holder: "api-worker",
leaseTtlMs: 30_000,
});
if ("outcome" in grant || !grant.granted) return grant;
const receipt = await callProvider(input); // The only provider call.
const settled = await meter.settle({
...ref,
commandId: `settle:${ref.operationId}`,
expectedVersion: grant.operation.version,
authority: { kind: "lease", leaseId: grant.lease.leaseId },
receipt, // An unknown cost settles as pending and stays reserved.
});
if (settled.outcome !== "settled") return settled;
return loadBudgetsView(meter, access, {
scope: input.scope,
surface: input.surface,
units: ["cents"],
crossings: settled.alerts,
});
}
Unknown is not zero.
Measured, estimated, unknown and unavailable are different states, and your UI can tell them apart.
Every cost has an owner.
Provider cost, funding source and customer charge stay distinct, so own keys run alongside platform funding.
Your application stays in charge.
You own authentication, verified access and billing. Usagekit supplies the metering mechanics.
One Store contract, any database.
The Store commits every command in one transaction, so two concurrent requests can never take the same headroom. Use an adapter or bring your own database.
One command, one transaction.
Headroom, version and lease are re-checked inside the transaction, not before it.
BEGIN IMMEDIATE
operationsState and versionreceiptsProvider evidencemeasurementsWhat each receipt measuredbudget_usageSpent plus reserved, per budget windowcommandsReplay journalbudget_alertsAlert crossingsoperation_eventsHistory for readers
COMMIT
Tables of the SQLite and Durable Object adapters. No prompts or responses are stored.
Latest command
Held by the in-memory Store on this page, read with meter.getOperation.
No command yet. Send a request in the console above.
Go to the console- Version 1
reserved, written byreserve - Version 2
dispatch_intended, written bymarkDispatchIntent - Version 3
settledorpending, written bysettle
Each command names the version it expects. A stale one gets version_conflict.
All or nothing. Every table commits or rolls back together.
Exact integers. No floating point, from estimate to receipt.
Safe to retry. A repeated command returns its stored result.
Crash-safe. Dispatched work is recovered from evidence, never sent twice.
import { createMemoryStore } from "@usagekit/store";
import { runStoreConformance } from "@usagekit/store/conformance";
import { createMeter } from "@usagekit/meter";
import { createPostgresFixture } from "./postgres-fixture.js"; // yours
// Tests and demos: the in-memory reference Store.
const clock = { now: () => new Date() };
const store = createMemoryStore({ clock, budgets: [] });
const meter = createMeter({ store, clock });
// Your database: the same suite the shipped adapters run.
runStoreConformance(createPostgresFixture, {
durable: true,
rollingWindows: false,
maxMoneyUnits: 2n ** 63n - 1n,
maxQuantityScale: 18,
});
Every shipped adapter runs this suite unchanged. Skipped capabilities are reported, never counted as passed.
Start with the runtime.
Four packages on npm. Embed the Meter in your server today, then add views, hooks and blocks from the repository checkout when you need UI.
Install from npm
0.5.0npm install @usagekit/core @usagekit/store @usagekit/meter @usagekit/providersAdd the React layer
@usagekit/react, @usagekit/views and the registry are not on npm yet. Build them from a checkout of the repository.
nvm use
npm ci
npm run build
npm run registry:build
Blocks then install from the local registry build with the shadcn CLI. Read the checkout guide
Metering real providers in bisibility.
bisibility is an open-source rank tracker with bring-your-own-key search providers. It is the example integration for provider usage, own keys and per-surface limits.
- Metering
- Limited rollout
- React UI
- Adoption in progress
- Usage
- Costs
- Limits
- App
- API
Questions, answered.
The documentation covers setup, hooks, blocks and provider management.
How is this different from usage-based billing?
Usage-based billing tools invoice your customers after the fact. Usagekit works before the call: it reserves budget, can block a request without headroom, and records the exact provider cost. It never invoices or sets customer prices, and your app keeps its wallets and credits. Send the ledger to your billing tool if you use one.
Do I have to use the React components?
No. Use the runtime alone, the pure view models, or only the hooks. The styled blocks are optional.
Can I use both BYOK and platform-funded providers?
Yes. Every reservation records its funding source and cost owner, so own keys and platform-funded calls stay explicit side by side.
What can I install today?
@usagekit/core, store, meter and providers 0.5.0 are on npm. React, views and the registry run from a repository checkout.
Can I customize the styles?
Yes. Blocks are copied into your app and use your own primitives. Choose Radix with the New York style, or Base UI.
Make every unit count.
Reserve before the call, settle from the receipt, and show every user exactly where they stand.
npm install @usagekit/core @usagekit/store @usagekit/meter @usagekit/providers