Claude's Corner: Autumn, The Billing Layer AI Startups Actually Need

Autumn is the open-source layer that sits between Stripe and your AI application, handling credits, usage metering, and entitlements with three API calls. In production at Mintlify, Firecrawl, and T3.chat. Here is why it exists and how it works.

9 min read
Claude's Corner: Autumn, The Billing Layer AI Startups Actually Need

TL;DR

Autumn is open-source billing infrastructure for AI startups that sits between Stripe and your application, providing real-time entitlement checks, credit management, and usage metering via three API calls: attach(), check(), and track(). In production at Mintlify, Firecrawl, T3.chat, and other leading AI developer tools, it replaces the sprawling internal billing state machines that most AI startups waste weeks building from scratch.

4.2
F

Build difficulty

Every AI Startup Eventually Drowns in a Billing Spreadsheet

You've shipped the model. The embeddings are fast. The UI is clean. And then someone on the team asks: "How do we charge per token?" And then: "What happens when a user runs out of credits mid-request?" And then: "Do credits roll over?" And then you're three weeks into building a state machine that has nothing to do with your actual product.

Billing is the unsexy problem that kills AI products not with a bang but with a thousand Slack threads. The typical trajectory: duct-tape Stripe webhooks, write a credits column in Postgres, realize Stripe's API is too slow to call inline during an LLM request, build a local cache, debug sync issues at 2am, ship it anyway, watch it break when a user upgrades mid-month. Congratulations, you've reinvented a billing state machine, badly, on a deadline, without knowing that's what you were doing.

Related startups

Autumn (useautumn.com, YC W2026) is the answer to a question that every AI founder eventually asks out loud: "Why does nobody make a proper billing layer for this?" Turns out, two people did. One came from building payments infrastructure at Checkout.com. The other spent six years building developer tools. They saw the same problem from two angles and built the thing nobody wanted to build twice.

The result is open-source, in production at companies you definitely use, and designed around three API calls that replace an entire internal billing system.

What Autumn Actually Does

Autumn bills itself as billing infrastructure for AI startups. That's underselling it a little. More precisely: it's a real-time source of truth for customer billing state that sits between Stripe and your application. Stripe handles money movement. Autumn handles everything your app actually needs to know, who's on what plan, how many credits they have left, whether they're allowed to use a specific feature, and what happens when they try to do something they can't afford.

The product is structured around three core functions:

  • autumn.attach(), Manages all purchase flows. New subscriptions, upgrades, downgrades, add-ons. Returns a Stripe Checkout URL or executes the change inline. One function replaces what would otherwise be a rats' nest of Stripe session logic and webhook handlers.
  • autumn.check(), The runtime entitlement check. Call it during request handling to ask: can this customer do this thing right now? It checks their plan tier, remaining credits, feature flags, and usage limits. Answers fast, from local state, not from Stripe.
  • autumn.track(), Usage recording. Call it after an LLM response to decrement tokens, record metered usage, handle monthly rollovers. The billing ledger updates without you touching it.

The target customer is obvious: any AI startup charging for inference, API usage, or token consumption. That's most of them right now. And the named customers in production aren't nobodies, Mintlify, Firecrawl, Mastra, Browser Use, T3.chat. These are the companies that developers in AI circles actually pay attention to. If you've used an AI developer tool in the last six months, there's a reasonable chance Autumn was somewhere in the billing path.

Business model is the classic open-source playbook: Apache 2.0 license, self-host for free, pay for managed hosting. The GitHub repo sits at 2,600 stars and 224 forks. That's not just a vanity metric, it's proof that the developer community recognized the gap before the product even launched commercially.

The pricing models it supports read like a checklist of everything Stripe alone can't do cleanly: usage-based billing, credit systems with grants and rollovers and expiration dates, subscription tiers, seat-based pricing, feature gating, custom enterprise overrides. Yes, all of that.

How the Architecture Actually Works

The stack is TypeScript-first, 84.5% of the codebase, with Python making up another 7.4%, likely for tooling and integrations. The runtime is Bun, which is the right call for a latency-sensitive infrastructure component. PostgreSQL is the backing store. The monorepo is managed by Turbo. Docker for self-hosting. Stripe for payment processing, Resend for transactional email.

The core architectural insight is about where billing state lives. Stripe is authoritative for payment history, it knows what someone paid, when, and how much. But Stripe is not the right system to query in the middle of an LLM request. A Stripe API call adds 150, 300ms of latency, requires a network hop, and doesn't natively understand concepts like "this user has 10,000 tokens remaining from a rollover credit grant they got in February."

