Usage-based billing recipes/Prepaid credits dashboard

Build a real-time prepaid credits dashboard with Chargebee

Credits are the currency in your product—they determine what customers can do. Customers need real-time visibility into their balance, spending, and what’s left. This is a RevOps moment: show transparency, and customers will spend more confidently. Chargebee's Ledger APIs give you the data; your dashboard makes it compelling to customers.

Billing pattern
Prepaid credits
Complexity
Medium–High
APIs used
3
Reference
Artlist
Frameshift StudioAI Creator · 80,000 credits / month
Live
Available credits
22,800
Consumed: 51,200
Held: 6,000
Available: 22,800
Consumed
51,200
Held / In-flight
6,000
3 Kling jobs active
Resets in
8 days
Jul 1, 2025
Recent transactions
Ledger
Kling 3.0 / 4K videoCapture · 2 min ago
−2,400
Kling 3.0 / short clipCapture · 18 min ago
−820
ElevenLabs voiceoverCapture · 1h ago
−110
In-flight holds
Authorized
Kling 3.0 / 4K (job A)Authorized · 1 min ago
−2,000
Kling 3.0 / 4K (job B)Authorized · 3 min ago
−2,000
Veo 3.1 / sceneAuthorized · 5 min ago
−2,000
Credit grants
🎁 Promo active
AI Creator plan, June 2025Expires Jul 1 · 80,000 total
22,800 left
Welcome bonusExpires Jun 30 · 5,000 total
4,120 left

Credits determine what customers can and can’t do in your product. Give them real-visibility on it.

Credits are runtime monetization: every job is both a product action and a consumption event. The balance a customer sees isn’t static. It’s a live state that changes as jobs start and finish. When that state is unclear, customers over-spend, under-use, or get surprised.

This recipe provides visibility into consumption, reserved credits, credit sources, and expiration dates, so customers always know where they stand.

What this dashboard needs to answer
  • “How many credits do I actually have available right now?”
  • “Where did my credits come from and when do they expire?”
  • “What consumed my credits? Which model, which job?”
  • “Are any credits currently held for jobs still in progress?”
  • “Do I have any bonus or promotional credits?”
Working reference throughout this recipe: Company: Artlist · Example customer: Frameshift Studio (illustrative) · Plan: AI Creator · 80,000 credits/month, 51,200 consumed, 6,000 held (3 jobs in progress), 22,800 available. Welcome bonus: 4,120 of 5,000 remaining. All figures are fictional.
The recipe

Three APIs. Each answers one customer question.

Used together, they take a customer from “how many credits do I have?” to a complete account view: current balance, where those credits came from, and the full history of what was spent.

1
List Ledger Account BalancesBalance snapshot
GET /ledger_account_balances ↗

The real-time credit balance for this subscription: provisioned balance (what they paid for), overdraft balance (the safety buffer), usable balance, and hold amount (credits currently reserved for in-flight jobs). The foundation for every number on the dashboard.

2
List Grant BlocksCredit allocation
GET /grant_blocks ↗

Every credit grant tied to this subscription: its original allocation, remaining balance, active window, and expiry. Answers where credits came from, and surfaces any that are about to expire before the customer finds out on their own.

3
List Ledger OperationsTransaction history
GET /ledger_operations ↗

The full double-entry ledger: every capture, authorization, release, and grant event for this subscription, with timestamps, amounts, and your own metadata. This is the star of the credits dashboard. A usage bar tells customers how much they’ve spent. The ledger tells them exactly what spent it.

01 Balance snapshot

How many credits does my customer actually have right now?

Provisioned balance is what they paid for. Hold amount is what’s reserved for jobs in progress. Usable balance is what they can actually spend right now. One API call returns all three, always in sync.

What your customer sees
app.artlist.io/credits
DashboardProjectsCredits & billingSettings
Credits & billing
AI Creator plan · Jun 1 – Jul 1, 2025
AI credits balance
unit_id: ai_credits
Healthy
22,800 available
Consumed: 51,200
Held: 6,000
Available: 22,800
Held
6,000
3 jobs in progress
Available
22,800
Ready to spend
Why available ≠ provisioned − consumed
Always compute available as usable_balance directly from the API. Never derive it by subtraction. Held credits are already excluded. Deriving it yourself creates a race condition when multiple jobs run in parallel.
API call
GET /api/v2/ledger_account_balances
// Query params
?subscription_id[is]="sub_FrameshiftStudio"
&unit_id[is]="ai_credits"

