LicenPro
DocumentationCredit Based License

Credit-Based license

A Credit-Based license (MeteredToken, metering mode Token) is always online. Customers share one credit wallet across all devices on the license key. Each entitled feature deducts credits according to per-feature token pricing on the product — not a flat “one use per call” like Usage-Based.

Shared wallet

One balance per license key — not per device.

Variable cost

Each feature has a TokenCost × quantity.

Usage tab

Balance, ledger, manual top-ups (owners).

When to choose Credit-Based

Choose Credit-Based when you sell a pre-paid pool of credits and different features in your product should cost different amounts. The customer starts with a balance (for example 10,000 credits). Each time they run a billable action, your app calls ConsumeAsync and the server deducts credits based on that feature’s configured price.

Think of it like a prepaid phone plan with variable call rates: one minute to country A costs 2 credits, one minute to country B costs 5 credits — same wallet, different prices per action.

Good fits

  • API or SaaS with tiered actions — “10,000 API credits per month”; a simple read costs 1 credit, a heavy export costs 25.
  • Document / OCR / AI products — “5,000 pages included”; OCR costs 10 credits per page, summary costs 40.
  • Creative or compute tools — “1,000 render credits”; preview is cheap, 4K export is expensive.
  • Top-up sales — customer buys another 5,000 credits when the wallet is low (manual grant from the Usage tab today).

How it behaves in LicenPro

  • Dashboard label: Credit-Based. API enum: MeteredToken.
  • Balance is shown in credits (shared across all devices on the license key).
  • You must set a token cost per feature before consume works (via metering API; UI coming later).
  • Example: feature ExportPdf priced at 25 → one consume deducts 25 credits, not 1.

When to use Usage-Based instead

If every billable action should cost exactly one use — “500 exports included”, “1,000 API calls” — and you do not need different prices per feature, use Usage-Based (MeteredCount). It is simpler: no feature pricing step.

At a glance

PropertyValue
Backend enumLicenseType.MeteredToken (value 6)
Dashboard labelCredit-Based
Metering modeMeteringMode.Token
Balance unitcredits
Cost per consumeFeatureMeterPricing.TokenCost × quantity
Activation modeOnline only — offline is not available
Seat limitNone — any number of devices may activate; the wallet is the limit

Key invariant

Balance is only checked and deducted in POST /api/meter/consume. License validation, activation, and session connect never look at the balance. A Credit-Based license can activate at zero credits; your app must call ConsumeAsync when a billable feature runs and handle InsufficientBalance (HTTP 402).

Create a Credit-Based license (dashboard)

Open LicensesGenerate License. Four steps: ActivationLicense TypeBasic InfoDetails.

Step 1 — Activation

Select Online. Credit-Based is an always-online type — the wizard forces online mode and hides metered cards if Offline is selected.

Step 2 — License type

Select the Credit-Based card (“Variable cost per feature”). Subtitle explains the shared credit pool and manual top-ups.

License Type — Credit-Based (MeteredToken).

Step 3 — Basic info

  • Product and Software release (required).
  • Issued to — end user assigned to the release (required for non-perpetual types).
  • License name — internal label in lists and audit.
  • Optional Entitlement set — when set, only entitled features can be consumed.

Step 4 — Details

  • Initial credits balance (initialMeterBalance) — required, must be > 0 (default in the form is often 10,000).
  • Notes — operator context (invoice, SKU, support ticket).

On save, the backend creates a MeterWallet with mode Token and writes an InitialGrant ledger row when balance > 0.

Create Credit-Based license, initial 10,000
└─ MeterWallet { mode: Token, balance: 10000 }
   └─ UsageLedger { type: InitialGrant, amount: +10000, balanceAfter: 10000 }

Configure per-feature pricing (Credit-Based only)

Before clients consume a feature, set its token cost on the product. API: PUT /api/meter/features/{featureId}/pricing (product owner / admin).

  • TokenCost must be > 0.
  • Previous active pricing rows are deactivated; history is preserved.
  • Consuming a feature with no active pricing returns PricingNotConfigured (HTTP 422).

Note: A dedicated pricing UI in the dashboard is planned; today pricing is set via API.

Activation & sessions

  • Always-online — activation and sessions are required like Floating.
  • No activation seat capEnforceSeatLimitOnActivation is false for metered types; many devices may share one key.
  • Activations and sessions appear in the dashboard for support visibility (optional attribution on consume via hardwareId / activationId).

See Activations and Sessions platform guides.

Runtime — SDK & API

Typical client flow:

var client = new LicenseClient(options);

// 1. Validate (always online — does NOT check credit balance)
var result = await client.ValidateAsync();
if (!result.IsValid) return;

// 2. Before running a billable feature — deduct credits
var consume = await client.ConsumeAsync("ExportPdf", quantity: 1);
if (!consume.Success && consume.IsInsufficientBalance)
    ShowTopUpPrompt();

// 3. Optional — show remaining credits
var balance = await client.GetBalanceAsync();

ConsumeAsync calls POST /api/meter/consume with product X-API-KEY. Pass an idempotency key to make retries safe — replays return the prior result without double-charging.

Consume request

FieldRequiredNotes
licenseKeyYesCustomer license key
featureNameYesMust be entitled; must have active pricing
idempotencyKeyYesReuse on retry of the same logical operation
quantityNo (default 1)Cost = TokenCost × quantity
hardwareIdNoAuto-detected by SDK when omitted
activationIdNoAttribute usage to a device row

Worked example

  1. Create license with initial 10,000 credits.
  2. Price feature "render" at TokenCost 40.
  3. SDK consumes render ×1 → cost 40 → balance 9,960.
  4. Retry with same idempotencyKey → replay, balance still 9,960.
  5. Consume unpriced feature → PricingNotConfigured (422).
  6. Owner grants +5,000 → balance 14,960, ledger AdminGrant.

Usage tab (license detail)

Open a Credit-Based license → Usage tab.

RoleWhat you see
Product owner / AdminRemaining balance, Grant balance form (amount, reason, external reference), full usage ledger
Assigned end user (My Licenses → detail)Read-only balance card; ledger without grant actions
Member / ViewerNo grant UI; read-only where permitted

Ledger entry types: InitialGrant, Consume (negative amount), AdminGrant, Adjust.

Top-ups are manual only — there is no payment gateway integration in the current release.

Analytics

Organization analytics includes a metered usage section from GET /api/statistics/meter-usage: metered license counts, total balance remaining, consumed/granted in the period, low-balance alerts, daily consumption trend, top features, and top licenses.

Consume error codes

ErrorCodeHTTPMeaning
InvalidRequest400Missing key, feature, or idempotency key
LicenseNotFound404No license for the key
NotMeteredLicense400Wrong license type
LicenseInvalid400Status is not Valid
FeatureNotEntitled403Feature not in entitlement sets (when sets are configured)
WalletNotFound400Wallet missing
PricingNotConfigured422No active TokenCost for this feature
InsufficientBalance402balance < cost
ConcurrencyConflict409Retry the consume call

Credit-Based vs Usage-Based

Use this quick guide if you are deciding between the two metered types:

QuestionCredit-BasedUsage-Based
What are you selling?A credit wallet (e.g. “10,000 credits”)A number of actions (e.g. “500 exports”)
Cost per actionVaries by feature — you set each feature’s token priceAlways the same — usually 1 use per consume
Setup before first consumeConfigure TokenCost per featureNothing extra — just create the license with an initial use count
Best analogyPrepaid credits with different prices per service“Includes 500 uses” — each button click counts as one

See also