# 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 (
Plan: {customer?.products[0]?.name}
Messages: {messagesFeature?.balance} / {messagesFeature?.included_usage}