Files
cfw-autumn/apps/docs/mintlify/documentation/modelling-pricing/usage-based-pricing.mdx
mintlify[bot] 9bd20cb2e9 Add changelog entry for checkout_session_params deep-merge fix (#999)
* docs improvements

* many changes

* prompt changes

* add refetch comment

* fix: checkout subscription data

* cus eligibility fixes

* rm cursor thing

---------

Co-authored-by: Ayush Rodrigues <joesj2905@gmail.com>
Co-authored-by: John Yeo <johnyeocx@gmail.com>
Co-authored-by: John Yeo <51376134+johnyeocx@users.noreply.github.com>
Co-authored-by: Ayush <74830628+ay-rod@users.noreply.github.com>
2026-03-17 17:33:52 +00:00

184 lines
4.5 KiB
Plaintext

---
title: Usage-Based Pricing
description: Bill customers based on actual usage at the end of each billing period
---
Pay-per-use (usage-based) pricing charges customers based on how much of a feature they actually consume, billed at the end of each billing period. This is ideal for products where usage varies significantly between customers.
> **Example** <br />
> A notification service charges \$1 per 1,000 notifications sent. A customer who sends 5,000 notifications in a month pays \$5 at the end of that month.
## Setting up
<Tabs>
<Tab title="CLI">
Create a consumable feature with a `usage_based` price:
```ts autumn.config.ts
import { feature, item, plan } from 'atmn';
export const notifications = feature({
id: 'notifications',
name: 'Notifications',
type: 'metered',
consumable: true,
});
export const payAsYouGo = plan({
id: 'pay_as_you_go',
name: 'Pay As You Go',
group: 'main',
items: [
item({
featureId: notifications.id,
included: 1000,
reset: { interval: 'month' },
price: {
amount: 1,
interval: 'month',
billingUnits: 1000,
billingMethod: 'usage_based',
},
}),
],
});
```
Push changes with `atmn push`.
</Tab>
<Tab title="Dashboard">
1. Navigate to **Plans** and create a plan
2. Add a **consumable** feature (e.g., notifications)
3. Set an optional **included** amount (free usage before charges begin)
4. Add a **price** with:
- **Billing method**: Usage-based
- **Amount**: price per billing unit (e.g., $1)
- **Billing units**: the package size (e.g., 1,000 notifications)
- **Interval**: billing frequency (e.g., monthly)
5. Save the plan
</Tab>
</Tabs>
## How it works
1. A customer's usage is tracked via the [track](/documentation/customers/tracking-usage) endpoint throughout the billing period
2. Usage first draws down from the **included** amount (if any) at no charge
3. Usage beyond the included amount is **overage** — billed at the configured rate
4. At the end of the billing period, Autumn generates a Stripe invoice for the total overage
<Note>
Usage-based features allow overage by default. The `check` endpoint will return `allowed: true` even if the customer has exceeded their included balance, as long as a usage-based price is configured.
</Note>
## Tracking usage
Track usage as it occurs — Autumn accumulates it over the billing period:
<CodeGroup>
```typescript TypeScript
import { Autumn } from "autumn-js";
const autumn = new Autumn({ secretKey: "am_sk_..." });
await autumn.track({
customer_id: "user_123",
feature_id: "notifications",
value: 500,
});
```
```python Python
from autumn_sdk import Autumn
autumn = Autumn("am_sk_...")
await autumn.track(
customer_id="user_123",
feature_id="notifications",
value=500,
)
```
```bash cURL
curl -X POST "https://api.useautumn.com/v1/track" \
-H "Authorization: Bearer am_sk_..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "user_123",
"feature_id": "notifications",
"value": 500
}'
```
</CodeGroup>
## Checking access
Check if the customer can use the feature. For usage-based features with overage, `allowed` is `true` as long as the feature exists on the customer's plan:
<CodeGroup>
```typescript TypeScript
const { data } = await autumn.check({
customer_id: "user_123",
feature_id: "notifications",
});
console.log(data.allowed); // true (overage allowed)
console.log(data.balance);
```
```python Python
response = await autumn.check(
customer_id="user_123",
feature_id="notifications",
)
print(response.allowed) # True (overage allowed)
print(response.balance)
```
```bash cURL
curl -X POST "https://api.useautumn.com/v1/check" \
-H "Authorization: Bearer am_sk_..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "user_123",
"feature_id": "notifications"
}'
```
</CodeGroup>
<Expandable title="check response">
```json
{
"allowed": true,
"customerId": "user_123",
"balance": {
"featureId": "notifications",
"granted": 1000,
"remaining": -500,
"usage": 1500,
"unlimited": false,
"overageAllowed": true,
"nextResetAt": 1757192635393
}
}
```
</Expandable>
## Combining with free tiers
A common pattern is pairing usage-based pricing with a [free plan](/documentation/modelling-pricing/free-plans). Free users are blocked when they exceed their limit, while paying users are billed for overages.
| Plan | Over limit | Result |
|------|------------|--------|
| Free | Yes | Blocked (`allowed: false`) |
| Pay-as-you-go | Yes | Allowed, billed at end of period |