Charge for usage, without building a ledger.
Workspaces buy credit packs through Stripe or get credits with their plan, and your app spends them with one call that refuses to take the balance below zero. For allowances there are quotas: a per-plan limit, followed by either overage billing or a hard stop.
Your app is an organization in BuildBase. Your users sign in and work inside workspaces - one per team or customer.
You set up
In the console and the SDK
- Credit packs and their prices, in the console
- Credits included with a plan, if you want them
- One call where the paid work happens, like an AI generation
Your users get
Inside their workspace
- A credit balance on their workspace
- A store to buy more credits, through Stripe
- A clear 'not enough credits' message, never a surprise bill
Usage-based pricing without the ledger work
Balances, buckets, expiry and the Stripe purchase are handled. You call consume where the work happens.
Sell Credit Packs
Set how many credits a pack holds and its price in each currency. Users buy through Stripe from a ready-made store.
Spend Safely
One call takes credits and returns the new balance. A retry never charges twice, and the balance never goes below zero.
Credits With a Plan
Include credits with a plan, once or every month, topped up or reset at renewal.
Oldest Spent First
Credits closest to expiring are used first, and users can see what is about to run out.
A Full History
Every purchase, spend, grant and refund is recorded with the balance after it. You can grant or take back credits per workspace.
Usage Limits by Plan
Give each plan an allowance, like API calls a month. Past it, you either bill the overage or stop the action.
Spend credits where the work happens
Gate the button with WhenCreditsAvailable and spend from the client, or charge from your API route and return a 402 when the balance runs out.
import {
useConsumeCredits,
useSaaSAuth,
useSaaSWorkspaces,
WhenCreditsAvailable,
WhenCreditsLow,
} from '@buildbase/sdk/react';
export function GenerateButton() {
const { currentWorkspace } = useSaaSWorkspaces();
const { openCreditStore } = useSaaSAuth();
const { consumeCredits, loading } = useConsumeCredits(currentWorkspace?._id);
const generate = async () => {
try {
await consumeCredits({ amount: 10, description: 'AI generation' });
// run the generation
} catch (err: any) {
if (err.code === 'INSUFFICIENT_CREDITS') openCreditStore();
}
};
return (
<>
<WhenCreditsLow threshold={20}>
<p>Running low on credits.</p>
</WhenCreditsLow>
<WhenCreditsAvailable
min={10}
fallbackComponent={<button onClick={() => openCreditStore()}>Buy credits</button>}
>
<button onClick={generate} disabled={loading}>
Generate (10 credits)
</button>
</WhenCreditsAvailable>
</>
);
}import BuildBase from '@buildbase/sdk';
import { cookies } from 'next/headers';
const bb = BuildBase({
serverUrl: process.env.BUILDBASE_SERVER_URL!,
orgId: process.env.BUILDBASE_ORG_ID!,
getSessionId: async () =>
(await cookies()).get('bb-session-id')?.value ?? null,
});
export async function POST(req: Request) {
const { workspaceId } = await req.json();
try {
const { balanceAfter } = await bb.credits.consume(workspaceId, {
amount: 50,
description: 'Batch export',
idempotencyKey: req.headers.get('x-request-id') ?? undefined,
});
// run the export
return Response.json({ balanceAfter });
} catch (err: any) {
if (err.code === 'INSUFFICIENT_CREDITS') {
return Response.json({ error: 'Not enough credits' }, { status: 402 });
}
throw err;
}
}Works well with
Other modules for billing & usage.
Read more in the docs
Setup guides and reference for Credits & Usage Metering.
Overview
Credit packs, a transaction ledger, expiry, and per-plan quotas with overage billing.
Quotas
Enforce per-plan usage limits for API calls, storage, exports, and more.
Billing overview
Add subscription plans, checkout, trials, and seat-based pricing to your app.
Settings screens
Pre-built settings for profile, members, billing, usage, features, and more.
Frequently Asked Questions
What people ask about Credits.
Do my users see this?
Yes. They see a credit balance on their workspace, a store to buy more, and a clear message when there are not enough credits.
What is the difference between credits and quotas?
Credits are a balance your users buy or get with a plan, and spend. Quotas are a per-plan allowance, like API calls a month, that resets every month and is either billed as overage or capped.
Can a retry charge twice?
Not if you pass the same idempotency key. The balance also never goes below zero - a short balance is refused, not overdrawn.
Do credits expire?
Purchased credits expire only when the pack has a validity period. Plan credits can also expire when they renew or when the plan changes. Credits closest to expiring are spent first.