Check and spend in your app

Everything your server does with the SDK: put users on a plan, check or spend before each action, and what happens if something goes wrong. TypeScript; other languages use the HTTP API.

Install

lib/gate.ts
// npm install @usagegate/sdk
import { GateClient } from "@usagegate/sdk";

// Server only. Create the key in Dashboard → API keys.
export const gate = new GateClient(process.env.USAGEGATE_KEY!);

Put users on a plan

New users have no plan until you give them one. Call grantPlan after sign-up with your user's id and a free plan id from Access rules. Their allowance refills every month on its own.

after sign-up
await gate.grantPlan(user.id, "plan_free");

It is safe to call on every login: a user who already has a plan, free or paid, keeps it. Paid plans are never set here; they come from Stripe or your payment provider.

Check before each action

Monthly amounts and limits (credits, API calls, seats): spend with consume. It checks and spends in one step, so two requests at the same moment can never both use the last credit.

spend one credit
const spent = await gate.consume(user.id, "ai_credits", 1);
if (!spent.success) {
  return Response.json({ error: "Upgrade to keep going" }, { status: 402 });
}
// ...do the work

On/off features (PDF export, SSO): ask with canAccess. It spends nothing, so you can also use it to show or hide an upgrade button.

on/off feature
if (!(await gate.canAccess(user.id, "export_pdf"))) {
  return Response.json({ error: "Pro feature" }, { status: 402 });
}

“No” is a normal answer, not an error. What your route returns is up to you; 402 with an upgrade link is a good default.

If something goes wrong

What canAccess and consume do
SituationWhat happensWhat to do
UsageGate is down or slow (over 800 ms)The request is allowed, with a warning in your logs, so your product stays up.Nothing. To block instead, pass { failOpen: false }.
Wrong API key, unknown feature key, or a bad requestThe answer is no, with a [usagegate] error in your server logs.Fix the key or the feature key. The log says which.
Your own UsageGate plan has used its monthly quotaThe request is allowed, with a warning.Upgrade in Dashboard → Billing.

The other methods (grantPlan, reportSubscription, grant, rules) throw an error instead, so you know nothing was saved.

Reference

@usagegate/sdk methods
MethodWhat it does
canAccess(userId, featureKey)true or false. Spends nothing.
consume(userId, featureKey, amount = 1)Spends atomically. Returns { success, remaining }; success is false when there is not enough.
grantPlan(userId, planId)Puts a user on a free plan that refills monthly. Safe to repeat (alreadyEnrolled: true).
reportSubscription({ eventId, userId, planId, status, periodEnd })Paid plan from a provider other than Stripe. See Other payment providers.
grant(userId, featureKey, { balance, resetAt? })Sets one balance by hand (support top-ups, one-off trials). Does not refill.
getRules() / putRules(table)Read or replace your plan table from code.
configureStripe({ webhookSecret }) / getStripeConfig()Save or check the Stripe connection from code.

Options for new GateClient(key, options): timeoutMs (default 800), failOpen (default true), baseUrl (only if you host UsageGate yourself).