Autumn Integration
Autumn fits apps that want product-led billing without building every plan, entitlement, and usage event by hand.
Install from the CLI
farm add integration autumn --ui
Config-first setup
src/lib/integrations.ts
import { autumn } from "@farmjs/integrations/autumn";export const integrations = { billing: autumn({ secretKey: process.env.AUTUMN_SECRET_KEY, webhookSecret: process.env.AUTUMN_WEBHOOK_SECRET, }),};
Usage
const checkout = await api.billing.checkout.post({ body: { productId: "pro", customerId: user.id, successPath: "/dashboard", },});
Storage-aware billing
The integration can persist customer, plan, entitlement, and usage snapshots through ctx.args.db, so the app keeps the same Farm integration surface even when the backing storage client changes.
What Autumn adds
| Area | Details |
|---|---|
| Products | Public products for pricing pages. |
| Status | Current plan, subscription, trial, features, limits, and entitlements. |
| Checkout | Attach an Autumn product and redirect users when payment or confirmation is required. |
| Portal | Open the customer portal from a typed caller. |
| Usage | Meter usage, report usage, check balance, and read current charges. |
| Webhooks | Verify Autumn events and keep local billing state in sync. |
Common callers
const products = await api.billing.products.get();const status = await api.billing.status.get();const allowed = await api.billing.check.post({ body: { key: "ai-generations", amount: 1, },});
Checkout flow
const checkout = await api.billing.checkout.post({ body: { productId: "pro", successPath: "/dashboard", metadata: { source: "pricing", }, },});if (checkout.data?.redirectTo) { window.location.href = checkout.data.redirectTo;}
Owner and entitlements
Autumn needs a billing owner when it checks or attaches customer state. Use the owner resolver to connect Farm auth/session data with Autumn customers.
autumn({ secretKey: process.env.AUTUMN_SECRET_KEY, billing: { async resolveOwner(ctx) { const organizationId = ctx.req.get<string>("organization.id"); return organizationId ? { id: organizationId, kind: "organization", email: ctx.req.get<string>("user.email") ?? null, } : null; }, },});
Production notes
- Set
AUTUMN_SECRET_KEY,AUTUMN_WEBHOOK_SECRET, andAPP_BASE_URL. - Keep Farm product IDs separate from provider IDs when you want a stable app contract.
- Use
checkbefore expensive operations andreportUsageafter successful work. - Treat webhooks as the source of truth for subscription state.
- Test free-plan reads, checkout redirects, portal redirects, usage limits, and webhook sync.