Credits

This guide shows how to model allowances and invoice discounts with Credits. You’ll create definitions, grant them to customers, understand renewals, and see how credits affect billing and entitlements.

What credits do:

  • Usage credits: Offset metered usage (e.g., API calls) against an allowance.
  • Monetary credits: Reduce invoice amounts as discounts (currency required).

Notes:

  • Monetary “prepaid top-ups” purchased by end users are not supported yet; use manual monetary grants as service/account credits.
  • To display credits on invoices, set billingVisible: true on the definition.

1) Create credit definitions

Usage (plan-scoped, tied to a price 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 credits",
    "billingVisible": true,
    "defaultAmount": 10000,
    "refillAmount": 10000,
    "renewOnBilling": true
  }'

Usage (feature-linked, for free plans without a price):

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_free",
    "featureSlug": "api-calls",
    "name": "Free plan API allowance",
    "defaultAmount": 1000,
    "renewOnBilling": true
  }'

Monetary (merchant-scoped account credits):

curl -X POST "https://api.getlumen.dev/v1/credits/definitions" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "merchant",
    "applicationType": "monetary",
    "name": "Account Credit",
    "currency": "USD",
    "billingVisible": true,
    "billingDescription": "Account Credit",
    "defaultAmount": 5000
  }'

Validation highlights:

  • Usage credits require either price/component linkage or a feature link.
  • Monetary credits require currency and must be billingVisible: true.
  • RRULEs are supported for renewals (no TZID); or set renewOnBilling: true.

2) Grant credits to customers

Manual grant:

curl -X POST "https://api.getlumen.dev/v1/credits/grants" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cust_123",
    "creditDefinitionId": "cd_api_credits",
    "initialAmount": 2000,
    "source": "manual",
    "notes": "Welcome boost"
  }'

Seat-based plans:

  • When you add a seat via /v1/seats/add, Lumen auto-grants any matching plan-scoped usage credit definitions to the seat customer.

3) Renewals and expirations

  • If renewOnBilling: true, credits refresh on the plan’s billing cycle.
  • If refillRrule is set, background jobs process renewals on schedule.
  • Expirations are processed by background jobs as grants pass their expiryDate.

Manual job triggers (for testing):

curl -X POST "https://api.getlumen.dev/v1/trigger/credits/process-grant-renewals" \
  -H "Authorization: Bearer $TRIGGER_API_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "timestamp": "2024-01-01T00:00:00Z" }'

curl -X POST "https://api.getlumen.dev/v1/trigger/credits/process-expirations" \
  -H "Authorization: Bearer $TRIGGER_API_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "timestamp": "2024-01-01T00:00:00Z" }'

4) How billing applies credits

Order of operations:

  • Usage credits (billing-visible) are converted to monetary line items (negative) at the component’s unit price.
  • Then monetary credits apply in a waterfall: component → price → plan → merchant.
  • Taxes are calculated on the remaining subtotal after credits.

5) Entitlements & metering

  • Entitlement checks consider credits plus plan features. For numeric features, the allowance can come from credits and usage is compared automatically.
  • Send usage events from your backend to meter usage:
import { sendEvent } from "@getlumen/server";

await sendEvent({
  name: "api-calls",
  value: 1,
  userId: "user_ext_456"
});