Usage Quota + Overage
This guide shows how to offer an included monthly quota (credits) for a usage-based feature and charge overage automatically when usage exceeds the quota.
What you’ll build:
- A plan with a usage component (per-unit price)
- An included monthly quota via usage credits that renew on billing
- Server-side metering with events
- Optional feature gating: soft cap (allow but bill) or hard cap (block when quota is exhausted)
Important notes:
- Prepaid top-up credit packs are not supported yet.
- Send usage events from your server only.
1) Configure pricing (UI)
In Plans → Create:
- Add your base components (optional).
- Add a Usage component:
- Set
unit_cost_cents
(e.g., $0.05 per unit). - Link it to a metric/event name (e.g.,
api-calls
). This is used for usage calculation.
- Set
Billing uses: quantity = usage in period
, charge = quantity × unit_cost_cents
.
2) Define the monthly included quota via credits
Create a plan-scoped Usage Credit Definition that renews on billing. If you want the credit application to show on invoices, set billingVisible: true
.
Example: 10,000 calls included per month, credited against the specific usage component.
curl -X POST "https://api.getlumen.dev/v1/credits/definitions" \
-H "Authorization: Bearer $LUMEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scope": "plan",
"applicationType": "usage",
"planId": "plan_abc",
"priceId": "price_123",
"priceComponentId": "comp_usage_xyz",
"name": "Monthly API Quota",
"defaultAmount": 10000,
"refillAmount": 10000,
"renewOnBilling": true,
"billingVisible": true
}'
Behavior:
- On subscription creation, initial grants are created for matching plan definitions.
- On each billing cycle, usage for the component is computed; billing-visible usage credits are applied as negative line items; the remainder is overage.
3) Meter usage from your backend
Send events when usage occurs. The name
must match your metric/event for the usage component.
import { sendEvent } from "@getlumen/server";
await sendEvent({
name: "api-calls", // matches the usage component metric
value: 1, // defaults to 1 if omitted
userId: "user_ext_123" // your external user ID or use lumenCustomerId
});
Notes:
- This function should be called on the server. It uses your secret API key.
- If you’re seat-based, send per-seat events using each seat user’s external ID; billing will aggregate per organization.
4) Entitlement checks for hard/soft caps
Soft cap (default): Don’t block usage; send all events. Overage is billed automatically.
Hard cap: Check entitlement before allowing work. For numeric features, entitlement considers plan feature value, credits, and current usage within the billing window.
import { isFeatureEntitled } from "@getlumen/server";
const allowed = await isFeatureEntitled({
userId: "user_ext_123",
feature: "api-calls",
});
if (!allowed) {
// Block or degrade; prompt upgrade
}
If you need precise UI counters, fetch detailed entitlements (including usages
and creditInfo
) via the Entitlements API.
Note: The feature
slug you check (e.g., api-calls
) must exist on the plan. When you add a usage feature in the plan UI, the matching feature is created and linked to the metric; otherwise, create a feature with that slug before gating.
5) Billing you can expect
- Usage line item:
usage_in_period × unit_cost_cents
. - Usage credits line item: negative amount equal to
credits_applied × unit_cost_cents
(when billingVisible). - Net charge: overage only when usage exceeds credits.
6) Test the flow
- Subscribe via Pricing Table.
- Trigger some usage with
sendEvent
. - Run a billing cycle (or wait for scheduled billing). Use Stripe test cards.
- Inspect the invoice: you’ll see usage charge and, if enabled, a credit line item.
Reference links
- Credits API:
/v1/credits/definitions
,/v1/credits/grants
- Events:
@getlumen/server
sendEvent()
(server-only) - Entitlements:
@getlumen/server
isFeatureEntitled()
and Entitlements API