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

# Bill Your Customers

> Set up usage-based billing with meters, plans, and checkout from code

This guide shows how to create a complete billing flow programmatically: define pricing, create a plan, embed checkout, and route billable traffic per customer.

<Info>
  **Prerequisites:** Start with [Authenticate an Agent](/agents/authenticate), then follow [Route Traffic](/agents/route-traffic) for the gateway path you chose.
</Info>

## MCP flow

The Lava MCP server handles gateway traffic routing. Billing setup (meters, plans, checkout) requires the SDK.

A typical billing workflow:

1. **SDK**: Create a meter, plan, and checkout session (Steps 1–3 below)
2. **MCP**: `login` to authenticate the gateway session
3. **MCP**: `prompt` or `call` to route billable traffic through the gateway

## SDK flow

### Overview

The billing flow has four parts:

1. **Meter** - Defines how usage is priced (e.g., \$3 per million tokens)
2. **Plan** - A subscription that includes an optional monthly fee, credit allowance, and linked meters
3. **Checkout** - An embedded flow where your customer subscribes and pays
4. **Forward tokens** - Per-customer auth tokens that route traffic through the gateway with billing

## Step 1: Create a Meter

A meter defines the pricing rules for a type of usage. For example, charging per token for AI model calls:

```typescript theme={null}
import { Lava } from '@lavapayments/nodejs';

const lava = new Lava(); // reads LAVA_SECRET_KEY from env

const meter = await lava.meters.create({
  name: 'AI Chat Tokens',
  rate_type: 'fixed',
  tier_type: 'tokens_1m',
  tiers: [
    { start: '0', rate: '3.00' }  // $3.00 per million tokens
  ]
});

console.log('Meter ID:', meter.meter_id);
console.log('Meter slug:', meter.meter_slug);
```

### Meter options

| Parameter   | Options                                             | Description                                             |
| ----------- | --------------------------------------------------- | ------------------------------------------------------- |
| `rate_type` | `fixed`, `percentage`                               | Fixed price per unit, or percentage markup on base cost |
| `tier_type` | `tokens_1m`, `characters_1m`, `minutes`, `requests` | What unit is being measured                             |

You can also add volume-based tiers for graduated pricing:

```typescript theme={null}
const meter = await lava.meters.create({
  name: 'API Requests',
  rate_type: 'fixed',
  tier_type: 'requests',
  tiers: [
    { start: '0', rate: '0.01' },       // $0.01/request for first 10k
    { start: '10000', rate: '0.005' }    // $0.005/request after 10k
  ]
});
```

## Step 2: Create a Plan

A plan ties together an optional recurring price, included credits, and one or more meters (product features included in your plan):

```typescript theme={null}
const plan = await lava.subscriptions.createPlan({
  name: 'Pro Plan',
  period_amount: '49.00',
  billing_interval: 'month',
  included_credit: '25.00',
  meter_ids: [meter.meter_id]  // Link meters to this plan
});

console.log('Plan ID:', plan.plan_id);
```

<Note>
  The `meter_ids` field links meters to the plan. You can link multiple meters to a single plan.
</Note>

### Plan options

| Parameter          | Options                        | Description                                         |
| ------------------ | ------------------------------ | --------------------------------------------------- |
| `billing_interval` | `day`, `week`, `month`, `year` | How often the subscription renews                   |
| `rollover_type`    | `full`, `none`                 | Whether unused included credit carries over         |
| `included_credit`  | Any decimal string             | Credit included with each billing cycle             |
| `credit_bundles`   | Array of bundles               | Optional add-on credit packs customers can purchase |

Example with credit bundles:

```typescript theme={null}
const plan = await lava.subscriptions.createPlan({
  name: 'Pro Plan',
  period_amount: '99.00',
  billing_interval: 'month',
  included_credit: '50.00',
  rollover_type: 'full',
  meter_ids: [meterA.meter_id, meterB.meter_id],
  credit_bundles: [
    { name: '$25 Top-up', cost: '25.00', credit_amount: '25.00' },
    { name: '$100 Top-up', cost: '100.00', credit_amount: '100.00' }
  ]
});
```

## Step 3: Embed Checkout

Checkout is a two-step flow: your **backend** creates a session, your **frontend** opens it with the `@lavapayments/checkout` SDK.

```bash theme={null}
npm install @lavapayments/checkout
```

### Backend: Create a session

```typescript theme={null}
const session = await lava.checkoutSessions.create({
  checkout_mode: 'subscription',
  origin_url: 'https://yourapp.com',
  plan_id: plan.plan_id
});

// Return session.checkout_session_token to your frontend
```

### Frontend: Open checkout

```typescript theme={null}
import { useLavaCheckout } from '@lavapayments/checkout';

const { open } = useLavaCheckout({
  onSuccess: ({ customerId }) => {
    // Save customerId — this is the billing relationship with your customer
  }
});

// Call with the token from your backend
open(checkoutSessionToken);
```

The checkout overlay handles phone verification, payment method collection, and subscription creation. When complete, `onSuccess` fires with the `customerId`.

<Warning>
  Checkout sessions expire after 60 minutes. Create a new session for each checkout attempt.
</Warning>

<Note>
  The `checkout_session_token` is an opaque token — do not try to construct URLs from it. Always use the SDK to open checkout.
</Note>

## Step 4: Route Billable Traffic

Once a customer has completed checkout, generate forward tokens scoped to their customer ID and meter. Every request made with this token is tracked and billed against their subscription:

```typescript theme={null}
// Get the customer (from your database, or list them)
const { data: customers } = await lava.customers.list();
const customer = customers[0];

// Generate a forward token for this customer
const forwardToken = lava.generateForwardToken({
  customer_id: customer.customer_id,
  meter_slug: meter.meter_slug,
});

// Use it exactly like in the Route Traffic guide
const response = await fetch(lava.providers.openai + '/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${forwardToken}`
  },
  body: JSON.stringify({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello!' }]
  })
});
```

## Step 5: Monitor Customer Usage

Track usage and costs per customer:

```typescript theme={null}
// Get usage for a specific customer
const usage = await lava.usage.retrieve({
  start: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
  customer_id: customer.customer_id,
});

console.log('Customer requests:', usage.totals.total_requests);
console.log('Customer cost:', usage.totals.total_cost);

// Check their subscription status
const sub = await lava.customers.getSubscription(customer.customer_id);
if (sub.subscription) {
  console.log('Plan:', sub.subscription.plan.name);
  console.log('Credits remaining:', sub.subscription.credits.total_remaining);
}
```

## What's Next?

<CardGroup cols={2}>
  <Card title="Meters" icon="gauge" href="/monetize/meters">
    Advanced meter configuration and pricing strategies
  </Card>

  <Card title="Checkout Guide" icon="credit-card" href="/monetize/checkout">
    Checkout modes, completion handling, and webhooks
  </Card>

  <Card title="Webhooks" icon="webhook" href="/integration/webhooks">
    Get notified when customers subscribe, run low on balance, or cancel
  </Card>

  <Card title="SDK Reference" icon="code" href="/sdk/nodejs">
    Full API for customers, subscriptions, and usage
  </Card>
</CardGroup>
