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

# Track usage

> Track metered usage for quota-based billing and feature limits.

Usage-based pricing lets you charge customers for what they actually use — API calls, storage, team members, or any metric. BillingOS tracks usage in real time and enforces limits automatically.

## When to track usage

Track usage when your product has metered or quota-based features:

* API calls per month
* Storage used (GB)
* Team members added
* Emails sent
* Files processed

## Client-side tracking

Use the `useTrackUsage` hook:

```tsx theme={null}
import { useTrackUsage } from "@billingos/sdk";

function UploadButton() {
  const { mutateAsync: trackUsage } = useTrackUsage();

  const handleUpload = async (file: File) => {
    await uploadFile(file);

    await trackUsage({
      featureKey: "storage_gb",
      quantity: file.size / (1024 * 1024 * 1024), // Convert to GB
    });
  };

  return <button onClick={() => fileInput.click()}>Upload</button>;
}
```

## Server-side tracking (recommended)

Server-side tracking is more reliable — it can't be bypassed and handles retries automatically.

```typescript theme={null}
import { BillingOS } from "@billingos/node";

const billing = new BillingOS({ secretKey: process.env.BILLINGOS_SECRET_KEY! });

// Track an API call
await billing.trackUsage({
  customerId: "user_123",
  featureKey: "api_calls",
  quantity: 1,
});

// Track with idempotency key (prevents duplicates on retries)
await billing.trackUsage({
  customerId: "user_123",
  featureKey: "api_calls",
  quantity: 1,
  idempotencyKey: `request-${requestId}`,
});
```

## Display usage to users

### UsageDisplay component

```tsx theme={null}
import { UsageDisplay } from "@billingos/sdk";

// Show all metered features
<UsageDisplay title="Your usage" />

// Show a specific feature
<UsageDisplay featureKey="api_calls" />
```

<img src="https://mintlify.s3.us-west-1.amazonaws.com/billingos/images/usage-display.png" alt="Usage display" />

### Custom usage UI with hooks

```tsx theme={null}
import { useUsageMetrics } from "@billingos/sdk";

function CustomUsageBar() {
  const { data } = useUsageMetrics("api_calls");
  const metric = data?.metrics?.[0];

  if (!metric) return null;

  const percentage = (metric.consumed / metric.limit) * 100;

  return (
    <div>
      <p>{metric.feature_title}: {metric.consumed} / {metric.limit}</p>
      <div className="bg-gray-200 rounded-full h-2">
        <div
          className="bg-green-500 rounded-full h-2"
          style={{ width: `${Math.min(percentage, 100)}%` }}
        />
      </div>
      <p className="text-sm text-gray-500">
        Resets in {metric.resets_in_days} days
      </p>
    </div>
  );
}
```

## Detect approaching limits

```tsx theme={null}
import { useIsApproachingLimit } from "@billingos/sdk";

const isNearLimit = useIsApproachingLimit("cus_123", "api_calls", 80);

if (isNearLimit) {
  // Show upgrade nudge or warning
}
```

The `UpgradeNudge` component can also handle this automatically — see [Upgrade nudges](/guides/upgrade-nudges).
