Billing controls let you manage how individual customers (or entities) consume usage-based features. You can toggle whether overage is allowed, cap how much overage accumulates, hard-cap how much a feature can be used per time window, get notified when usage crosses a threshold, and automatically replenish prepaid balances — all configured per-customer via the API or viewed in the dashboard.
All billing controls are set through the billingControls field when updating a customer or updating an entity.
await autumn.customers.update({
customerId: "user_123",
billingControls: {
overageAllowed: [{ featureId: "api_calls", enabled: true }],
spendLimits: [{ featureId: "api_calls", enabled: true, overageLimit: 5000 }],
usageLimits: [{ featureId: "api_calls", limit: 50, interval: "day" }],
usageAlerts: [{ featureId: "api_calls", threshold: 80, thresholdType: "usage_percentage", enabled: true }],
autoTopups: [{ featureId: "credits", enabled: true, threshold: 500, quantity: 1000 }],
},
});
Overage Allowed
By default, whether a customer can use a feature beyond their included balance depends on the plan’s pricing model. Features with usage-based pricing (pay-per-use) automatically allow overage — the customer keeps using and gets billed for the extra. Features without usage-based pricing (like a flat included allowance) block usage once the balance hits zero.
The overageAllowed control lets you override this default per customer or entity.
Default behavior (no override)
| Plan item pricing | Overage? |
|---|
| Usage-based (pay-per-use) | Allowed — customer is billed for overage |
| Included / prepaid (no overage price) | Blocked — check returns allowed: false at zero balance |
With overageAllowed enabled
Setting overageAllowed to true on a feature lets a customer consume beyond their included balance even when the plan doesn’t have usage-based pricing for that feature. The balance goes negative, meaning you can track how much overage occurred, though no automatic overage charge is created.
Example
A customer is on a free plan with 100 API calls included (no overage pricing). Normally they’d be blocked at 0 remaining. You set overageAllowed: true for api_calls. Now they can keep using beyond 100, and you can decide how to handle the overage in your application (prompt an upgrade, bill manually, etc.).
await autumn.customers.update({
customerId: "user_123",
billingControls: {
overageAllowed: [{
featureId: "api_calls",
enabled: true,
}],
},
});
| Field | Type | Description |
|---|
feature_id | string | The feature to override overage behavior for |
enabled | boolean | true to allow overage, false to block it |
Disabling overage on a pay-per-use feature
You can also use overageAllowed to block overage on a feature that would normally allow it. Setting enabled: false forces a hard cap at the included balance — even if the plan has usage-based pricing for that feature.
Example
A customer’s plan includes 1,000 API calls with pay-per-use overage at $1/1,000 calls. You set overageAllowed: false for api_calls. The customer is now blocked at 1,000 total calls — no overage charges will occur.
Setting overageAllowed: false is a hard override. It takes precedence over usage-based pricing on the plan. The customer will be blocked at zero remaining balance regardless of whether overage pricing exists.
How it interacts with spend limits
overageAllowed and spend limits are complementary:
overageAllowed answers: can usage go beyond the included balance?
- Spend limits answer: how far can overage go?
If both are set, overageAllowed is checked first. If overage is blocked (enabled: false), the spend limit is irrelevant. If overage is allowed, the spend limit caps how much overage can accumulate.
Spend Limits
Spend limits cap how much overage a customer can accumulate on a usage-based feature. Once the cap is reached, check returns allowed: false and track stops deducting.
Example
A customer’s plan includes 1,000 API calls with $1 per 1,000 overage calls. You set a spend limit of 5,000 on api_calls. The customer can use up to 6,000 total calls (1,000 included + 5,000 overage), then they’re blocked.
await autumn.customers.update({
customerId: "user_123",
billingControls: {
spendLimits: [{
featureId: "api_calls",
enabled: true,
overageLimit: 5000,
}],
},
});
| Field | Type | Description |
|---|
feature_id | string | The feature to cap |
enabled | boolean | Whether the spend limit is active |
overage_limit | number | Maximum overage units beyond the included amount |
The overage_limit is measured in feature units, not dollars. An overage_limit of 5,000 on “API calls” means 5,000 additional API calls beyond the included allowance.
When both a spend limit and a plan-level max purchase exist for the same feature, the spend limit takes precedence. This lets you use max purchase as a default for all customers, then selectively raise or lower the cap per-customer.
For a deeper dive, see Spend Limits & Usage Alerts.
Usage Limits
A usage limit is a windowed hard cap: at most limit units of a feature per interval window (day, week, month, or year), regardless of how much balance the customer has left or how the plan is priced. It’s a throttle, that you or your customer may set.
Once usage reaches the cap inside the active window, check returns allowed: false and track stops deducting.
Usage limits cap total usage of a feature within a period: a sub-limit within an existing balance. They sit on top of the plan’s allowance and apply even when there’s balance remaining and even when the feature has no overage pricing.
Example
A customer’s plan includes 300 credits per month, but you want to stop any single day from burning through them. Set a usage limit of 50 on credits with a day interval. The customer still gets their 300 monthly credits, but can never spend more than 50 in a day.
await autumn.customers.update({
customerId: "user_123",
billingControls: {
usageLimits: [{
featureId: "credits",
limit: 50,
interval: "day",
}],
},
});
| Field | Type | Description |
|---|
feature_id | string | The feature to cap |
limit | number | Maximum units allowed per window |
interval | string | Window length: "day", "week", "month", or "year". Cannot be one_off. |
Each customer/entity feature in a get response carries a usage_limits array where every entry also reports the usage consumed in the current window, so you can show “12 / 50 used today” without a separate call.
Window reset and plan changes
Each window aligns to the customer’s billing cycle, not the UTC calendar. A day cap rolls at the customer’s billing time-of-day; a month cap rolls on their billing-cycle anchor. When there’s no billing cycle to anchor to (e.g. a feature with no backing plan), the window falls back to UTC calendar alignment — daily windows roll at UTC midnight, monthly on the 1st.
Because the window is tied to the feature’s reset cycle, a plan change that restarts that cycle also restarts the window. If a customer upgrades mid-month and their billing anchor moves, the usage limit’s window re-anchors to the new cycle and the consumed counter starts fresh.
Caps on credit systems
When a feature is part of a credit system, you can cap usage at either level:
- Cap the credit balance — e.g. limit total
credits spend per window across every feature that draws from it.
- Cap an individual feature — e.g. give a credit system shared by features A, B, and C, but limit how many units of B specifically can be used per window. The per-feature cap is converted into credits using B’s credit cost, so both caps are enforced together.
Example — per-feature cap inside a credit system
Your credits system is spent by images, transcriptions, and exports. Customers can spend credits freely across all three, but you cap exports at 10 per day so one feature can’t drain the whole balance. A check or track on exports is blocked at 10/day even if plenty of credits remain.
When more than one cap applies to a check (the cap on the evaluated feature and a cap on its parent credit system), Autumn enforces the tightest one — the remaining headroom is the minimum across all armed caps.
Usage Alerts
Usage alerts fire a webhook when a customer’s usage crosses a threshold. They don’t block usage — they notify, so you can take action like sending a warning email or prompting an upgrade.
There are two threshold types:
usage — fires when absolute usage reaches a specific count
usage_percentage — fires when usage reaches a percentage of the included allowance
await autumn.customers.update({
customerId: "user_123",
billingControls: {
usageAlerts: [
{
featureId: "api_calls",
threshold: 80,
thresholdType: "usage_percentage",
enabled: true,
name: "80% usage warning",
},
{
featureId: "api_calls",
threshold: 900,
thresholdType: "usage",
enabled: true,
name: "Approaching limit",
},
],
},
});
| Field | Type | Description |
|---|
feature_id | string | The feature to monitor |
threshold | number | Trigger value — absolute count or percentage (0–100) |
threshold_type | string | "usage" for absolute count, "usage_percentage" for percentage of included allowance |
enabled | boolean | Whether the alert is active (defaults to true) |
name | string (optional) | A label to distinguish multiple alerts |
Each alert fires once per threshold crossing. It won’t re-fire unless usage drops below the threshold and crosses it again.
When triggered, Autumn sends a balances.usage_alert_triggered webhook. See the webhook schema for the full payload.
For more details and examples, see Spend Limits & Usage Alerts.
Auto Top-Ups
Auto top-ups automatically replenish a customer’s prepaid balance when it drops below a configured threshold. This prevents service interruptions for customers who don’t want to manually manage their credits.
Example
A customer gets 5,000 credits per month. When their balance drops below 500, Autumn automatically purchases 1,000 more credits using the plan’s one-off prepaid price.
Auto top-ups require a plan with a one-off prepaid item for the feature, and the customer must have a payment method on file.
await autumn.customers.update({
customerId: "user_123",
billingControls: {
autoTopups: [{
featureId: "credits",
enabled: true,
threshold: 500,
quantity: 1000,
}],
},
});
| Field | Type | Description |
|---|
feature_id | string | The feature (credit balance) to monitor |
enabled | boolean | Whether auto top-up is active |
threshold | number | Balance level that triggers a top-up |
quantity | number | Units to purchase each time |
purchase_limit | object (optional) | Rate limit on how often top-ups can occur |
To prevent runaway spending, you can set a purchase limit:
{
"purchase_limit": {
"interval": "month",
"interval_count": 1,
"limit": 5
}
}
This limits the customer to 5 auto top-ups per month. Supported intervals: hour, day, week, month.
For setup instructions and how it works end-to-end, see Auto Top-Ups.
Customer vs Entity Controls
Billing controls can be set at two levels:
| Control | Customer-level | Entity-level |
|---|
| Overage allowed | Yes | Yes |
| Spend limits | Yes | Yes |
| Usage limits | Yes | Yes |
| Usage alerts | Yes | Yes |
| Auto top-ups | Yes | No |
Entity-level controls are configured by updating the entity instead of the customer. Entity-level controls override customer-level controls for that entity — for example, an entity overage override takes precedence over the customer-level setting, and entity spend limits override the customer-level limit.
Overrides are resolved per feature: an entity’s own entry for a feature wins, and the customer’s entries fill in any features the entity doesn’t set. For usage limits specifically, an inherited (customer-level) cap counts usage against the shared customer window — it’s the same aggregate cap, not a separate per-entity copy. An entity-level usage limit, by contrast, gets its own per-entity window and counter.
Example — per-entity cap
An org (the customer) has 1,000 monthly API calls shared across its workspaces (entities). You set a customer-level usage limit of 1,000/month so the org can’t exceed its plan, and an entity-level limit of 200/day on a noisy workspace so it can’t starve the others. The workspace is blocked at 200/day; the org is blocked at 1,000/month.
await autumn.entities.update({
customerId: "org_123",
entityId: "workspace_a",
billingControls: {
overageAllowed: [{
featureId: "api_calls",
enabled: true,
}],
spendLimits: [{
featureId: "api_calls",
enabled: true,
overageLimit: 2000,
}],
usageLimits: [{
featureId: "api_calls",
limit: 200,
interval: "day",
}],
usageAlerts: [{
featureId: "api_calls",
threshold: 90,
thresholdType: "usage_percentage",
enabled: true,
}],
},
});
Auto top-ups are customer-level only because they create invoices and charge a payment method, which is tied to the customer account — not individual entities.
Billing controls tie into three webhook events that fire automatically based on usage:
| Event | When it fires |
|---|
balances.limit_reached | Customer transitions from allowed to not allowed on a feature (included allowance exhausted, max purchase hit, spend limit reached, or usage limit hit). The payload’s limit_type distinguishes included, max_purchase, spend_limit, and usage_limit. |
balances.usage_alert_triggered | Customer’s usage crosses a configured alert threshold |
customer.products.updated | Customer’s subscription changes (new, upgrade, downgrade, cancel, etc.) |
For webhook setup and security details, see Webhooks.