# Autumn API Documentation Autumn is a pricing and billing database that integrates with Stripe to manage customer subscriptions, feature access, and usage metering for SaaS and AI applications. It acts as a single source of truth for pricing plans, subscription states, feature permissions, and usage tracking, eliminating the need to build complex billing infrastructure yourself. By handling Stripe webhooks, enforcing access limits, and providing drop-in UI components, Autumn enables developers to implement sophisticated pricing models with minimal code while maintaining the flexibility to make pricing changes without redeploying their application. This documentation provides comprehensive code examples for all core API endpoints and SDK functions. Each example demonstrates real-world usage patterns including authentication, error handling, and expected responses, enabling quick integration into your Node.js or React application. ## Check Permissions Verifies if a customer has access to a feature or product and optionally tracks usage in a single request. ```typescript import { Autumn as autumn } from 'autumn-js'; // Basic feature access check const response = await autumn.check({ customer_id: 'user_123', feature_id: 'messages' }); if (response.data.allowed) { console.log('Customer has access'); console.log(`Balance: ${response.data.balance.balance}`); } else { console.log('Access denied:', response.data.code); } // Check with required balance threshold const checkWithBalance = await autumn.check({ customer_id: 'user_123', feature_id: 'messages', required_balance: 12 }); // Check and track usage simultaneously const checkAndTrack = await autumn.check({ customer_id: 'user_123', feature_id: 'messages', required_balance: 1, send_event: true // Deducts from balance }); // Include preview data for paywalls const withPreview = await autumn.check({ customer_id: 'user_123', feature_id: 'messages', with_preview: true }); if (!withPreview.data.allowed && withPreview.data.feature_preview) { console.log('Show paywall:', withPreview.data.feature_preview.message); console.log('Upgrade to:', withPreview.data.feature_preview.upgrade_product_id); } ``` ```bash curl -X POST 'https://api.useautumn.com/v1/check' \ -H 'Authorization: Bearer am_sk_1234567890' \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "user_123", "feature_id": "messages", "required_balance": 1 }' # Response: # { # "customer_id": "user_123", # "feature_id": "messages", # "code": "feature_found", # "allowed": true, # "balance": { # "balance": 100, # "required_balance": 1 # } # } ``` ## Checkout Generates a Stripe Checkout URL for new purchases or returns upgrade/downgrade confirmation data for existing subscribers. ```typescript import { Autumn as autumn } from 'autumn-js'; // Basic checkout for new purchase const checkout = await autumn.checkout({ customer_id: 'user_123', product_id: 'pro' }); if (checkout.data.url) { // Redirect to Stripe Checkout window.location.href = checkout.data.url; } else if (checkout.data.lines) { // Customer already has payment method - show confirmation console.log('Proration lines:', checkout.data.lines); console.log('Due today:', checkout.data.total); console.log('Next cycle:', checkout.data.next_cycle); } // Checkout with success URL const withRedirect = await autumn.checkout({ customer_id: 'user_123', product_id: 'pro', success_url: 'https://app.example.com/success' }); // Checkout with prepaid options (seats, credits, etc) const withOptions = await autumn.checkout({ customer_id: 'user_123', product_id: 'enterprise', options: [ { feature_id: 'seats', quantity: 10 } ] }); // Create customer if not exists const withCustomerData = await autumn.checkout({ customer_id: 'user_456', product_id: 'pro', customer_data: { name: 'John Yeo', email: 'john@example.com' } }); ``` ```bash curl -X POST 'https://api.useautumn.com/v1/checkout' \ -H 'Authorization: Bearer am_sk_1234567890' \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "user_123", "product_id": "pro", "customer_data": { "name": "John Yeo", "email": "john@example.com" } }' # Response (new customer): # { # "url": "https://checkout.stripe.com/c/pay/cs_test_...", # "customer_id": "user_123", # "product": { # "id": "pro", # "name": "Pro", # "scenario": "new", # "items": [...] # } # } ``` ## Track Usage Records a usage event to deduct from a customer's feature balance or meter usage-based billing. ```typescript import { Autumn as autumn } from 'autumn-js'; // Track single event await autumn.track({ customer_id: 'user_123', feature_id: 'messages' }); // Track multiple units await autumn.track({ customer_id: 'user_123', feature_id: 'api_calls', value: 50 }); // Track with idempotency key await autumn.track({ customer_id: 'user_123', feature_id: 'messages', value: 1, idempotency_key: 'msg_abc123' }); // Track with custom properties await autumn.track({ customer_id: 'user_123', feature_id: 'compute_hours', value: 5, properties: { region: 'us-west', instance_type: 't2.micro' } }); // Track using event name (maps to multiple features) await autumn.track({ customer_id: 'user_123', event_name: 'mobile_messages', value: 12 }); // Track for entity (e.g., specific workspace) await autumn.track({ customer_id: 'org_789', feature_id: 'storage_gb', entity_id: 'workspace_1', value: 10 }); ``` ```bash curl -X POST 'https://api.useautumn.com/v1/track' \ -H 'Authorization: Bearer am_sk_1234567890' \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "user_123", "feature_id": "messages", "value": 3 }' # Response: # { # "id": "evt_2w5dzidzFD1cESxOGnn9frVuVcm", # "code": "event_received", # "customer_id": "user_123", # "feature_id": "messages" # } ``` ## Query Usage Data Retrieves historical usage data for features over a specified time range for analytics and dashboards. ```typescript import { Autumn as autumn } from 'autumn-js'; // Query single feature for 30 days const usage = await autumn.query({ customer_id: 'user_123', feature_id: 'messages', range: '30d' }); console.log('Usage over time:', usage.data.list); // [ // { period: 1672531200000, messages: 45 }, // { period: 1672617600000, messages: 32 }, // ... // ] // Query multiple features const multiUsage = await autumn.query({ customer_id: 'user_123', feature_id: ['credits', 'messages'], range: '7d' }); console.log('Multi-feature usage:', multiUsage.data.list); // [ // { period: 1672531200000, credits: 20, messages: 45 }, // { period: 1672617600000, credits: 15, messages: 32 }, // ... // ] // Query last billing cycle const cycleUsage = await autumn.query({ customer_id: 'user_123', feature_id: 'api_calls', range: 'last_cycle' }); // Query 24 hours const recentUsage = await autumn.query({ customer_id: 'user_123', feature_id: 'compute_hours', range: '24h' }); ``` ```bash curl -X POST 'https://api.useautumn.com/v1/query' \ -H 'Authorization: Bearer am_sk_1234567890' \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "user_123", "feature_id": ["credits", "messages"], "range": "7d" }' # Response: # { # "list": [ # { "period": 1672531200000, "credits": 20, "messages": 45 }, # { "period": 1672617600000, "credits": 15, "messages": 32 }, # { "period": 1672704000000, "credits": 30, "messages": 18 } # ] # } ``` ## Attach Product Attaches a product to a customer and processes payment if their card is on file, otherwise returns checkout URL. ```typescript import { Autumn as autumn } from 'autumn-js'; // Attach product (upgrade/downgrade) const attach = await autumn.attach({ customer_id: 'user_123', product_id: 'pro' }); if (attach.data.success) { console.log('Product attached:', attach.data.message); } else if (attach.data.checkout_url) { window.location.href = attach.data.checkout_url; } // Force checkout URL even with saved card const forceCheckout = await autumn.attach({ customer_id: 'user_123', product_id: 'pro', force_checkout: true }); // Attach with options const withSeats = await autumn.attach({ customer_id: 'org_456', product_id: 'enterprise', options: [ { feature_id: 'seats', quantity: 25 } ] }); // Attach to entity const entityAttach = await autumn.attach({ customer_id: 'org_789', product_id: 'workspace_plan', entity_id: 'workspace_2' }); // Attach with metadata const withMetadata = await autumn.attach({ customer_id: 'user_123', product_id: 'pro', metadata: { campaign: 'summer_promo', source: 'email' } }); ``` ```bash curl -X POST 'https://api.useautumn.com/v1/attach' \ -H 'Authorization: Bearer am_sk_1234567890' \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "user_123", "product_id": "pro" }' # Response: # { # "customer_id": "user_123", # "product_ids": ["pro"], # "code": "updated_product_successfully", # "message": "Successfully updated product" # } ``` ## Cancel Product Cancels a customer's subscription or product, either immediately or at the end of the billing period. ```typescript import { Autumn as autumn } from 'autumn-js'; // Cancel at end of billing period const cancel = await autumn.cancel({ customer_id: 'user_123', product_id: 'pro' }); console.log('Cancellation scheduled'); // Cancel immediately const cancelNow = await autumn.cancel({ customer_id: 'user_123', product_id: 'pro', cancel_immediately: true }); // Cancel for specific entity const cancelEntity = await autumn.cancel({ customer_id: 'org_456', product_id: 'workspace_plan', entity_id: 'workspace_3' }); ``` ```bash curl -X POST 'https://api.useautumn.com/v1/cancel' \ -H 'Authorization: Bearer am_sk_1234567890' \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "user_123", "product_id": "pro", "cancel_immediately": false }' # Response: # { # "message": "Product cancelled successfully" # } ``` ## Get Customer Retrieves complete customer information including subscriptions, features, balances, and optionally invoices or entities. ```typescript import { Autumn as autumn } from 'autumn-js'; // Get basic customer data const customer = await autumn.customers.get('user_123'); console.log('Customer:', customer.data.name); console.log('Products:', customer.data.products); console.log('Features:', customer.data.features); customer.data.features.forEach(feature => { console.log(`${feature.feature_id}: ${feature.balance}/${feature.included_usage}`); }); // Get with expanded data const withInvoices = await autumn.customers.get('user_123', { expand: ['invoices', 'payment_method'] }); console.log('Invoices:', withInvoices.data.invoices); // Get with all expansions const fullData = await autumn.customers.get('user_123', { expand: ['invoices', 'rewards', 'trials_used', 'entities', 'referrals', 'payment_method'] }); ``` ```bash curl 'https://api.useautumn.com/v1/customers/user_123' \ -H 'Authorization: Bearer am_sk_1234567890' # Response: # { # "autumn_id": "cus_2w5dzidzFD1cESxOGnn9frVuVcm", # "created_at": 1677649423000, # "env": "production", # "id": "user_123", # "name": "John Yeo", # "email": "john@example.com", # "stripe_id": "cus_abc123", # "products": [ # { # "id": "pro", # "name": "Pro Plan", # "status": "active", # "started_at": 1677649423000, # "current_period_end": 1680327823000 # } # ], # "features": [ # { # "feature_id": "messages", # "unlimited": false, # "balance": 80, # "usage": 20, # "included_usage": 100, # "next_reset_at": 1680327823000 # } # ] # } ``` ## Set Feature Balance Directly sets or adjusts feature balances for a customer, useful for granting credits or rewards. ```typescript import { Autumn as autumn } from 'autumn-js'; // Set balances for one or more features await autumn.customers.setBalances('user_123', { balances: [ { feature_id: 'credits', balance: 1000 }, { feature_id: 'messages', balance: 500 } ] }); // Grant bonus credits await autumn.customers.setBalances('user_123', { balances: [ { feature_id: 'api_calls', balance: 10000 } ] }); ``` ```bash curl -X POST 'https://api.useautumn.com/v1/customers/user_123/balances' \ -H 'Authorization: Bearer am_sk_1234567890' \ -H 'Content-Type: application/json' \ -d '{ "balances": [ { "feature_id": "credits", "balance": 1000 } ] }' ``` ## React Integration - useCustomer Hook Access customer data and perform operations from React components with automatic state synchronization. ```jsx import { useCustomer, CheckoutDialog } from 'autumn-js/react'; export default function BillingPage() { const { customer, check, checkout, refetch, openBillingPortal } = useCustomer(); // Display customer info const messagesFeature = customer?.features.messages; console.log(`${messagesFeature?.balance} messages remaining`); // Check feature access client-side const handleSendMessage = async () => { const { data } = check({ featureId: 'messages' }); if (!data?.allowed) { alert('Out of messages! Please upgrade.'); return; } // Send message server-side, then refetch await fetch('/api/send-message', { method: 'POST' }); await refetch(); }; // Handle checkout with dialog const handleUpgrade = async () => { await checkout({ productId: 'pro', dialog: CheckoutDialog }); }; return (