Autumn solves this by maintaining its own billing state in PostgreSQL, synchronized with Stripe via webhooks. When your app calls autumn.check(), it's hitting a local database query, single-digit milliseconds, no external dependency, no Stripe rate limits. The webhook layer handles reconciliation. The result is that entitlement checks become cheap enough to run inline, on every request, without thinking about it.

A realistic usage pattern looks like this:

// At request time, check before burning compute
const allowed = await autumn.check({
  customerId: user.id,
  featureId: "ai_generations",
});

if (!allowed.ok) {
  return res.status(402).json({ error: "Credit limit reached" });
}

// ... run the LLM call ...

// After response, record what was consumed
await autumn.track({
  customerId: user.id,
  featureId: "ai_generations",
  value: tokensUsed,
});

That's it. No Stripe API calls in the hot path. No manual credit decrement logic. No custom rollover code. Autumn handles the state transition, debiting credits, recording metered usage, triggering limit events, asynchronously, after you've already returned a response to the user.

The monorepo structure with Turbo suggests a product that already has multiple surfaces, likely a dashboard, an API server, a webhook processor, and SDK packages, all maintained in a single coherent codebase. That's the right architecture for infrastructure tooling that needs to ship updates across layers simultaneously without breaking customer integrations.

Self-hosting via Docker means a team that cares about data residency or enterprise procurement can run the whole thing themselves. That's not an afterthought, it's what makes the open-source positioning credible to companies that can't send billing data to a third-party SaaS.

Difficulty Score

DimensionScoreNotes
ML / AI1 / 10No ML in the product itself. The AI complexity lives in the customers' stacks, not Autumn's.
Data6 / 10Getting billing state sync right, especially across webhook failures, retries, and edge cases, is genuinely hard data engineering.
Backend7 / 10Payment systems are unforgiving. Correctness at the money layer, idempotency, and low-latency entitlement checks at scale are real backend challenges.
Frontend3 / 10Dashboard exists but isn't the product. Developers are the users; they care about the API, not the UI.
DevOps4 / 10Docker self-hosting, Turbo monorepo, Bun runtime, clean setup, but not a distributed systems nightmare.

The Moat, Such As It Is

Let's be honest about what's easy to replicate here: the code. Apache 2.0 license, public GitHub, 2,600 people have already read it. You could fork Autumn tomorrow and stand up a competitor next week. The technical barrier is not the moat.

The actual moat is in three places, none of them obvious from the outside.

First: being the source of truth creates lock-in that compounds over time. Once Autumn is the system that knows your customers' credit balances, plan states, and usage history, ripping it out means migrating months of billing state with zero tolerance for error. Billing migrations are the kind of project that gets scoped, descoped, rescheduled, and eventually never shipped. Companies don't swap out their billing state machine any more than they swap out their payment processor. Autumn doesn't need to be dramatically better than alternatives, it just needs to be good enough and already embedded.

Second: the customer list is a reference sale machine. Mintlify, Firecrawl, T3.chat, these aren't random companies. They're the companies that every AI developer follows, reads about, and talks to at YC events. When the next AI startup founder asks "how are you handling billing," and four engineers from four different companies say "Autumn," that's more valuable than any marketing budget. Enterprise sales calls at category-defining companies take years to build. Autumn has them already, as a W2026 batch company.

Third: the integration surface grows with the ecosystem. Every pricing model, every Stripe feature, every edge case in subscription logic that gets added to Autumn is one less thing a customer has to build. The product gets more defensible as it handles more of the weird cases, annual subscriptions with monthly rollover credits, seat-based plans with per-seat usage overages, trial periods that convert to different tiers. Each solved edge case is a tiny moat.

What's genuinely hard to replicate is the founders' payment infrastructure background. Ayush Rodrigues came from Checkout.com, a Stripe competitor, which means he's seen payment edge cases that most engineers never encounter. That domain knowledge is baked into the product's correctness guarantees in ways that are invisible until something goes wrong and Autumn handles it gracefully while a competitor's implementation silently corrupts state.

The open-source paradox works in Autumn's favor: the code being free is actually a feature for credibility and distribution, not a vulnerability. Developers trust tools they can read. The revenue model doesn't depend on hiding the implementation.

Replicability Score

22 / 100

The codebase is public and the architecture is understandable, which makes a fork trivially easy, but being embedded as the billing state layer inside production systems at companies like Mintlify and Firecrawl means the hard part was never the code. Building the same reference customer base, trust, and payments domain expertise from scratch would take years, not sprints.

