This commit is contained in:
Ayush Rodrigues
2026-03-02 22:23:20 +00:00
parent c2ffe88497
commit 8774f1843e
15 changed files with 1775 additions and 209 deletions

View File

@@ -0,0 +1,259 @@
---
title: "Command reference"
description: "Every command, flag, and option available in the atmn CLI"
---
## Global flags
These flags work with any command:
| Flag | Description |
|------|-------------|
| `-p, --prod` | Target production instead of sandbox |
| `-l, --local` | Use `localhost:8080` API server |
| `--headless` | Force non-interactive mode (for CI/agents) |
| `-c, --config <path>` | Path to config file (default: `autumn.config.ts`) |
| `-v, --version` | Show CLI version |
Flags can be combined -- for example, `atmn push -lp` targets production on a local API server.
## Authentication
### `atmn login`
Authenticate with Autumn via OAuth. Opens your browser, lets you select an organization, and saves sandbox + production API keys to `.env`.
```bash
atmn login
```
In non-TTY environments (CI), it prints a URL you can open manually.
### `atmn logout`
Remove `AUTUMN_SECRET_KEY` and `AUTUMN_PROD_SECRET_KEY` from your `.env` file.
```bash
atmn logout
```
### `atmn env`
Show your current organization and environment:
```bash
atmn env
```
```
Organization: Acme Corp
Slug: acme-corp
Environment: Sandbox
```
## Configuration
### `atmn init`
Create an `autumn.config.ts` from a starter template. Prompts for login if you haven't authenticated yet.
```bash
atmn init
```
### `atmn push`
Push your local `autumn.config.ts` to Autumn.
```bash
atmn push [options]
```
| Flag | Description |
|------|-------------|
| `-y, --yes` | Auto-confirm all prompts |
The CLI compares your local config with what's in Autumn and shows a summary of changes before applying. If plans with existing customers are modified, it will prompt about versioning.
### `atmn pull`
Pull plans and features from Autumn into your local `autumn.config.ts`.
```bash
atmn pull [options]
```
| Flag | Description |
|------|-------------|
| `-f, --force` | Overwrite config instead of smart in-place update |
By default, `pull` does a smart in-place update -- it adds new features and plans, updates existing ones, and removes deleted ones while preserving your formatting. Use `--force` to overwrite the entire file.
`pull` also generates an `@useautumn-sdk.d.ts` file with typed `FeatureIds` and `PlanIds` for IDE autocompletion.
### `atmn preview`
Render a pricing table from your local config without making any API calls.
```bash
atmn preview [options]
```
| Flag | Description |
|------|-------------|
| `--plan <id>` | Preview a specific plan |
| `--currency <code>` | Currency for display (default: `USD`) |
### `atmn nuke`
Permanently delete all data in your **sandbox**. This command refuses to run with `--prod`.
```bash
atmn nuke
```
| Flag | Description |
|------|-------------|
| `--dangerously-skip-all-confirmation-prompts` | Skip all safety prompts |
<Warning>
This is irreversible. The flag name is intentionally long to prevent accidental use.
</Warning>
## Data browsing
These commands open a full interactive TUI for browsing and inspecting your Autumn data. Use the `--headless` flag to get structured data instead.
### `atmn customers`
```bash
atmn customers [options]
```
| Flag | Description |
|------|-------------|
| `--id <id>` | Get a specific customer |
| `--search <query>` | Filter customers |
| `--page <n>` | Page number (default: `1`) |
| `--limit <n>` | Results per page (default: `50`) |
| `--format <fmt>` | Output: `text`, `json`, `csv` (default: `text`) |
### `atmn plans`
```bash
atmn plans [options]
```
| Flag | Description |
|------|-------------|
| `--id <id>` | Get a specific plan |
| `--search <query>` | Filter plans |
| `--include-archived` | Include archived plans |
| `--page <n>` | Page number (default: `1`) |
| `--limit <n>` | Results per page (default: `50`) |
| `--format <fmt>` | Output: `text`, `json`, `csv` (default: `text`) |
<Note>
`atmn products` is an alias for `atmn plans`.
</Note>
### `atmn features`
```bash
atmn features [options]
```
| Flag | Description |
|------|-------------|
| `--id <id>` | Get a specific feature |
| `--search <query>` | Filter features |
| `--include-archived` | Include archived features |
| `--page <n>` | Page number (default: `1`) |
| `--limit <n>` | Results per page (default: `50`) |
| `--format <fmt>` | Output: `text`, `json`, `csv` (default: `text`) |
### `atmn events`
```bash
atmn events [options]
```
| Flag | Description |
|------|-------------|
| `--customer <id>` | Filter by customer |
| `--feature <id>` | Filter by feature (comma-separated for multiple) |
| `--time <range>` | Time range: `24h`, `7d`, `30d`, `90d` (default: `7d`) |
| `--mode <mode>` | `list` or `aggregate` (default: `list`) |
| `--bin <size>` | Bin size for aggregate: `hour`, `day`, `month` |
| `--group-by <prop>` | Group by property in aggregate mode |
| `--page <n>` | Page number (default: `1`) |
| `--limit <n>` | Results per page (default: `100`) |
| `--format <fmt>` | Output: `text`, `json`, `csv` (default: `text`) |
## Configuration
### `atmn config`
View and manage persistent CLI settings.
```bash
atmn config # Show help and config file location
atmn config --global # Same as above
atmn config --global <key> # Read a setting
atmn config --global <key> <value> # Write a setting
```
Running `atmn config` with no arguments shows the full path to your config file, supported keys, and usage info.
| Flag | Description |
|------|-------------|
| `-g, --global` | Use global config |
#### Available keys
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `noDeclarationFile` | `boolean` | `false` | Skip generating `@useautumn-sdk.d.ts` on `atmn pull` |
#### Priority order
Settings are resolved in this order: **CLI flag** → **global config** → **default value**. For example, `--no-declaration-file` on `atmn pull` always takes priority over the global `noDeclarationFile` setting.
#### Config file location
Running `atmn config` or `atmn config --global` (with no key) prints the exact path to your config file on disk.
| OS | Path |
|----|------|
| macOS | `~/Library/Preferences/atmn/config.json` |
| Linux | `~/.config/atmn/config.json` (or `$XDG_CONFIG_HOME`) |
| Windows | `%APPDATA%\atmn\config.json` |
## Utilities
### `atmn dashboard`
Open the Autumn dashboard in your browser.
```bash
atmn dashboard
```
### `atmn version`
Print the CLI version. Alias: `atmn v`.
```bash
atmn version
```
## Headless mode
The CLI automatically detects non-TTY environments and switches to headless mode with plain text output and no interactive prompts. You can also force it with `--headless`.
### Exit codes
| Code | Meaning |
|------|---------|
| `0` | Success |
| `1` | Error (network, auth, validation, or confirmation required) |

