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
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.tsin the project root. If it doesn't exist, runnpx atmn initto log in and generate the file (this saves your API key and syncs your config). Then refer toautumn.config.tsfor your product and feature IDs.
Before making changes, detect:
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
Before writing any integration code, present a short plan to the user covering:
Ask the user to read, edit, and confirm the plan before proceeding. Do NOT start coding until the user approves.
Use this path if there's a React frontend with a Node.js backend.
Use the package manager already installed (npm, yarn, pnpm, bun):
npm install autumn-js
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.
// app/api/autumn/[...all]/route.ts
import { autumnHandler } from "autumn-js/next";
export const { GET, POST } = autumnHandler({
identify: async (request) => {
// Get user/org from your auth provider
const session = await auth.api.getSession({ headers: request.headers });
return {
customerId: session?.user.id, // or session?.org.id for B2B
customerData: {
name: session?.user.name,
email: session?.user.email,
},
};
},
});
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, // or session?.org.id for B2B
customerData: { name: session?.user.name, email: session?.user.email },
};
},
}));
For any framework not listed above, use the generic handler:
import { autumnHandler } from "autumn-js/backend";
// Mount this handler onto the /api/autumn/* path in your 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" },
});
};
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}>
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.
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:
Use this path if there's no React frontend, or you prefer server-side only.
Node.js:
npm install autumn-js
Python:
pip install autumn-sdk
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')
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: "[email protected]",
});
Python:
customer = await autumn.customers.get_or_create(
customer_id="user_or_org_id_from_auth",
name="John Doe",
email="[email protected]",
)
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": "[email protected]"}'
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.
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",
)
# Redirect to response.payment_url
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:
After setup, report to the user:
Note: Your Autumn configuration is in autumn.config.ts in your project root.
Documentation: https://docs.useautumn.com/llms.txt