Usage-Based license
A Usage-Based license (MeteredCount, metering mode Count) is always online. Customers share one use counter across all devices on the license key. Every consume deducts quantity from the remaining uses — there is no per-feature token pricing (unlike Credit-Based).
Shared counter
One “uses” balance per license key.
Flat deduction
Each consume costs quantity (usually 1).
Usage tab
Balance, ledger, manual top-ups (owners).
When to choose Usage-Based
Choose Usage-Based when you sell a fixed number of actions and every billable operation should count the same — typically one use per call. The customer starts with a balance (for example 500 uses). Each time they run a metered feature, your app calls ConsumeAsync and the server subtracts 1 use (or more if you pass a higher quantity).
Think of it like a punch card: “This license includes 500 exports.” Export #1 uses one punch, export #2 uses one punch — it does not matter which export template they pick; each export costs the same.
Good fits
- Simple bundled SKUs — “500 PDF exports per year” or “1,000 API calls included.”
- Evaluation limits — “Try 50 full runs before buying a larger pack.”
- Flat per-event billing — every report generated, every sync job, every upload counts as one use.
- Operations that should not need a price table — you do not want to maintain different credit costs per feature.
How it behaves in LicenPro
- Dashboard label: Usage-Based. API enum:
MeteredCount. - Balance is shown in uses (shared across all devices on the license key).
- No per-feature pricing — the feature name is for entitlement and audit; cost is always
quantity. - Example: customer has 500 uses → one consume with
quantity: 1leaves 499 uses, regardless of feature name.
When to use Credit-Based instead
If different features should burn the wallet at different rates — a light API call costs 1 credit but a heavy AI job costs 50 — use Credit-Based (MeteredToken) and configure a token price per feature.
At a glance
| Property | Value |
|---|---|
| Backend enum | LicenseType.MeteredCount (value 7) |
| Dashboard label | Usage-Based |
| Metering mode | MeteringMode.Count |
| Balance unit | uses |
| Cost per consume | quantity (1 use per unit by default) |
| Feature pricing | Not used — feature name is for entitlement/audit only |
| Activation mode | Online only |
| Seat limit | None — wallet/counter is the limit, not device seats |
Key invariant
Balance is only checked and deducted in POST /api/meter/consume. Validation and activation succeed even at zero uses; your app must call consume when the metered action runs and handle InsufficientBalance (HTTP 402).
Create a Usage-Based license (dashboard)
Open Licenses → Generate License. Four steps: Activation → License Type → Basic Info → Details.
Step 1 — Activation
Select Online. Usage-Based is always-online; offline mode hides metered type cards.
Step 2 — License type
Select the Usage-Based card (“One use per action”). Description: shared use counter, manual top-ups from the dashboard.
Step 3 — Basic info
- Product and Software release (required).
- Issued to — end user for the release.
- License name — internal label.
- Optional Entitlement set — restricts which feature names may be consumed.
Step 4 — Details
- Initial uses balance (
initialMeterBalance) — required, must be > 0 (e.g. 500 uses). - Notes — operator context.
Backend creates MeterWallet { mode: Count } and an InitialGrant ledger entry.
Create Usage-Based license, initial 500 uses
└─ MeterWallet { mode: Count, balance: 500 }
└─ UsageLedger { type: InitialGrant, amount: +500, balanceAfter: 500 }No feature pricing step
Unlike Credit-Based, Usage-Based ignoresFeatureMeterPricing. ResolveCostAsync sets cost = quantity regardless of feature name. Configure entitlements if you need to restrict which features can be metered.
Activation & sessions
- Always-online — same activation/session requirements as other online types.
- No activation seat cap — unlimited devices may activate the same key.
- Use global Activations / Sessions pages for cross-license support views.
Runtime — SDK & API
var client = new LicenseClient(options);
var result = await client.ValidateAsync();
if (!result.IsValid) return;
// Each call deducts `quantity` uses (default 1)
var consume = await client.ConsumeAsync("ApiCall", quantity: 1);
if (!consume.Success && consume.IsInsufficientBalance)
ShowTopUpPrompt();
var balance = await client.GetBalanceAsync(); // remaining uses Read balance without deducting: GET /api/meter/balance?licenseKey=... (API key) or dashboard GET /api/meter/balance/{licenseId}.
Worked example
- Create license with initial 500 uses.
- Consume any entitled feature ×1 → balance 499.
- Consume ×600 in one call →
InsufficientBalance(402); balance unchanged at 499. - Consume ×499 → balance 0.
- Next consume ×1 →
InsufficientBalance(402). - Owner grants +1,000 → balance 1,000, ledger
AdminGrant.
Usage-Based, balance 100, consume quantity 3
└─ cost = 3 → balance 97
└─ UsageLedger { type: Consume, amount: -3, balanceAfter: 97 }Usage tab (license detail)
Open a Usage-Based license → Usage tab.
| Role | What you see |
|---|---|
| Product owner / Admin | Remaining uses, grant form, full ledger (consumes + grants) |
| End user (My Licenses) | Read-only balance; consumption history where exposed |
| Member / Viewer | Read-only; no grant actions |
The balance card shows “Use mode — each consume deducts one use regardless of feature.” Grants require amount > 0 and are recorded as AdminGrant with optional reason and external reference (invoice / PO).
Analytics
GET /api/statistics/meter-usage aggregates both metered types: meteredCountLicenseCount, total balance, period consumption, low-balance licenses, daily trend, and top licenses.
Consume error codes
| ErrorCode | HTTP | Meaning |
|---|---|---|
InvalidRequest | 400 | Missing required fields |
LicenseNotFound | 404 | Unknown license key |
NotMeteredLicense | 400 | Not Usage-Based or Credit-Based |
LicenseInvalid | 400 | Revoked / expired |
FeatureNotEntitled | 403 | Feature blocked by entitlement sets |
InsufficientBalance | 402 | Not enough remaining uses |
ConcurrencyConflict | 409 | Retry consume |
Usage-Based never returns PricingNotConfigured — that applies to Credit-Based only.
Usage-Based vs Credit-Based
Use this quick guide if you are deciding between the two metered types:
| Question | Usage-Based | Credit-Based |
|---|---|---|
| What are you selling? | A use counter (e.g. “500 exports”) | A credit wallet (e.g. “10,000 credits”) |
| Cost per action | Flat — 1 use per consume (unless you pass a higher quantity) | Variable — each feature has its own token cost |
| Setup before first consume | Create license with initial use count only | Set TokenCost per feature, then consume |
| Best analogy | Punch card — every action uses one punch | Prepaid wallet — different services cost different amounts |
