| name | autumn-setup |
| description | Sets up Autumn billing integration: installs the SDK, creates a customer, and adds the payment flow.
Use this skill when the user wants to:
- Set up Autumn billing
- Create an Autumn customer
- Integrate Autumn into their app
- Add billing/entitlements with Autumn
- Configure Autumn SDK
- Add payment flow or checkout
|
Set up Autumn Billing
Autumn is a billing and entitlements layer over Stripe. This skill walks through installing the SDK, creating an Autumn customer, and wiring up the payment flow.
Before starting: Check for an autumn.config.ts in the project root. If it doesn't exist, run npx atmn init to log in and generate the file (this saves your API key and syncs your config). Then refer to autumn.config.ts for your product and feature IDs.
Step 1: Analyze the Codebase
Before making changes, detect:
- Language: TypeScript/JavaScript, Python, or other
- If TS/JS - Framework: Next.js, Hono, or other
- If TS/JS - React frontend?: Check for React in package.json
- Customer model: Look at the auth setup to determine whether customers map to individual users or organizations. Check for org/team/workspace models in the codebase.
If it's clear from the codebase (e.g., there's an org model and team-based auth), state your assumption. If it's ambiguous, ask the user:
Should Autumn customers be individual users, or organizations?
- Users (B2C): Each user has their own plan and limits
- Organizations (B2B): Plans and limits are shared across an org
Step 2: Create a Plan and Confirm
Before writing any integration code, present a short plan to the user covering:
- What stack/framework you detected
- Whether customers are users or orgs (and why you think so)
- Which path you're following (React fullstack vs backend-only)
- Which files you'll create or modify
- Where the handler / provider / customer creation will go
- Where the payment flow will be wired up
Ask the user to read, edit, and confirm the plan before proceeding. Do NOT start coding until the user approves.
Path A: React + Node.js (Fullstack TypeScript)
Use this path if there's a React frontend with a Node.js backend.
A1. Install the SDK
Use the package manager already installed (npm, yarn, pnpm, bun):
npm install autumn-js
A2. Mount the Handler (Server-Side)
This creates endpoints at /api/autumn/* that the React hooks will call. The identify function should return either the user ID or org ID from your auth provider, depending on how you're using Autumn.
Next.js (App Router)
import { autumnHandler } from "autumn-js/next";
export const { GET, POST } = autumnHandler({
identify: async (request) => {
const session = await auth.api.getSession({ headers: request.headers });
return {
customerId: session?.user.id,
customerData: {
name: session?.user.name,
email: session?.user.email,
},
};
},
});
Hono
import { autumnHandler } from "autumn-js/hono";
app.use("/api/autumn/*", autumnHandler({
identify: async (c) => {
const session = await auth.api.getSession({ headers: c.req.raw.headers });
return {
customerId: session?.user.id,
customerData: { name: session?.user.name, email: session?.user.email },
};
},
}));
Other Frameworks (Generic Handler)
For any framework not listed above, use the generic handler:
import { autumnHandler } from "autumn-js/backend";
const handleRequest = async (request) => {
const session = await auth.api.getSession({ headers: request.headers });
let body = null;
if (request.method !== "GET") {
body = await request.json();
}
const { statusCode, response } = await autumnHandler({
customerId: session?.user.id,
customerData: {
name: session?.user.name,
email: session?.user.email,
},
request: {
url: request.url,
method: request.method,
body: body,
},
});
return new Response(JSON.stringify(response), {
status: statusCode,
headers: { "Content-Type": "application/json" },
});
};
A3. Add the Provider (Client-Side)
Wrap your app with AutumnProvider:
import { AutumnProvider } from "autumn-js/react";
export default function RootLayout({ children }) {
return (
<AutumnProvider>
{children}
</AutumnProvider>
);
}
If your backend is on a different URL (e.g., Vite + separate server), pass backendUrl:
<AutumnProvider backendUrl={import.meta.env.VITE_BACKEND_URL}>
A4. Create a Customer
Add this hook to any component. It automatically creates an Autumn customer for new users and fetches existing customer state:
import { useCustomer } from "autumn-js/react";
const { data } = useCustomer();
console.log("Autumn customer:", data);
Autumn's customer ID is the same as your internal user or org ID from your auth provider. No need to store any extra IDs.
A5. Stripe Payment Flow
Call attach when the customer wants to purchase a plan. This returns a Stripe payment URL. Once they pay, Autumn grants access to the features defined in the plan.
import { useCustomer } from "autumn-js/react";
export default function PurchaseButton() {
const { attach } = useCustomer();
return (
<button
onClick={async () => {
await attach({
planId: "pro",
redirectMode: "always",
});
}}
>
Select Pro Plan
</button>
);
}
This handles all plan change scenarios (upgrades, downgrades, one-time topups, renewals, etc).
The redirectMode: "always" flag always returns a payment URL:
- New purchases redirect to Stripe Checkout to enter payment details
- Subsequent charges redirect to an Autumn hosted, one-click confirmation page
Path B: Backend Only (Node.js, Python, or Other)
Use this path if there's no React frontend, or you prefer server-side only.
B1. Install the SDK
Node.js:
npm install autumn-js
Python:
pip install autumn-sdk
B2. Initialize the Client
TypeScript/JavaScript:
import { Autumn } from "autumn-js";
const autumn = new Autumn({
secretKey: process.env.AUTUMN_SECRET_KEY,
});
Python:
from autumn_sdk import Autumn
autumn = Autumn('am_sk_test_xxx')
B3. Create a Customer
When the customer signs up, create an Autumn customer. Autumn will automatically enable any autoEnable plan (typically Free).
TypeScript:
const customer = await autumn.customers.getOrCreate({
customerId: "user_or_org_id_from_auth",
name: "John Doe",
email: "john@example.com",
});
Python:
customer = await autumn.customers.get_or_create(
customer_id="user_or_org_id_from_auth",
name="John Doe",
email="john@example.com",
)
cURL:
curl -X POST https://api.useautumn.com/v1/customers \
-H "Authorization: Bearer am_sk_test_xxx" \
-H "Content-Type: application/json" \
-d '{"customer_id": "user_or_org_id_from_auth", "name": "John Doe", "email": "john@example.com"}'
Autumn's customer ID is the same as your internal user or org ID from your auth provider. No need to store any extra IDs.
B4. Stripe Payment Flow
Call attach when the customer wants to purchase a plan. This returns a Stripe payment URL. Redirect the customer to complete payment.
TypeScript:
const response = await autumn.billing.attach({
customerId: "user_or_org_id_from_auth",
planId: "pro",
redirectMode: "always",
});
redirect(response.paymentUrl);
Python:
response = await autumn.billing.attach(
customer_id="user_or_org_id_from_auth",
plan_id="pro",
redirect_mode="always",
)
cURL:
curl -X POST 'https://api.useautumn.com/v1/attach' \
-H 'Authorization: Bearer am_sk_test_xxx' \
-H 'Content-Type: application/json' \
-d '{
"customer_id": "user_or_org_id_from_auth",
"plan_id": "pro",
"redirect_mode": "always"
}'
This handles all plan change scenarios (upgrades, downgrades, one-time topups, renewals, etc).
The redirectMode: "always" flag always returns a payment URL:
- New purchases redirect to Stripe Checkout to enter payment details
- Subsequent charges redirect to an Autumn hosted, one-click confirmation page
Verification
After setup, report to the user:
- What stack you detected
- Which path you followed
- What files you created/modified
- That the Autumn customer is logged in browser, and to check in the Autumn dashboard
Note: Your Autumn configuration is in autumn.config.ts in your project root.
Documentation: https://docs.useautumn.com/llms.txt