Build
Add the SDK
GateClient talks to UsageGate from your server. It does not create login accounts — userId is whatever id already exists in your product.
Install
npm install @usagegate0/sdk
# or: pnpm add @usagegate0/sdk
# or: yarn add @usagegate0/sdkConfigure
import { GateClient } from "@usagegate0/sdk";
const gate = new GateClient(process.env.USAGEGATE_KEY!, {
baseUrl: process.env.USAGEGATE_API_BASE_URL, // e.g. https://usagegate.vercel.app
failOpen: true,
timeoutMs: 800,
});Create a key first — API keys. Defaults to https://usagegate.vercel.app when baseUrl / USAGEGATE_API_BASE_URL are omitted.
Grant (provision balances)
Call when someone signs up, starts a trial, or you override from an admin tool. Absolute set — not an increment.
await gate.grant(session.user.id, "ai_credits", { balance: 1000 });
await gate.grant(session.user.id, "export_pdf", { balance: 1 });
await gate.grant(session.user.id, "ai_credits", {
balance: 50,
resetAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
});Paid plans: Stripe webhooks set balances and resetAt (period end) on every invoice. Manual resetAt is for trials / overrides only — see billing periods.
Check & consume
const customerId = session.user.id;
if (!(await gate.canAccess(customerId, "ai_credits"))) {
return Response.json({ error: "upgrade" }, { status: 402 });
}
const result = await gate.consume(customerId, "ai_credits", 1);
if (!result.success) {
return Response.json({ error: "out of credits" }, { status: 402 });
}Fail-open
canAccess / consume default to fail-open so your app stays up if UsageGate blips. grant, getRules, and putRules do not fail-open — if they error, assume nothing changed.
Rules & Stripe from code
await gate.putRules({ nodes: [...], edges: [...] });
const graph = await gate.getRules();
await gate.configureStripe({
webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
accountHint: "acct_optional",
});Visual editor: Define access rules. Stripe guide: Connect Stripe.
