> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Credit-Based Billing

> The payload sent to your webhook endpoint when credit-based billing events occur — virtual credits (API calls, tokens, compute hours) granted, consumed, expired, rolled over, or balance alerts. These webhooks are not related to Customer Wallets (monetary balances).

## Credit-Based Billing Webhook Events

The following webhook events are available for tracking credit-based billing lifecycle changes. These events apply to virtual credit entitlements (API calls, tokens, compute hours), not to [Customer Wallets](/features/customer-wallet) (monetary balances).

| Event                       | Description                                                                              |
| --------------------------- | ---------------------------------------------------------------------------------------- |
| `credit.added`              | Credits are granted to a customer (via subscription, one-time purchase, add-on, or API)  |
| `credit.deducted`           | Credits are consumed through usage or manual debit                                       |
| `credit.expired`            | Unused credits expired after the configured expiry period                                |
| `credit.rolled_over`        | Unused credits are carried forward to a new grant at cycle end                           |
| `credit.rollover_forfeited` | Credits forfeited because the max rollover count was reached                             |
| `credit.overage_charged`    | Overage charges applied when usage continues beyond zero balance                         |
| `credit.overage_reset`      | Accumulated overage charges are reset (for example, at the start of a new billing cycle) |
| `credit.manual_adjustment`  | Manual credit or debit adjustment made via dashboard or API                              |
| `credit.balance_low`        | Credit balance drops below the configured low balance threshold                          |

### Ledger Events

All ledger events (`credit.added` through `credit.manual_adjustment`) share the same `CreditLedgerEntryResponse` payload documented in the schema below.

### Balance Low Event (credit.balance\_low)

The `credit.balance_low` event uses a different payload (`CreditBalanceLowPayload`) focused on threshold alerting:

```json theme={null}
{
  "business_id": "bus_H4ekzPSlcg",
  "type": "credit.balance_low",
  "timestamp": "2025-08-04T06:15:00.000000Z",
  "data": {
    "payload_type": "CreditBalanceLow",
    "customer_id": "cus_8VbC6JDZzPEqfBPUdpj0K",
    "subscription_id": "sub_7EeHq2ewQuadropD2ra",
    "credit_entitlement_id": "cent_9xY2bKwQn5MjRpL8d",
    "credit_entitlement_name": "API Credits",
    "available_balance": "15",
    "subscription_credits_amount": "100",
    "threshold_percent": 20,
    "threshold_amount": "20"
  }
}
```

<ParamField body="customer_id" type="string">
  The customer whose credit balance triggered the alert.
</ParamField>

<ParamField body="subscription_id" type="string">
  The subscription associated with this credit entitlement.
</ParamField>

<ParamField body="credit_entitlement_id" type="string">
  The credit entitlement that has a low balance.
</ParamField>

<ParamField body="credit_entitlement_name" type="string">
  Display name of the credit entitlement.
</ParamField>

<ParamField body="available_balance" type="string">
  Current credit balance at the time of the alert.
</ParamField>

<ParamField body="subscription_credits_amount" type="string">
  Total credits issued per billing cycle for this subscription.
</ParamField>

<ParamField body="threshold_percent" type="integer">
  The configured low balance threshold percentage.
</ParamField>

<ParamField body="threshold_amount" type="string">
  The absolute credit amount that the threshold corresponds to.
</ParamField>

### Using `credit.balance_low` for Proactive Alerts

Use the `credit.balance_low` webhook to notify customers before they run out of credits:

```javascript theme={null}
app.post('/webhooks/dodo', async (req, res) => {
  const event = req.body;
  
  if (event.type === 'credit.balance_low') {
    const data = event.data;
    
    // Notify the customer their credits are running low
    await sendEmail(data.customer_id, {
      subject: `Your ${data.credit_entitlement_name} balance is running low`,
      body: `You have ${data.available_balance} credits remaining ` +
            `(${data.threshold_percent}% threshold reached). ` +
            `Consider upgrading your plan or purchasing additional credits.`
    });
    
    console.log(`Low balance alert for customer ${data.customer_id}`);
  }
  
  res.json({ received: true });
});
```

<Tip>
  Subscribe to `credit.balance_low` to proactively alert customers before they exhaust their credits. Combine with `credit.deducted` to track real-time consumption patterns.
</Tip>

<CardGroup cols={2}>
  <Card title="Get Customer Balance" icon="wallet" href="/api-reference/credit-entitlements/get-customer-balance">
    Check a customer's current balance via API.
  </Card>

  <Card title="Create Ledger Entry" icon="plus" href="/api-reference/credit-entitlements/create-ledger-entry">
    Manually credit or debit a customer's balance.
  </Card>
</CardGroup>

## Webhook Payload Schema