// Response
{
  "ledger_account_balance": {
    "subscription_id": "sub_FrameshiftStudio",
    "unit_id":          "ai_credits",
    "unit_type":        "credit_unit",
    "modified_at":      1751020800,
    "provisioned_balance": {
      "usable_balance":  "22800", // spendable now
      "hold_amount":     "6000",  // in-flight holds
      "consumed_balance": "51200"  // permanently used
    },
    "overdraft_balance": {
      "usable_balance":  "0",
      "hold_amount":     "0",
      "consumed_balance": "0"
    }
  }
}
Fields used in dashboard
provisioned_balance.usable_balanceprovisioned_balance.hold_amountprovisioned_balance.consumed_balance→ segment bar + 2 KPI cards
02 Grant blocks

Where did the credits come from? And when do they expire?

Every credit in a customer’s balance traces back to a grant block: a specific allocation with its own active window and expiry. Listing grant blocks turns a raw number into a sourced, time-aware account view. Promotional grants appear here too, as a distinct type alongside the plan allocation.

Credit grants breakdown
app.artlist.io/credits
Active credit grants
AI Creator plan, June 2025
grant_block_id: gb_JunePlan2025 · unit_id: ai_credits
22,800
of 80,000 · expires Jul 1
🎁 Welcome bonus
promotional_grant_id: pg_WelcomeBonus · one-time
★ Promotional
4,120
of 5,000 · expires Jun 30
⚠️ Referral reward (expiring soon)
promotional_grant_id: pg_Referral_May · one-time
880
of 2,000 · expires in 2 days
API calls
GET /api/v2/grant_blocks
// Query params
?subscription_id[is]="sub_FrameshiftStudio"
&unit_id[is]="ai_credits"

// Response: one object per grant
{
  "grant_block": {
    "id":              "gb_JunePlan2025",
    "subscription_id": "sub_FrameshiftStudio",
    "unit_id":         "ai_credits",
    "granted_amount":  "80000",
    "usable_balance":  "22800",
    "effective_from":     1748736000, // Jun 1
    "expires_at":       1751328000, // Jul 1
    "source":          "item_price"
  }
}
Fields used in dashboard
granted_amountusable_balanceeffective_from / expires_atsource: promotional_grant→ grant list + expiry warning
Want to surface promotional credits separately from plan credits?
Promotional grants created via POST /promotional_grants appear alongside plan grants in the grant blocks list, with source: "promotional_grant". Filter on this field to badge them differently on the dashboard.
03 Ledger feed

What spent the credits? The ledger is the honest answer.

A balance tells customers how much is left. The ledger tells them exactly where it went. Every capture is a job that completed. Every authorization is a job still running. Every release is a job that failed and returned credits to the pool. And because ledger operations are immutable once recorded, the ledger is also a tamper-proof audit trail: every state change permanently on the record, traceable back to its source.

Transaction ledger
Credit transactions
ai_credits · Jun 2025
Live
TypeDescriptionAmountBalance after
Authorized
Kling 3.0 / 4K video (job A)
op_sA9x · 2 min ago
−2,000 held22,800
Captured
Kling 3.0 / 4K video
op_sB3k · 2 min ago
−2,40024,800
Captured
Kling 3.0 / short clip
op_kL7m · 18 min ago
−82027,200
Released
Veo 3.1 / failed render
op_vE1p · 34 min ago
+2,000 returned28,020
Captured
ElevenLabs / voiceover
op_eV2q · 1h ago
−11026,020
Allocation
AI Creator plan, Jun renewal
gb_JunePlan2025 · Jun 1
+80,00080,000
How do you make each ledger entry meaningful to your customer?
The metadata field is an opaque JSON object stored verbatim. Pass model, resolution, job_id on every capture, and your ledger feed becomes a readable production log, not just a list of numbers.
API call
GET /api/v2/ledger_operations
// Query params
?subscription_id[is]="sub_FrameshiftStudio"
&unit_id[is]="ai_credits"
&limit=25

// Response: one object per event
{
  "ledger_operation": {
    "id":              "op_sB3k",
    "type":            "capture",
    "subscription_id": "sub_FrameshiftStudio",
    "unit_id":         "ai_credits",
    "amount":                    "2400",
    "provisioned_start_balance": "27200",
    "provisioned_end_balance":   "24800", // 'balance after' column
    "ledger_operation_timestamp": 1751018400,
    "metadata": {
      "model":      "kling-3.0",
      "resolution": "4k",
      "job_id":     "job_7fabc91"
    }
  }
}
Fields used in dashboard
typeamountprovisioned_end_balanceledger_operation_timestampmetadata.modelmetadata.job_id→ ledger table rows
Start building

Visibility that drives customers to spend more.

Prepaid credits only work when customers trust their balance and understand what they have left. Chargebee's Ledger APIs track every grant, spending, expiration, and reserve in real time so your dashboard shows the complete picture. Customers see clarity. They spend confidently. You capture more revenue per account.