View File

@@ -0,0 +1,364 @@
---
title: "Configuration reference"
description: "Define features, plans, and pricing in autumn.config.ts"
---
Your `autumn.config.ts` file is the source of truth for your pricing. It exports features and plans using helper functions from the `atmn` package.
```ts autumn.config.ts
import { feature, plan, planFeature } from 'atmn';
export const messages = feature({ ... });
export const pro = plan({ ... });
```
Push changes with `atmn push`, or pull existing config with `atmn pull`.
## Features
Features define what can be gated, metered, or billed in your app.
### `feature(config)`
<ParamField body="id" type="string" required>
Unique identifier used in API calls (`check`, `track`, etc).
</ParamField>
<ParamField body="name" type="string" required>
Display name shown in the dashboard and billing UI.
</ParamField>
<ParamField body="type" type="enum" required>
`"boolean"` | `"metered"` | `"credit_system"`
</ParamField>
<ParamField body="consumable" type="boolean">
**Required for `metered` features.**
- `true` -- usage is consumed (messages, API calls, credits)
- `false` -- usage is ongoing (seats, storage, workspaces)
</ParamField>
<ParamField body="credit_schema" type="array">
**Required for `credit_system` features.** Maps metered features to credit costs.
Each entry: `{ metered_feature_id: string, credit_cost: number }`
</ParamField>
### Feature types
**Boolean** -- simple on/off flag:
```ts
export const sso = feature({
id: 'sso',
name: 'SSO Authentication',
type: 'boolean',
});
```
**Metered, consumable** -- used up and replenished (messages, API calls):
```ts
export const messages = feature({
id: 'messages',
name: 'Messages',
type: 'metered',
consumable: true,
});
```
**Metered, non-consumable** -- ongoing usage (seats, storage):
```ts
export const seats = feature({
id: 'seats',
name: 'Seats',
type: 'metered',
consumable: false,
});
```
**Credit system** -- maps multiple metered features to credit costs:
```ts
export const basicModel = feature({
id: 'basic_model',
name: 'Basic Model',
type: 'metered',
consumable: true,
});
export const premiumModel = feature({
id: 'premium_model',
name: 'Premium Model',
type: 'metered',
consumable: true,
});
export const credits = feature({
id: 'credits',
name: 'AI Credits',
type: 'credit_system',
credit_schema: [
{ metered_feature_id: basicModel.id, credit_cost: 1 },
{ metered_feature_id: premiumModel.id, credit_cost: 5 },
],
});
```
<Tip>
If you set the price per credit to 1 cent, credits become monetary credits (eg, 5 credits = $0.05 per premium message).
</Tip>
## Plans
Plans combine features with pricing to create your subscription tiers, add-ons, and top-ups.
### `plan(config)`
<ParamField body="id" type="string" required>
Unique identifier used in checkout and subscription APIs.
</ParamField>
<ParamField body="name" type="string" required>
Display name shown in pricing tables and billing.
</ParamField>
<ParamField body="price" type="object">
Base subscription price:
- `amount: number` -- price amount (eg, `20` for $20)
- `interval: string` -- `"month"` | `"quarter"` | `"semi_annual"` | `"year"` | `"one_off"`
</ParamField>
<ParamField body="items" type="array">
Array of `planFeature()` objects defining what's included.
</ParamField>
<ParamField body="auto_enable" type="boolean" default="false">
Automatically assign this plan to new customers. Typically used for free plans.
</ParamField>
<ParamField body="add_on" type="boolean" default="false">
Allow this plan to be purchased alongside other plans (instead of replacing them).
</ParamField>
<ParamField body="free_trial" type="object">
Free trial before billing starts:
- `duration_length: number` -- eg, `14`
- `duration_type: string` -- `"day"` | `"month"` | `"year"`
- `card_required: boolean` -- whether a card is needed to start the trial
</ParamField>
<ParamField body="group" type="string">
Group related plans together. Plans in the same group replace each other on upgrade/downgrade.
</ParamField>
## Plan features
Plan features define what each plan includes -- usage limits, pricing, and billing behavior.
### `planFeature(config)`
<ParamField body="feature_id" type="string" required>
The `id` of the feature to include.
</ParamField>
<ParamField body="included" type="number">
Amount included for free. Omit for boolean features.
</ParamField>
<ParamField body="unlimited" type="boolean">
Grant unlimited usage of this feature.
</ParamField>
<ParamField body="reset" type="object">
How often the included amount resets:
- `interval: string` -- `"hour"` | `"day"` | `"week"` | `"month"` | `"quarter"` | `"semi_annual"` | `"year"`
- `interval_count: number` -- defaults to `1`
</ParamField>
<ParamField body="price" type="object">
Pricing for usage beyond the included amount. See [pricing patterns](#pricing-patterns) below.
</ParamField>
<ParamField body="proration" type="object">
How to handle mid-cycle quantity changes:
- `on_increase:` `"prorate"` | `"charge_immediately"`
- `on_decrease:` `"prorate"` | `"refund_immediately"` | `"no_action"`
</ParamField>
<ParamField body="rollover" type="object">
Carry unused balance forward:
- `max: number` -- maximum rollover amount
- `expiry_duration_type:` `"month"` | `"forever"`
- `expiry_duration_length: number` -- ignored if type is `"forever"`
</ParamField>
### Pricing patterns
The `price` object on a plan feature supports different billing models:
**Usage-based** -- charge based on actual usage:
```ts
planFeature({
feature_id: seats.id,
included: 5,
price: {
amount: 10,
interval: 'month',
billing_method: 'usage_based',
billing_units: 1,
},
})
```
**Prepaid** -- customer buys a fixed quantity upfront:
```ts
planFeature({
feature_id: credits.id,
price: {
amount: 5,
billing_units: 100,
billing_method: 'prepaid',
},
})
```
**Tiered** -- price changes based on usage volume:
```ts
planFeature({
feature_id: apiCalls.id,
price: {
tiers: [
{ to: 1000, amount: 0.01 },
{ to: 10000, amount: 0.008 },
{ to: 'inf', amount: 0.005 },
],
billing_method: 'usage_based',
interval: 'month',
},
})
```
#### Price fields
<ParamField body="amount" type="number">
Price per `billing_units`. Mutually exclusive with `tiers`.
</ParamField>
<ParamField body="tiers" type="array">
Tiered pricing. Each entry: `{ to: number | "inf", amount: number }`. Mutually exclusive with `amount`.
</ParamField>
<ParamField body="billing_method" type="enum" required>
`"usage_based"` | `"prepaid"`
</ParamField>
<ParamField body="interval" type="enum">
`"week"` | `"month"` | `"quarter"` | `"semi_annual"` | `"year"`. Omit for one-time charges. Not needed if the plan feature has a top-level `reset`.
</ParamField>
<ParamField body="billing_units" type="number" default="1">
Units per price. Eg, $5 per 100 credits = `amount: 5, billing_units: 100`.
</ParamField>
<ParamField body="max_purchase" type="number">
Maximum quantity that can be purchased.
</ParamField>
## Full example
A complete config with a free plan, a paid plan with a trial, and a credits top-up add-on:
```ts autumn.config.ts
import { feature, plan, planFeature } from 'atmn';
// Features
export const messages = feature({
id: 'messages',
name: 'Messages',
type: 'metered',
consumable: true,
});
export const seats = feature({
id: 'seats',
name: 'Seats',
type: 'metered',
consumable: false,
});
export const sso = feature({
id: 'sso',
name: 'SSO',
type: 'boolean',
});
// Plans
export const free = plan({
id: 'free',
name: 'Free',
auto_enable: true,
items: [
planFeature({
feature_id: messages.id,
included: 5,
reset: { interval: 'month' },
}),
planFeature({
feature_id: seats.id,
included: 1,
}),
],
});
export const pro = plan({
id: 'pro',
name: 'Pro',
price: { amount: 20, interval: 'month' },
free_trial: {
duration_length: 14,
duration_type: 'day',
card_required: true,
},
items: [
planFeature({
feature_id: messages.id,
included: 1000,
reset: { interval: 'month' },
}),
planFeature({
feature_id: seats.id,
included: 5,
price: {
amount: 10,
interval: 'month',
billing_method: 'usage_based',
billing_units: 1,
},
}),
planFeature({
feature_id: sso.id,
}),
],
});
export const topUp = plan({
id: 'top_up',
name: 'Message Top-Up',
add_on: true,
items: [
planFeature({
feature_id: messages.id,
price: {
amount: 5,
billing_units: 100,
billing_method: 'prepaid',
},
}),
],
});
```

View File

@@ -0,0 +1,121 @@
---
title: "Getting started"
description: "Install the CLI, authenticate, and sync your pricing config"
---
The `atmn` CLI lets you define your pricing plans in code via an `autumn.config.ts` file, and sync them to Autumn with a single command.
## Installation
Run the CLI directly with your package manager:
<CodeGroup>
```bash bunx
bunx atmn
```
```bash pnpm
pnpm dlx atmn
```
```bash npx
npx atmn
```
</CodeGroup>
## Login
Authenticate with your Autumn account:
```bash
bunx atmn login
```
This opens your browser, lets you pick an organization, and saves API keys for both sandbox and production to your `.env` file:
```bash .env
AUTUMN_SECRET_KEY=am_sk_test_...
AUTUMN_PROD_SECRET_KEY=am_sk_live_...
```
<Check>
You can verify your setup at any time with `bunx atmn env`, which shows your current organization and environment.
</Check>
## Initialize a project
Run `atmn init` in your project root to create an `autumn.config.ts` file:
```bash
bunx atmn init
```
You'll be prompted to choose a starter template:
| Template | Pricing model |
|----------|--------------|
| **T3 Chat** | Freemium with message limits and a credits add-on |
| **Railway** | Credit-based infrastructure pricing with overage |
| **Linear** | Per-seat pricing with team limits |
| **OpenAI** | Credit system mapping multiple AI models |
Pick whichever is closest to your use case, or start from scratch and build your own using the [config reference](/api-reference/cli/config).
## Push and pull
Once you have an `autumn.config.ts`, sync it with Autumn:
```bash
# Push local config to Autumn
bunx atmn push
# Pull remote config into your local file
bunx atmn pull
```
`push` reads your config file, compares it with what's in Autumn, and applies the changes. In interactive mode you'll see a summary of what will be created, updated, or deleted before confirming.
`pull` fetches your plans and features from Autumn and writes them into your local `autumn.config.ts`. If the file already exists, it does a smart in-place update that preserves your local formatting and comments where possible.
<Tip>
Use `bunx atmn pull` to generate an `autumn.config.ts` from plans you've already created in the dashboard.
</Tip>
## Preview locally
You can preview your plans without pushing anything:
```bash
bunx atmn preview
```
This renders a pricing table from your local config.
## Environments
By default, all commands target your **sandbox** environment. Add the `-p` flag to target production:
```bash
# Push to production
bunx atmn push -p
# Pull from production
bunx atmn pull -p
```
<Warning>
Pushing to production will prompt for confirmation. Use `--yes` to skip the prompt automatically.
</Warning>
**Next: Configuration reference**
Learn how to define features, plans, and pricing in your `autumn.config.ts`.
<Card
title="Configuration reference"
href="/api-reference/cli/config"
>
Complete reference for features, plans, and plan features
</Card>

View File

@@ -45,7 +45,7 @@
"groups": [
{
"group": " ",
"pages": ["welcome"]
"pages": ["welcome", "documentation/getting-started/migration"]
},
{
"group": "Getting Started",
@@ -76,19 +76,36 @@
{
"group": "Manage Customers",
"pages": [
{
"group": "Subscriptions",
"pages": [
"documentation/customers/subscriptions/overview",
"documentation/customers/subscriptions/accepting-payments",
"documentation/customers/subscriptions/managing-subscriptions"
]
},
{
"group": "Balances",
"pages": [
"documentation/customers/balances/overview",
"documentation/customers/balances/balance-stacking",
"documentation/customers/balances/managing-balances"
]
},
"documentation/customers/check",
"documentation/customers/tracking-usage",
"documentation/customers/balances",
"documentation/customers/feature-entities",
"documentation/customers/attaching-plans",
"documentation/customers/updating-subscriptions",
"documentation/customers/creating-customers",
"documentation/customers/managing-customers"
]
},
{
"group": "Additional Resources",
"pages": ["documentation/external-providers/revenuecat"]
"pages": [
"documentation/webhooks",
"documentation/external-providers/revenuecat",
"documentation/external-providers/vercel-marketplace"
]
}
]
},
@@ -104,7 +121,7 @@
},
{
"tab": "React",
"icon": "image",
"icon": "react",
"groups": [
{
"group": "React Hooks",
@@ -122,9 +139,14 @@
}
]
},
{
"tab": "CLI",
"icon": "square-terminal",
"pages": ["cli/getting-started", "cli/config", "cli/commands"]
},
{
"tab": "API Reference",
"icon": "rectangle-terminal",
"icon": "display-code",
"groups": [
{
"group": "Billing",

View File

@@ -1,196 +0,0 @@
---
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.

View File

@@ -0,0 +1,71 @@
---
title: "Balance Stacking"
description: "How multiple balances combine and how usage is deducted"
---
A single feature can have balances from multiple sources - different plans, add-ons, or standalone grants.
Autumn combines these into a single parent balance while tracking each source separately in a `breakdown` array, grouped by plan and interval.
> **Example** <br />
> A customer has a feature, `messages`, with the following balances:
> - Pro plan: 500 messages per month
> - Top-up add-on: 200 lifetime messages
>
> Their total available balance is 700 `messages`.
## The Breakdown Array
Each balance source is tracked separately in the `breakdown` array. This lets you see exactly where the balance came from and how much remains from each source.
```json expandable
{
"balances": {
"messages": {
"included_usage": 700,
"balance": 700,
"usage": 0,
"breakdown": [
{
"id": "ent_abc123",
"product_id": "pro",
"included_usage": 500,
"balance": 500,
"usage": 0,
"interval": "month",
"next_reset_at": 1745193600000
},
{
"id": "ent_def456",
"product_id": "top-up",
"included_usage": 200,
"balance": 200,
"usage": 0,
"interval": "one_off",
"next_reset_at": null
}
]
}
}
}
```
## Deduction Order
When usage is tracked, Autumn deducts from balances in a specific order based on their reset interval. **Shorter intervals are deducted first** by default.
The order is: `hour` (shortest) > `day` > `week` > `month` > `quarter` > `semi_annual` > `year` > `one_off` (lifetime - never resets).
This ensures that expiring balances are used before permanent ones.
<Note>
If you need the deduction order reversed (longest interval first), please [contact us](https://discord.gg/STqxY92zuS).
</Note>
> **Example** <br />
> Suppose a customer has two balances for messages: 500 monthly and 200 lifetime. They have a total of 700 messages. <br />
> - The customer uses 400 messages. The monthly balance (the shorter interval) is used up first, leaving 100 in monthly and 200 in lifetime (300 total). <br />
> - The customer uses another 200 messages. The remaining 100 monthly is depleted, and the next 100 is deducted from the lifetime balance. Now, monthly is 0, lifetime is 100 (100 total). <br />
> - On the next cycle, the monthly balance resets to 500, and the lifetime remains at 100, for a new total of 600. <br />

View File

@@ -0,0 +1,186 @@
---
title: "Managing Balances"
description: "Create, update, and manage balances via the dashboard or API"
---
You can manage customer balances through the Autumn dashboard or programmatically via the API.
## From the Dashboard
### Viewing Balances
1. Go to the [Customers page](https://app.useautumn.com/customers)
2. Click on a customer to view their details
3. Their balances are displayed in the **Balances** section, including breakdown by source
### Modifying a Balance
To set or add to a feature's balance:
1. Navigate to the customer's detail page
2. Under the balances section, click on the feature you want to modify. If there are [stacked balances](/documentation/customers/balance-stacking), choose the one you want to modify.
3. Choose whether to **set the balance** to a specific value or **add to the balance**
4. Enter the amount and save
## Creating Standalone Balances (API)
You can use the `/balances/create` endpoint to grant balances independent of any plan, for example to issue one-time promotional credits, referral rewards, or make manual customer adjustments.
You can also set expiration dates for promotional usage grants and configure reset intervals.
<CodeGroup>
```typescript Node.js
import { Autumn } from "autumn-js";
const autumn = new Autumn({ secretKey: "am_sk_..." });
await autumn.balances.create({
customer_id: "user_123",
feature_id: "credits",
granted_balance: 500,
reset: {
interval: "one_off"
}
});
```
```python Python
from autumn import Autumn
autumn = Autumn(secret_key="am_sk_...")
autumn.balances.create(
customer_id="user_123",
feature_id="credits",
granted_balance=500,
reset={
"interval": "one_off"
}
)
```
```bash cURL
curl -X POST https://api.useautumn.com/v1/balances/create \
-H "Authorization: Bearer am_sk_..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "user_123",
"feature_id": "credits",
"granted_balance": 500,
"reset": {
"interval": "one_off"
}
}'
```
</CodeGroup>
See the [Create Balance API reference](/api-reference/features/create-balance) for all available parameters.
## Updating Balances (API)
Use the `/customers/{customer_id}/balances` endpoint to set balances for a customer.
<CodeGroup>
```typescript Node.js
import { Autumn } from "autumn-js";
const autumn = new Autumn({ secretKey: "am_sk_..." });
await autumn.customers.updateBalances("user_123", {
balances: [{ feature_id: "credits", balance: 750 }]
});
```
```python Python
from autumn import Autumn
autumn = Autumn(secret_key="am_sk_...")
autumn.customers.update_balances(
"user_123",
balances=[{"feature_id": "credits", "balance": 750}]
)
```
```bash cURL
curl -X POST https://api.useautumn.com/v1/customers/user_123/balances \
-H "Authorization: Bearer am_sk_..." \
-H "Content-Type: application/json" \
-d '{
"balances": [{ "feature_id": "credits", "balance": 750 }]
}'
```
</CodeGroup>
See the [Set Feature Balance API reference](/api-reference/features/set-feature-balances) for all available parameters.
## Querying Balances
### Via Get Customer
Retrieve all balances for a customer:
<CodeGroup>
```typescript Node.js
const customer = await autumn.customers.get("user_123");
console.log(customer.balances);
```
```python Python
customer = autumn.customers.get("user_123")
print(customer.balances)
```
```bash cURL
curl https://api.useautumn.com/v1/customers/user_123 \
-H "Authorization: Bearer am_sk_..."
```
</CodeGroup>
See the [Get Customer API reference](/api-reference/customers/get-customer) for the full response schema.
### Via Check Endpoint
Check access and get the current balance for a specific feature:
<CodeGroup>
```typescript Node.js
const result = await autumn.check({
customer_id: "user_123",
feature_id: "credits"
});
console.log(result.allowed);
console.log(result.balance);
```
```python Python
result = autumn.check(
customer_id="user_123",
feature_id="credits"
)
print(result.allowed)
print(result.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": "credits"
}'
```
</CodeGroup>
See the [Check API reference](/api-reference/core/check) for more details.

View File

@@ -0,0 +1,105 @@
---
title: "Balances"
description: "Understanding how feature balances work in Autumn"
---
Balances determine what features a customer can use, and track how much they have used.
Balances are created in two ways:
1. **Automatically from plans**: When a plan is attached to a customer, each feature in the plan becomes a balance for that customer.
2. **Standalone via API**: You can create balances directly using the API, independent of any plan. See [Managing Balances](/documentation/customers/managing-balances) for details.
```mermaid
flowchart LR
F[Feature] -->|added to plan| PF[Plan Feature]
PF -->|plan attached to customer| B[Customer Balance]
```
Customers can also [Stack Balances](/documentation/customers/balance-stacking) of the same feature from multiple plans (eg, an add-on plan), or different reset intervals (eg, monthly credits and one-time top-ups).
## Core Fields
Each balance has the following key fields:
| Field | Description |
|-------|-------------|
| `included_usage` | The amount granted by the plan, or a purchased quantity |
| `balance` | The remaining amount available |
| `usage` | The amount that has been consumed |
When you retrieve a customer, their balances will be included in the response.
<Tip>
For the complete balance schema including reset configuration, overage settings, and breakdown details, see the [Get Customer API reference](/api-reference/customers/get-customer).
</Tip>
<Expandable title="example customer response">
```json
{
"balances": {
"messages": {
"granted_balance": 1000,
"current_balance": 750,
"usage": 250,
"unlimited": false,
"reset": {
"interval": "month",
"resets_at": 1745193600000
}
},
"premium-support": {
"unlimited": true
}
}
}
```
</Expandable>
## Feature Types and Balances
When you create a feature, you define its type. This affects how balances behave.
### Consumable Features
Features that are used up and can be replenished. Examples: credits, API requests, AI tokens.
Consumable features support **reset intervals** - the balance resets to the granted amount on a regular schedule.
Available reset intervals:
- `hour`, `day`, `week`, `month`, `quarter`, `semi_annual`, `year`
- `one_off` - the balance never resets (useful for one-time grants or top-ups)
### Non-Consumable Features
Features with persistent, continuous usage. Examples: seats, workspaces, storage.
Non-consumable features don't reset. Instead, they support **proration** when quantities change mid-billing cycle.
### Credit Systems
A [credit system](/documentation/pricing/credits) lets multiple features draw from a single shared balance.
When you check or track usage, you use the underlying feature ID (e.g., `premium_message`), but the balance is deducted from the credit system.
When you track usage for a feature in a credit system, Autumn:
1. Looks up the credit cost for that feature that you defined
2. Multiplies the usage value by the credit cost
3. Deducts from the credit system balance
For example, if you have a credit system with a credit cost of 2 credits per API request, and a customer uses 10 API requests, Autumn will deduct 20 credits from the balance.
## Positive and Negative Balances
A balance can be positive or negative:
- **Positive balance**: Customer has unused allowance remaining
- **Negative balance**: Customer has used more than their allowance (only possible if [overage](/documentation/pricing/plan-features#priced-features) is enabled)
<Note>
Features can only have a negative balance if they have a usage-based price that allows overage. Otherwise, tracking stops when balance reaches 0.
</Note>

View File

@@ -0,0 +1,168 @@
---
title: "Accepting Payments"
description: "How to handle the Stripe payment flow with Autumn"
---
Accepting payments is a two-step process:
1. **`checkout`** - Gets checkout information (either a Stripe Checkout URL or purchase confirmation data)
2. **`attach`** - Enables the product and charges a saved payment method
```mermaid
graph TD
A(("checkout")) -->|"url"| B["Stripe Checkout"]
A -->|"preview"| C["Display preview info"]
B --> D["Payment complete"]
D --> E["Plan enabled"]
C --> F["User confirms"]
F --> G(("attach"))
G --> D
```
## Checkout
Call `checkout` when a customer wants to purchase a product. If no payment method is on file, a Stripe Checkout URL is returned. Otherwise, preview data (prices, proration info) is returned for the customer to confirm.
<CodeGroup>
```tsx React
import { useCustomer, CheckoutDialog } from "autumn-js/react";
const { checkout } = useCustomer();
<Button onClick={() => checkout({ productId: "pro", dialog: CheckoutDialog })} />
```
```typescript Node.js
import { Autumn } from "autumn-js";
const autumn = new Autumn({ secretKey: "am_sk_..." });
const { data } = await autumn.checkout({
customer_id: "user_123",
product_id: "pro",
});
if (data.url) {
// Redirect to Stripe Checkout
} else {
// Show confirmation UI with preview data
}
```
```python Python
from autumn import Autumn
autumn = Autumn("am_sk_...")
response = await autumn.checkout(
customer_id="user_123",
product_id="pro",
)
if response.url:
# Redirect to Stripe Checkout
else:
# Show confirmation UI with preview data
```
```bash cURL
curl -X POST 'https://api.useautumn.com/v1/checkout' \
-H 'Authorization: Bearer am_sk_...' \
-H 'Content-Type: application/json' \
-d '{
"customer_id": "user_123",
"product_id": "pro"
}'
```
</CodeGroup>
## Attach
If `checkout` returned preview data (no URL), call `attach` after the customer confirms to charge their saved payment method and enable the product.
<CodeGroup>
```tsx React
import { useCustomer } from "autumn-js/react";
const { attach } = useCustomer();
<Button onClick={() => attach({ productId: "pro" })} />
```
```typescript Node.js
const { data } = await autumn.attach({
customer_id: "user_123",
product_id: "pro",
});
```
```python Python
response = await autumn.attach(
customer_id="user_123",
product_id="pro",
)
```
```bash cURL
curl -X POST 'https://api.useautumn.com/v1/attach' \
-H 'Authorization: Bearer am_sk_...' \
-H 'Content-Type: application/json' \
-d '{
"customer_id": "user_123",
"product_id": "pro"
}'
```
</CodeGroup>
## 3DS and Payment Failures
When calling `attach`, the payment may require additional action. Autumn will return:
| Code | Description |
|------|-------------|
| `3ds_required` | Payment requires 3D Secure authentication |
| `payment_failed` | Payment was declined (e.g., insufficient funds) |
Both cases include an invoice URL. Direct the customer to this URL to complete authentication or update their payment method. Once resolved, the payment processes and the subscription activates.
## Past Due Subscriptions
If a recurring payment fails (e.g., card expired), the subscription status becomes `past_due`. To resolve this:
1. Direct the customer to the [billing portal](/api-reference/customers/open-billing-portal) to update their payment method
2. Once updated, Stripe will automatically retry the failed invoice
<CodeGroup>
```tsx React
import { useCustomer } from "autumn-js/react";
const { openBillingPortal } = useCustomer();
<Button onClick={() => openBillingPortal({ returnUrl: window.location.href })} />
```
```typescript Node.js
const { data } = await autumn.customers.billingPortal("user_123", {
return_url: "https://your-app.com/billing",
});
// Redirect to data.url
```
```python Python
response = await autumn.customers.billing_portal(
"user_123",
return_url="https://your-app.com/billing",
)
# Redirect to response.url
```
</CodeGroup>
<Note>
If you'd like to block feature access when a subscription is `past_due`, please contact us. We can enable a configuration flag to do this for you.
</Note>

View File

@@ -0,0 +1,103 @@
---
title: "Managing Subscriptions"
description: "Handle upgrades, downgrades, and cancellations"
---
## Upgrades
Upgrades happen when you attach a product with a higher price than the customer's current product. Use the same `attach` method—Autumn handles the rest.
<Warning>
If a payment method exists, attaching the product will immediately charge the customer. If upgrading from a free to a paid product, a checkout URL is generated instead.
</Warning>
**Pricing behavior:**
- **Fixed prices** are prorated based on time remaining in the billing period
- **Usage-based prices** bill outstanding usage at the old rate immediately, then apply the new rate going forward
## Downgrades
Downgrades happen when you attach a product with a lower price. Unlike upgrades, downgrades are **scheduled** to take effect at the end of the current billing period.
The new product will have status `scheduled` until it activates. Customers can cancel a scheduled downgrade by re-attaching their current product.
<Note>
If you've set a [`group`](/documentation/pricing/plans#plan-properties) when creating products, upgrades and downgrades only apply between products in the same group. Attaching a product from a different group adds it alongside the existing product.
</Note>
## Cancellations
Cancel a subscription using the `cancel` method. By default, cancellations take effect at the end of the billing period.
<CodeGroup>
```tsx React
import { useCustomer } from "autumn-js/react";
const { cancel } = useCustomer();
// Cancel at end of billing period
await cancel({ productId: "pro" });
// Cancel immediately
await cancel({ productId: "pro", cancelImmediately: true });
```
```typescript Node.js
import { Autumn } from "autumn-js";
const autumn = new Autumn({ secretKey: "am_sk_..." });
// Cancel at end of billing period
await autumn.cancel({
customer_id: "user_123",
product_id: "pro",
});
// Cancel immediately
await autumn.cancel({
customer_id: "user_123",
product_id: "pro",
cancel_immediately: true,
});
```
```bash cURL
# Cancel at end of billing period
curl -X POST 'https://api.useautumn.com/v1/cancel' \
-H 'Authorization: Bearer am_sk_...' \
-H 'Content-Type: application/json' \
-d '{
"customer_id": "user_123",
"product_id": "pro"
}'
# Cancel immediately
curl -X POST 'https://api.useautumn.com/v1/cancel' \
-H 'Authorization: Bearer am_sk_...' \
-H 'Content-Type: application/json' \
-d '{
"customer_id": "user_123",
"product_id": "pro",
"cancel_immediately": true
}'
```
</CodeGroup>
If you have a default product (with `auto-enable` set), it will be activated after the cancellation takes effect.
## Usage reset behavior
When a new product is enabled, you can control what happens to existing feature usage with the `reset_usage_when_enabled` property on the product item:
- `true`: Usage resets to 0 (typical for consumable features like credits)
- `false`: Usage carries over to the new product (typical for continuous features like seats)
<Info>
**Example:** A customer on Free has used 20 of their 100 credits. They upgrade to Pro which includes 500 credits.
- If `reset_usage_when_enabled = true`: They get 500 credits
- If `reset_usage_when_enabled = false`: They get 480 credits (500 - 20 used)
</Info>

View File

@@ -0,0 +1,36 @@
---
title: "Subscriptions"
description: "How Autumn manages customer subscriptions"
---
Autumn uses Stripe subscriptions under the hood to handle recurring billing. When you attach a plan to a customer, Autumn creates the Stripe subscription and provisions feature balances automatically.
```mermaid
flowchart LR
P[Plan] -->|attach| C[Customer]
C -->|creates| S[Stripe Subscription]
S -->|provisions| B[Balances]
```
When a subscription is created, Autumn provisions [balances](/documentation/customers/balances) for each feature in the plan. Balances determine what the customer can access and track how much they've used. For example, a Pro plan might grant 1,000 API requests per month—this becomes a balance that decrements as the customer uses your product.
Balances can also be created for [credit systems](/documentation/pricing/credits) (eg, $10 credits per month) and boolean toggle features (eg, access to a premium analytics dashboard).
## Subscription statuses
| Status | Description |
|--------|-------------|
| `active` | Subscription is in good standing |
| `trialing` | Customer is in a free trial period |
| `past_due` | Payment failed, subscription needs attention |
| `scheduled` | Product will activate at end of current billing period |
| `expired` | Subscription has ended |
<CardGroup cols={2}>
<Card title="Accepting Payments" icon="credit-card" href="/documentation/subscriptions/accepting-payments">
Learn about the checkout and payment flow
</Card>
<Card title="Managing Subscriptions" icon="sliders" href="/documentation/subscriptions/managing-subscriptions">
Handle upgrades, downgrades and cancellations
</Card>
</CardGroup>

View File

@@ -0,0 +1,70 @@
---
title: "Vercel Marketplace"
description: "Set up the Vercel Marketplace integration in Autumn"
---
When you use Autumn, you can also add your product to [Vercel's Marketplace](https://vercel.com/marketplace) without any additional code. Follow these steps to connect the Autumn partner API and webhooks to Vercel.
<Note>
This is currently in beta, please reach out to us on [Discord](https://discord.gg/STqxY92zuS) or email us at hey@useautumn.com to get access.
</Note>
<Steps>
<Step>
### Step 1: Gather integration credentials and IDs
In your Vercel Integration Console, open your integration entry.
- Copy the **Client Integration ID**.
- Copy the **Client Integration Secret**.
In Stripe:
- Open **Settings > Custom payment methods**.
- Create a custom payment method named **Vercel Marketplace**.
- Upload the Vercel logo.
- Copy the resulting **Custom Payment Method ID**.
In the Autumn Dashboard:
- Open **Developer > Vercel Webhook**.
- Add a new endpoint.
- Set the endpoint URL to your production API endpoint plus `/autumn/webhooks/vercel`.
- Confirm the router path is current before saving.
</Step>
<Step>
### Step 2: Configure values in Autumn
In the Autumn Dashboard, open **Developer > Vercel** and set:
- `Client Integration ID`
- `Client Integration Secret`
- `Custom Payment Method ID`
Also save the **Base URL** shown in this section.
</Step>
<Step>
### Step 3: Configure values in Vercel
In the Vercel Integration Console, paste the Autumn **Base URL** into:
- **Partner API Base URL**
- **Webhooks URL**
This ensures Vercel can call Autumn when onboarding users and when key lifecycle events occur.
</Step>
<Step>
### Step 4: Validate the webhook
Confirm webhook delivery in both systems:
- Trigger a test event flow in Vercel.
- Verify Vercel receives callback requests for **key create/delete** events.
- Verify Autumn logs/receives the payload and updates API keys as expected.
If events are not delivered, confirm the exact webhook route in your deployment (for example `.../autumn/webhooks/vercel`) and update both sides if it has changed.
</Step>
</Steps>

View File

@@ -0,0 +1,88 @@
---
title: "Migrating to Autumn"
description: "How to migrate your existing Stripe customers to Autumn"
---
It's easy to move your existing customers to Autumn. The Autumn team will help you move your subscriptions and purchases over without any disruption. The main reasons teams migrate are:
- **Speed** - Team-based billing, multi-interval usage limits, auto-topups, timeseries charts: all handled by Autumn out of the box.
- **Flexibility** — Plan versioning, custom deals, and pricing changes without code deploys
- **Reliability** — No webhook edge cases, race conditions, or state sync issues to debug
## Migration Steps
<Steps>
<Step>
### Replace your existing billing code with Autumn
Start by integrating Autumn in your development environment. Replace your existing Stripe billing logic with Autumn's SDK:
- Set up your pricing plans in the [Autumn dashboard](https://app.useautumn.com)
- Install the Autumn SDK and configure your API keys
- Replace Stripe checkout, subscription management, and usage tracking with Autumn equivalents
See our [setup guides](/documentation/getting-started/setup/react) for detailed integration instructions.
</Step>
<Step>
### Link your production Stripe account
Connect your existing Stripe account to Autumn in your production environment. This gives us access to your active subscriptions so we can link them during migration.
</Step>
<Step>
### Prepare your customer mapping CSV
When you're ready to move to production, prepare a CSV file with the following columns:
| Column | Description |
|--------|-------------|
| `autumn_id` | The customer ID you'll use in Autumn (typically your internal user/org ID from auth) |
| `stripe_id` | The customer's existing Stripe customer ID (e.g., `cus_xxx`) |
| `plan` | The Autumn product ID the customer should be on |
You can also optionally include user's names and emails as separate columns.
**Example CSV:**
```csv
autumn_id,stripe_id,plan
user_123,cus_ABC123,pro
user_456,cus_DEF456,enterprise
user_789,cus_GHI789,starter
```
</Step>
<Step>
### Submit your CSV
Send your CSV to the Autumn team via the [Discord](https://discord.gg/STqxY92zuS) support channel or email at hey@useautumn.com. We'll import the data into your production account within 8 hours.
We will reuse your existing Stripe products and subscriptions — **there will be no change or disruption to your customers' billing**. We're simply linking what's already there so Autumn can manage it going forward. We'll also make sure **all your active subscriptions and purchases are accounted for**, in case customers made payments after you exported your CSV.
</Step>
<Step>
### Deploy your Autumn integration
Once the import is complete, you can deploy your Autumn integration to production. Your existing customers will be seamlessly linked to their Stripe subscriptions through Autumn.
</Step>
</Steps>
<Note>
**Usage balances will reset mid-cycle**
With this migration method, customers' usage balances will be reset when they're imported. This means they may get some extra usage during their current billing cycle.
If preserving exact usage counts is critical for your business, reach out to us and we can work with you on a rolling deploy strategy.
</Note>
<Info>
**Forward deploy service**
If you're processing $1M+ ARR, we can handle the migration and deployment for you at no extra charge. We'll work directly with your engineering team to ensure a smooth transition.
Contact us on [Discord](https://discord.gg/STqxY92zuS) or at hey@useautumn.com to learn more.
</Info>

View File

@@ -0,0 +1,129 @@
---
title: "Webhooks"
description: "Receive real-time notifications when customer billing events occur"
---
With Autumn, you don't need webhooks for managing billing — subscription state, usage tracking, and access control are all synchronized automatically.
However, webhooks can still be useful for specific use cases where you want to trigger actions in your own systems.
<Note>
Webhooks are currently in beta. Please reach out to us on [Discord](https://discord.gg/STqxY92zuS) or email us at support@useautumn.com to enable webhooks for your account.
</Note>
## Use Cases
While Autumn handles billing complexity for you, webhooks are helpful for:
- **Sending activation emails** — Welcome new subscribers or notify users when their plan changes
- **Triggering workflows** — Start onboarding sequences, provision resources, or update CRM records
- **Syncing with external systems** — Keep your database, analytics, or other tools in sync with subscription changes
- **Deprovisioning access to services** — Shut off access to downstream services when a customer cancels their subscription
## Available Events
### customer.products.updated
Fired when a customer's product or plan changes. The `scenario` field indicates what type of change occurred.
| Scenario | Description |
|----------|-------------|
| `new` | Customer subscribed to a new product |
| `upgrade` | Customer upgraded to a higher-tier plan |
| `downgrade` | Customer downgraded to a lower-tier plan |
| `renew` | Subscription renewed for another billing period |
| `cancel` | Subscription was canceled |
| `expired` | Subscription has expired |
| `past_due` | Payment is past due |
| `scheduled` | A plan change has been scheduled |
**Example payload:**
```json expandable
{
"type": "customer.products.updated",
"data": {
"scenario": "new",
"customer": {
"id": "user_123",
"name": "John Doe",
"email": "john@example.com",
"balances": { ... },
"subscriptions": [ ... ]
},
"updated_product": {
"id": "pro_plan",
"name": "Pro Plan",
"features": [ ... ]
}
}
}
```
### customer.threshold_reached
Fired when a customer reaches a usage threshold for a feature. This is useful for notifying users before they hit hard limits.
| Threshold Type | Description |
|----------------|-------------|
| `limit_reached` | Customer has reached their usage limit |
| `allowance_used` | Customer has exhausted their allowance |
In most cases, these events will fire at the same time, as the included allowance is the same as the user's usage limit. However, you may have a feature with a different included allowance and a different "max purchase" limit.
Eg: 100 API calls included, then 0.1 per API call, with a maximum purchase limit of 1000 API calls.
**Example payload:**
```json expandable
{
"type": "customer.threshold_reached",
"data": {
"threshold_type": "limit_reached",
"customer": {
"id": "user_123",
"name": "John Doe",
"email": "john@example.com",
"balances": { ... }
},
"feature": {
"id": "api_calls",
"name": "API Calls",
"type": "metered"
}
}
}
```
## Setup
Once webhooks are enabled for your account, you can configure your webhook endpoints in the Autumn dashboard:
<Steps>
<Step title="Navigate to Developer Settings">
Go to the **Developer** section in your Autumn dashboard and select the **Webhooks** tab.
</Step>
<Step title="Add an Endpoint">
Click **Add Endpoint** and enter the URL where you want to receive webhook events.
</Step>
<Step title="Select Events">
Choose which events you want to subscribe to. You can select all events or specific ones.
</Step>
<Step title="Save and Test">
Save your endpoint configuration. You can use the **Send Test Event** button to verify your endpoint is receiving events correctly.
</Step>
</Steps>
## Webhook Security
Autumn uses [Svix](https://www.svix.com/) for reliable webhook delivery. Each webhook request includes signature headers that you can use to verify the request is genuinely from Autumn:
- `svix-id` — Unique message identifier
- `svix-timestamp` — Timestamp of when the message was sent
- `svix-signature` — Signature for verifying authenticity
You can use the [Svix libraries](https://docs.svix.com/receiving/verifying-payloads/how) to easily verify webhook signatures in your application.
## Retry Policy
If your endpoint returns an error or is unavailable, Autumn will automatically retry the webhook with exponential backoff. You can view delivery attempts and retry failed webhooks from the dashboard.

View File

@@ -1,19 +1,60 @@
---
title: Welcome to Autumn
sidebarTitle: Introduction
description: "Open-source billing infrastructure that manages webhooks, usage limits and credits."
description: "Open source, drop-in system of record for AI billing and monetization."
---
## What is Autumn?
Autumn handles your billing flows and makes sure your customers have the access to the right features and limits.
Autumn is an infrastructure layer between your application and Stripe. It acts as your source of truth for subscription status, usage metering and credit balances.
It sits between your server and Stripe billing, and acts as your managed database for subscription status, usage metering and credit balances.
Your app queries Autumn in real-time to check if a customer is allowed to do something (eg, send an AI message, access SSO, etc).
```mermaid actions={false}
flowchart TD
subgraph app["Your Application"]
A["Frontend App"]
B["Backend Server"]
end
subgraph autumn["Autumn"]
C["Autumn Server"]
D["Dashboard or CLI"]
E["Database & Cache"]
end
F["Stripe"]
A -- "Autumn hooks (optional)" --> B
B -- "Balance checks + usage tracking" --> C
C -- "Customer state" --> E
C -- "Payments" --> F
F -- "Webhooks" --> C
D -- "Configure Pricing" --> C
```
## Why use Autumn?
AI made pricing and billing significantly harder for engineers to build and maintain. For reference, OpenAI wrote a [blog post](https://openai.com/index/beyond-rate-limits/) about the system they built in-house. Some of the things you will need to build and maintain are:
| Feature | Requirements |
|-----------------------|--------------------------------------------------------------------------------------------------|
| Subscription logic | Checkouts, prorated upgrades, scheduled downgrades, add-ons, trials. 10+ webhook cases to handle. |
| Credit system | Monthly limits, rollovers, promotional grants with exipry, waterfall deduction rules, real-time enforcement |
| Spend controls | Auto top ups, spend caps, per-seat allowances, usage analytics, observability |
| Enterprise plans | Tiered pricing, custom credit grants, pilots, expansion logic |
| Edge cases | Plan switching, failed payments, 3DS, race conditions, refunds |
At some point you or your GTM team will want to change your pricing, and you will need to rebuild everything.
Autumn offloads all this logic out of your codebase. After you set it up, everything about your pricing can be managed through our dashboard.
It gives you easier setup, saves months of engineering time, more flexibility and more reliability.
## Core concepts
1000s of founders and fast-growing startups use Autumn to make billing easier and more reliable. No webhooks needed!
## How it works
<Steps>
<Step title="Model your pricing in Autumn">
@@ -65,7 +106,6 @@ This gives you flexibility to make pricing changes, or define custom plans for i
## What Autumn is not
- **A Stripe billing replacement**: although you don't need to deal with Stripe's APIs, you are still using (and paying for) Stripe's subscriptions, payments and invoicing. You bring your own Stripe account and are never "locked in" to our system.
- **For fully sales-led companies**: Autumn is designed to be used by product-led, or hybrid product-sales teams with self-serve billing. If your customers only pay via custom invoices, Autumn is probably not for you yet.