Welcome {customer?.name}

Plan: {customer?.products[0]?.name}

Messages: {messagesFeature?.balance} / {messagesFeature?.included_usage}

); } ``` ## Server-Side Integration - autumnHandler Set up backend endpoints to handle authentication and proxy Autumn API calls from your frontend. ```typescript // Next.js: app/api/autumn/[...all]/route.ts import { autumnHandler } from "autumn-js/next"; import { auth } from "@/lib/auth"; export const { GET, POST } = autumnHandler({ identify: async (request) => { const session = await auth.api.getSession({ headers: request.headers, }); if (!session?.user) { throw new Error('Unauthorized'); } return { customerId: session.user.id, customerData: { name: session.user.name, email: session.user.email, }, }; }, }); // Express: index.ts import { autumnHandler } from "autumn-js/express"; import express from 'express'; const app = express(); app.use(express.json()); app.use("/api/autumn", autumnHandler({ identify: async (req) => { const session = await auth.api.getSession({ headers: fromNodeHeaders(req.headers), }); if (!session?.user) { throw new Error('Unauthorized'); } return { customerId: session.user.id, customerData: { name: session.user.name, email: session.user.email, }, }; }, })); ``` ```jsx // Client setup: layout.tsx import { AutumnProvider } from "autumn-js/react"; export default function RootLayout({ children }) { return ( {children} ); } ``` ## Summary Autumn provides a complete billing infrastructure that integrates seamlessly with Stripe to handle subscription management, feature gating, and usage metering for SaaS applications. The core workflow consists of three functions: `checkout()` to handle payments, `check()` to verify feature access, and `track()` to record usage events. Additional functions like `query()` enable usage analytics, while `attach()` and `cancel()` provide programmatic subscription management. The SDK automatically creates customers, handles Stripe webhooks, and maintains a unified customer state accessible via the `useCustomer()` React hook or server-side `customers.get()` endpoint. Integration patterns vary by architecture: full-stack frameworks like Next.js use the `autumnHandler` to create authenticated API routes at `/api/autumn/*`, while separate backend/frontend setups use the handler on Express, Fastify, or Hono servers with the `AutumnProvider` component wrapping the React app. All access control should be enforced server-side using `autumn.check()` with the secret key, while client-side checks provide instant UI feedback without API calls. Pricing models are defined via the CLI config file or dashboard UI, enabling non-technical team members to modify pricing, add products, or adjust feature limits without code deployments.