Autumn isn't trying to replace Stripe. It's trying to be the layer that makes Stripe usable for the specific, weird, real-time, inline entitlement-checking, credit-decrementing, rollover-handling requirements of AI products. That's a narrower problem than general payments infrastructure, and a much better place to be positioned, because it's the exact problem every AI startup hits the moment they try to monetize.

The unsexy billing problem turns out to be the one that most reliably needs a purpose-built solution. Autumn got there first, built it in the open, and got the right companies using it before the space gets crowded. That's a good start.

© 2026 StartupHub.ai. All rights reserved. Do not enter, scrape, copy, reproduce, or republish this article in whole or in part. Use as input to AI training, fine-tuning, retrieval-augmented generation, or any machine-learning system is prohibited without written license. Substantially-similar derivative works will be pursued to the fullest extent of applicable copyright, database, and computer-misuse laws. See our terms.

Build This Startup with Claude Code

Complete replication guide — install as a slash command or rules file

# Building an Autumn Clone: A 7-Step Developer Guide\n\nA billing layer that sits between Stripe and your application, acting as the real-time source of truth for customer entitlements, usage, and credits.\n\n## Step 1: Database Schema\n\nDesign the PostgreSQL schema with tables: customers (mirrors Stripe customers 1:1), plans (maps to Stripe Products), features (gatable capabilities with type: boolean|metered|limit), plan_entitlements (what each plan includes, with credit_amount, rollover_cap, expires_in_days), subscriptions (synced from Stripe webhooks, with status active|past_due|canceled|trialing|paused|incomplete), credit_ledger (immutable double-entry ledger with type: grant|usage|rollover|expiration|adjustment, idempotency_key, expires_at), usage_events (raw firehose, append-only), webhook_events (idempotency log for Stripe events).\n\nKey insight: never UPDATE credit_ledger rows, only INSERT. The balance is always SUM(amount) WHERE expires_at > NOW().\n\n## Step 2: Stripe Integration & Webhook Handler\n\nSet up Stripe products/prices with autumn_plan_slug metadata. Webhook handler: insert event to webhook_events first (idempotency), then process. Handle: customer.subscription.created/updated (upsert local subscription row), customer.subscription.deleted (mark canceled), invoice.paid (trigger credit grant), invoice.payment_failed (mark past_due). Never trust unsigned payloads, always use stripe.webhooks.constructEvent().\n\n## Step 3: The Check API\n\nSingle SQL query joining customers → subscriptions → plans → plan_entitlements → features → credit_ledger SUM. Returns: allowed (bool), plan, balance, limit, remaining, overage. The key: this query NEVER calls Stripe, it's a local Postgres read, < 5ms. For boolean features: check subscription status only. For metered: compare balance >= quantity. For hard limits: compare cumulative usage <= limit.\n\n## Step 4: The Track API\n\nAtomic Postgres transaction: (1) check idempotency_key in usage_events, (2) SELECT SUM(amount) FOR UPDATE to lock ledger rows, (3) INSERT usage_event, (4) INSERT credit_ledger debit (negative amount), (5) COMMIT. Fire async webhook on credit exhaustion (balance crosses zero). Never block track() response on webhook delivery.\n\n## Step 5: The Attach API\n\nTwo paths: (A) No active subscription → create Stripe Checkout Session with allow_promotion_codes: true, trial_period_days if applicable. (B) Active subscription → upgrades use proration_behavior: create_prorations + immediate switch; downgrades schedule for period end with proration_behavior: none. Immediately update local DB on upgrade, webhook will arrive later and be idempotent. Always ensure Stripe customer exists before any payment flow.\n\n## Step 6: Credit Rollovers & Expiration\n\nRun nightly (Bun.cron or pg_cron). Idempotency key: grant:{stripe_sub_id}:{period_start_date}. Per subscription, per metered feature: (1) SUM current non-expired balance, (2) INSERT expiration entry (negative amount zeroing balance), (3) calculate rollover = MIN(current_balance, credit_amount * rollover_cap), (4) INSERT rollover grant with expires_at, (5) INSERT new period grant. Use pg_advisory_xact_lock to prevent concurrent processing for same customer+feature.\n\n## Step 7: SDK & Deployment\n\nTypeScript SDK class with attach()/check()/track() methods, Bearer auth header, typed responses. Build with tsup for ESM+CJS. Dockerfile: oven/bun:1.1-alpine, frozen lockfile install, bun run db:migrate && bun run src/server.ts. docker-compose: api + postgres:16-alpine (with healthcheck) + stripe-cli (dev profile only). Required env: STRIPE_SECRET_KEY, WEBHOOK_SECRET, DATABASE_URL, AUTUMN_API_KEY. Test with stripe-cli forwarding webhooks to localhost.
claude-code-skills.md