Creator
Billing

Plans & Limits

How to define billing plans and gate features based on plan limits.

Configuration

Plans are defined in config/billing.config.ts. This is the single source of truth for pricing, features, and limits. The pricing page reads plans from this config and renders them automatically.

Each plan includes an id, name, price, interval, Stripe/Lemon Squeezy IDs, a features list, and an optional limits object.

Helper functions

import { getPlanById, getPlanByPriceId, getPlanByVariantId, getPlanLimit }
  from "@/config/billing.config";
FunctionDescription
getPlanById("starter")Find plan by its config ID
getPlanByPriceId("price_...")Find plan by Stripe price ID
getPlanByVariantId("123456")Find plan by Lemon Squeezy variant ID
getPlanLimit("starter", "requestsPerDay", 0)Get a limit value with fallback

Feature gating

Add limits to your plan config:

{
  id: "starter",
  limits: {
    requestsPerDay: 100,
    canExport: false,
  },
}

Then gate features in your API routes:

import { requireLimit } from "@/lib/auth/subscription-guard";

const { authorized, response } = await requireLimit("requestsPerDay", currentCount);
if (!authorized) return response;

Or check a boolean feature flag:

import { getPlanLimit } from "@/config/billing.config";
import { getSubscriptionStatus } from "@/lib/auth/subscription-guard";

const { plan } = await getSubscriptionStatus();
const canExport = getPlanLimit(plan ?? "free", "canExport", false);

Use -1 for unlimited numeric limits.

Free users

Users without a subscription row in the database are implicitly on the free tier. The planId defaults to "free" when no subscription exists.

On this page

We use cookies to ensure you get the best experience on our website. For more information on how we use cookies, please see our cookie policy.