Meters
Turn usage events into a billable quantity per customer and period.
See Usage-based billing for how meters, prices and events fit together.
The meter object
idstring
Prefixed
mtr_.objectstring
meternamestring
event_namestring
Matched against
event_name on usage events.aggregateobject
type (count, sum, max, min, avg, unique) and property.filterobject | null
Metadata conditions events must match.
unit_labelstring | null
unit_multiplierinteger | null
archived_attimestamp | null
created_attimestamp
updated_attimestamp
Create a meter
POST/v1/metersSecret key
Body
namestringrequired
Up to 200 characters.
event_namestringrequired
Up to 200 characters.
aggregate_typeenumrequired
count, sum, max, min, avg or unique.aggregate_propertystring
Metadata path such as
metadata.total_tokens. Required unless aggregate_type is count.filterobject
Only events whose metadata matches count, e.g.
{ "metadata.tier": "pro" }.unit_labelstring
Shown on invoices, e.g.
tokens.unit_multiplierinteger
Divide the aggregate by this before pricing.
Node.jsts
// Count API requests
const requests = await borga.meters.create({
name: "API requests",
event_name: "api_request",
aggregate_type: "count",
unit_label: "requests",
});
// Sum tokens, priced per million
const tokens = await borga.meters.create({
name: "LLM tokens",
event_name: "llm_completion",
aggregate_type: "sum",
aggregate_property: "metadata.total_tokens",
unit_label: "tokens",
unit_multiplier: 1_000_000,
});Errors: missing_aggregate_property.
Retrieve a meter
GET/v1/meters/:idSecret key
List meters
GET/v1/metersSecret key
Query parameters
archivedboolean
true includes archived meters.limitintegerdefault: 25
starting_afterstring
Archive a meter
DELETE/v1/meters/:idSecret key
Archived meters stop accepting events but keep their history and remain readable.
Meter quantity for a period
GET/v1/meters/:id/quantitiesSecret key
Aggregates one customer's events over a period.
Query parameters
customerstringrequired
period_starttimestamp
Defaults to the customer's current billing period.
period_endtimestamp
Response
{
"meter": "mtr_1Zx3Cv5Bn7Mq9We1Rt3Yu5Io",
"customer": "cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz",
"period_start": "2026-09-01T00:00:00.000Z",
"period_end": "2026-10-01T00:00:00.000Z",
"quantity": 14250,
"unit_label": "requests"
}Customer meter balance
GET/v1/customer-meters/:customerId/:meterIdSecret key
The live state of a customer's meter in the current period, including included units and overage.
Node.jsts
const balance = await borga.meters.balance(
"cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz",
"mtr_1Zx3Cv5Bn7Mq9We1Rt3Yu5Io",
);
console.log(balance.consumed_units, "of", balance.included_units);
console.log("overage:", balance.overage_units);Response
{
"customer": "cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz",
"meter": "mtr_1Zx3Cv5Bn7Mq9We1Rt3Yu5Io",
"period_start": "2026-09-01T00:00:00.000Z",
"period_end": "2026-10-01T00:00:00.000Z",
"consumed_units": 7420,
"included_units": 10000,
"balance": 2580,
"overage_units": 0
}Customer billing state
GET/v1/customer-state/:customerIdSecret key
Everything needed for a customer-facing billing page in one call: active, trialing and past-due subscriptions with their items, and every meter balance.
Response
{
"customer": "cus_8Jk2Lm4Np6Qr8St0Uv2Wx4Yz",
"subscriptions": [
{
"id": "sub_9Qw1Er3Ty5Ui7Op9As1Df3Gh",
"status": "active",
"current_period_start": "2026-09-01T00:00:00.000Z",
"current_period_end": "2026-10-01T00:00:00.000Z",
"cancel_at_period_end": false,
"items": [{ "id": "si_…", "price": "price_…", "quantity": 3 }]
}
],
"meters": [
{
"meter": "mtr_1Zx3Cv5Bn7Mq9We1Rt3Yu5Io",
"name": "API requests",
"unit_label": "requests",
"consumed_units": 7420,
"included_units": 10000,
"balance": 2580,
"overage_units": 0,
"period_start": "2026-09-01T00:00:00.000Z",
"period_end": "2026-10-01T00:00:00.000Z"
}
]
}