Troubleshooting & Patterns

What this is

Practical fixes and copy‑pasteable patterns for common pricing and entitlement issues. Short answers, clear choices, and links to deeper pages.

When to use this

  • You’re wiring usage and pricing and something feels off
  • You’re choosing between multiple ways to model a feature or price
  • You need quick guidance without re‑reading full guides

Choose the right metric aggregation

Pick the simplest option that answers “what do I bill on?”

  • Count events: Bill per action (e.g., API calls)
    • Emit api-call on success → metric: COUNT where event_name = 'api-call'
  • Sum a value: Bill by size (e.g., AI tokens, GB processed)
    • Emit ai-token with eventValue → metric: SUM of eventValue
  • Unique over a key: Bill on distinct users/projects
    • Emit events with userId/projectId → metric: COUNT DISTINCT using an indexed/complex metric
  • Derived/filtered: Bill on cohorts or “latest only” behaviors
    • Use a complex metric with filters (e.g., WHERE tier = 'pro') or windowing (latest per id)

See: Metrics


Avoid double‑counting and retries

Only emit after the action succeeds, and dedupe with idempotencyKey.

curl -X POST "https://api.getlumen.dev/v1/events" \
  -H "Authorization: Bearer $LUMEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "eventName": "api-call",
    "customerId": "cust_123",
    "eventValue": 1,
    "idempotencyKey": "txn_12345"
  }'

Tips:

  • Use a stable business id (job id, message id) for idempotencyKey
  • Emit once per action boundary (after success), not per attempt
  • For bulk jobs, consider batching into one event with eventValue

See: Events


Free allowance vs allowance + overage

Two clean ways to model “included usage”.

  • Hard limit (no overage)
    • Create a usage feature + credit definition with monthly refill
    • Do not add a usage price component
    • Result: Access stops when credits are used up
  • Allowance + overage
    • Same as above, plus a usage price component for the metric
    • Result: Included amount is free; extra usage bills automatically

Minimal usage component shape:

{
  "type": "usage",
  "label": "API calls overage",
  "unit_label": "call",
  "metric_id": "met_...",
  "unit_cost_cents": 1,
  "recurrence_rule": "RRULE:FREQ=MONTHLY;INTERVAL=1"
}

See: Plans & Pricing, Credits


Override vs new plan version

Use this decision guide to avoid migration pain.

  • Use an override when…
    • It’s a bespoke exception for one customer
    • You need a temporary tweak (e.g., extra seats for a month)
    • You’re honoring a legacy contract for a single account
  • Create a new plan version when…
    • Multiple customers should get the change
    • You want clean history and future reuse
    • Prices/feature sets fundamentally change

Migration tips:

  • Treat versions as append‑only; don’t edit past versions
  • For upgrades with price changes, schedule at next_billing_cycle
  • Provide price mappings when target version uses different price IDs

See: Overrides & Enterprise Deals


Event naming and versioning

Make names stable and machine‑friendly; version intentionally.

  • Use kebab‑case slugs (e.g., api-call, image-transcode)
  • Prefer nouns representing the action boundary; avoid ambiguous verbs
  • Include properties you’ll filter/aggregate on later (e.g., userId, projectId)
  • Version with suffixes when semantics change: api-call.v2
  • Avoid overloading one event for many behaviors; add a new event or property

See: Events


UI vs API

  • UI: Use Create/Update Plan to wire features, metrics, and credit definitions. It sets safe defaults and links allowances for you.
  • API: Reach for this when you need indexed/complex metrics, mixed cycles, custom RRULEs, or migration tooling.

Common pitfalls

  • Counting retries because events fire before success
  • Expecting unused credits to roll over with expiryDays set
  • Forgetting to link a usage metric to a usage price component (no overage)
  • Checking plan names in code instead of feature slugs
  • Using timezones in RRULEs; keep them UTC

See also