# Usage-based billing

> Meter what customers consume, price it with exact-integer math, manage prepaid credits on an immutable ledger, and gate features with entitlements: all visible in the dashboard.

Part of the Soca documentation (https://soca.finance/docs). Human version: https://soca.finance/docs/business/usage-billing
If your product is consumed rather than just subscribed to, through API calls, tokens, images, or seats, Soca can bill it by usage. You define meters for what you measure, send an event each time it happens, and the pricing engine, credit ledger, and entitlements do the rest. The dashboard shows every piece: usage, balances, and who has access to what.

## What is a meter?

A meter is a named, billable thing you measure, such as "tokens", "API calls", or "images rendered". It has a display name, a unit label, an event name (the key you send usage with), and an aggregation, how events roll into a period total: **sum** (add the values), **count** (number of events), **max** (peak), or **last** (most recent). **Dashboard → Usage** lists your meters with total usage and event counts, plus a live feed of recent events by customer, so you can watch consumption arrive.

## How do I create a meter?

Under **Dashboard → Usage → New meter**: give it an event key (e.g. `api_calls`), a display name, and an aggregation. That is all it takes before you can send usage to it. Programmatically it is one call, and it is idempotent by key, so it is safe to run on every deploy:

**Create a meter**

```bash
curl -X POST https://your-soca-host/v1/meters \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"key":"api_calls","display_name":"API calls","aggregation":"sum","unit_label":"calls"}'
# → { "object": "meter", "id": "meter_...", "key": "api_calls", ... }
```

The returned `id` is what a [usage-based plan](#can-usage-charge-the-customer-automatically) or a metered feature references. With the [SDK](/docs/developers/sdk) it is `soca.meters.create({ key, display_name })`.

## How do I record usage?

Your backend sends one small request per unit of consumption:

**Send a meter event**

```bash
curl -X POST https://your-soca-host/v1/meter-events \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"event_name":"tokens","customer_id":"cus_...","value":"5000","idempotency_key":"req_abc"}'
```

- **`event_name`** matches the meter, **`customer_id`** is your identifier for the customer, and **`value`** is the quantity consumed.
- **Always pass an `idempotency_key`.** If your request retries, the event counts once. Usage data has to be safe to resend.
- Events roll up in the dashboard within moments and drive pricing, credits, and entitlements together.

## How is usage priced?

With exact integer arithmetic, end to end. Amounts are USDC base units (6 decimals) and quantities are integers, so there is no floating-point rounding anywhere in the pipeline. Even a billion events are priced to the exact unit, and totals always reconcile to the ledger. The Usage page includes a **pricing simulator** that runs your model through the same engine that bills real usage, so you can try tiers and rates against sample volumes before anything is charged. Nothing in the simulator is saved.

## How do prepaid credits work?

Credits are balances customers pay for up front and draw down as they consume. **Dashboard → Credits** shows outstanding balances, lifetime granted and consumed, and lets you grant credits to a customer directly; programmatically, grants and debits are `POST /v1/credit_grants` and `POST /v1/credit_debits`.

> **The ledger is immutable**: Every balance is the exact sum of an append-only ledger of grants, debits, refunds, adjustments, and expirations. Corrections are new entries, never edits. Any balance can be audited line by line, and history can never quietly change.

There are three ways a balance goes up. **Grant credits** adds them directly (a comped balance, or credit you sold elsewhere). **Sell credits** raises a payment link for a customer to buy them; the balance is topped up automatically the moment it settles. **Auto-reload** watches the balance and, when it falls below your threshold, raises that top-up invoice for you and notifies the customer, so a heavy user never runs dry mid-month. All three are on **Dashboard → Credits**.

The Balances table flags customers running low and shows each account's auto-reload rule. The full ledger view shows each entry with its type, reason, signed amount, and the balance after it.

> **Reloads are invoices, never silent pulls**: Auto-reload asks; it never charges on its own. The customer approves the top-up by paying the invoice, and the credits land in the same transaction that marks it paid. If you want collection with no customer action, that is a usage-based plan (below), where they pre-approve a per-period cap.

## What are entitlements?

Entitlements are the yes/no layer: what is each customer currently allowed to use, given what they have paid for or hold? A **feature** is anything a plan unlocks, such as a model, an export, or an API. It is either boolean (has it or not) or metered (has it, up to an allowance enforced against a meter). Create one under **Dashboard → Entitlements → New feature**, or `POST /v1/features` (`soca.features.create` in the SDK); then grant it to customers with `POST /v1/entitlement_grants`. Your backend asks one question:

**Check access before serving a request**

```bash
curl https://your-soca-host/v1/customers/cus_.../entitlements/pro_models \
  -H "Authorization: Bearer sk_live_..."
```

The response is a definitive yes/no plus the remaining allowance for metered features: one call to gate a request. **Dashboard → Entitlements** lists your features and recent grants with their status (active, in grace, expired, or revoked), and includes a checker that returns exactly the same answer as the API, which makes "why can't this customer access X?" a ten-second question.

## Can usage charge the customer automatically?

Yes. Create a **usage-based plan**: pick the meter, set a price per unit (and any included units), and set a **per-period cap**, the most that can ever be charged in one period. The customer subscribes once, approving that cap. From then on, at the end of each period Soca prices the usage they racked up and pulls exactly that amount from their wallet, with no signature and no invoice, and never more than the cap they agreed to.

- **No charge at signup.** There is no usage yet, so subscribing takes nothing; the first charge is at the end of the first period, based on what they used.
- **Capped by consent.** The per-period cap is enforced on-chain: a period can never pull more than it, so a runaway meter can never overcharge. Usage above the cap is billed at the cap and flagged for you (raise the cap for the next period if you need to).
- **Zero-usage periods cost nothing.** If a customer used nothing, the period advances with no charge.
- Create one under **Dashboard → New plan → Usage-based**, or `POST /v1/plans` with `usage_type: "metered"`, a `meter`, and a `pricing_model`.

> **Two ways to collect usage**: Prepaid credits (customers buy a balance and draw it down) and usage-based plans (usage is auto-charged each period up to a cap) are independent. Use credits when customers pay in advance; use a usage-based plan when you want to bill consumption after the fact, automatically.

## How do the pieces fit together?

Two flows, one engine. Prepaid: grant a customer credits → your product sends meter events as they consume → debits draw the balance down → the entitlement check gates each request against what remains. Auto-charge: a customer subscribes to a usage-based [plan](/docs/business/subscriptions) → your product sends meter events → at each period end the usage is priced and pulled from their wallet, up to the cap. Meters live in **Usage**, balances in **Credits**, and access in **Entitlements**: views over one consistent engine. Endpoint details are in the [API reference](/docs/developers/api-reference).
