Files
cfw-autumn/apps/docs/mintlify/documentation/customers/balances.mdx
2026-02-20 17:33:15 +00:00

197 lines
6.3 KiB
Plaintext

---
title: Balances
description: Learn about feature balances for your metered features
---
Each metered feature you create has 3 different fields associated with it per customer:
1. **Granted**: The total allowance of usage granted to the customer (included + prepaid).
2. **Usage**: The amount of the feature that the customer has used.
3. **Remaining**: The amount of usage that the customer has left (`granted - usage`).
<Note>
If the product item has a `prepaid` price, the granted amount will be dynamically set to the quantity of the product item purchased in advance.
</Note>
## Getting a Customer's Balances
You can get a customer's balances with the `customers.getOrCreate` method:
<CodeGroup>
```typescript TypeScript
import { Autumn } from "autumn-js";
const autumn = new Autumn({ secretKey: "am_sk_test_1234" });
const customer = await autumn.customers.getOrCreate({
customerId: "user_123",
});
// Access balances by feature ID
const messages = customer.balances?.messages;
console.log(`${messages?.remaining} / ${messages?.granted} remaining`);
```
```python Python
from autumn_sdk import Autumn
autumn = Autumn("am_sk_test_1234")
customer = await autumn.customers.get_or_create(
customer_id="user_123"
)
messages = customer.balances.get("messages")
print(f"{messages.remaining} / {messages.granted} remaining")
```
```bash cURL
curl -X POST "https://api.useautumn.com/v1/customers" \
-H "Authorization: Bearer am_sk_test_1234" \
-H "Content-Type: application/json" \
-d '{ "customer_id": "user_123" }'
```
</CodeGroup>
<Expandable title="Example response">
```json
{
"id": "user_123",
"balances": {
"ai-messages": {
"featureId": "ai-messages",
"granted": 100,
"remaining": 40,
"usage": 60,
"unlimited": false,
"overageAllowed": false,
"nextResetAt": 1745193600011
},
"seats": {
"featureId": "seats",
"granted": 5,
"remaining": -1,
"usage": 6,
"unlimited": false,
"overageAllowed": true,
"nextResetAt": null
},
"premium-support": {
"featureId": "premium-support",
"granted": 0,
"remaining": 0,
"usage": 0,
"unlimited": true,
"overageAllowed": false,
"nextResetAt": null
}
}
}
```
</Expandable>
## Positive and Negative Balances
A feature's remaining balance can be positive or negative:
- **Positive Balance**: The customer has used less than the granted amount — they have usage remaining.
- **Negative Balance**: The customer has used more than the granted amount — they will be billed for overage in the next billing period.
<Note>
Features can only have a negative balance if they have a [usage-based price](/documentation/pricing/plan-features#priced-features) associated with them.
If a feature does not have a price, its balance will never fall below 0 even if more usage events are sent.
</Note>
## Reset Intervals
When you create a product item, you'll define a usage reset interval. When the reset interval comes around, `usage` will be reset to 0, and `remaining` will be set back to the `granted` amount.
Reset intervals can be: `minute`, `hour`, `day`, `week`, `month`, `quarter`, `semi_annual`, or `year`.
If a feature has a price associated with it, the reset interval will be the same as the billing interval. This means it can be one of the following: `month`, `quarter`, `semi_annual`, or `year`.
#### No Reset
Certain features are consumable, and can have balances that are replenished. For example, you may have features like:
- Credits
- AI messages
- Hours of compute
Other features are not consumable, and their usage is continuous. For example:
- Seats
- Workspaces
- Number of compute instances in use
These features should not have a reset interval, so that their balances are never reset.
<Note>
This is not a hard rule. You may have consumable features like messages, but
want them to last forever. In this case, they should also have a reset
interval of "no reset"
</Note>
You can configure a product item to have no reset interval by selecting "One-off" in the plan editor dashboard.
<Info>
**Example use case**
We have a free tier, which gives customers access to 3 seats.
We also have a pro tier, which is charged at $10/seat/month.
For our free tier, we'd create a product item with:
- Usage reset: No Reset
- Via API: `interval: null`
For our pro tier, we'd create a product item with:
- Usage reset: No Reset
- Billing Interval: Month
- Via API: `interval: month`, and `reset_usage_on_billing: false`
</Info>
#### Features with multiple intervals
You may have a pricing model in which a customer can buy the following together:
- a pro plan with 50 credits per month.
- a top-up add-on that grants 100 credits that don't expire
In this case you have a feature that shares two intervals: `month` and "no reset".
Autumn will create 2 separate balances for each of these. You will see each of these in the `customers` route and on the customer details page in the dashboard.
When you send a usage event, Autumn will deduct from the balance with the shortest reset interval first.
<Note>
If you want to deduct from the balance with the longest reset interval first,
please contact us.
</Note>
## Edge Cases
There are certain cases in which a feature's balance will diverge from the typical `granted` minus `usage` calculation.
#### Setting a feature's balance manually
You can manually edit a users balance via the dashboard or via the API.
When this happens, the balance will be updated to the new value, but the `granted` and `usage` will not be updated.
#### Customer has paid for more than they are using
Let's take a pricing model in which a customer pays $10 per seat per month. At the start of the billing period, they are using 5 seats (`remaining: -5`, `usage: 5`). Then, they remove a seat.
If `prorate_decrease` is set to `false`, the customer will be paying for 5 seats and using 4 seats (`remaining: -5`, `usage: 4`). This means that our customer has 1 seat available that they have paid for but not using.
In this case, the balance and usage has diverged. Autumn accounts for this scenario: they can add another seat at any time, which will not be charged for.
Otherwise, at the start of the next billing period, they usage and balance will synchronize again (`remaining: -4`, `usage: 4`), and they will be billed for 4 seats.