Entitlements
Gate features by plan tier or individual feature flags. Entitlements are derived from the user's active subscription and evaluated both client-side and server-side.
How entitlements work
Entitlements are the mapping between a subscription plan and the features that plan unlocks. You define features when creating a plan in the dashboard:
Starter plan → ["basic_analytics", "5_seats"]
Pro plan → ["basic_analytics", "advanced_analytics", "25_seats", "api_access"]
Enterprise → ["basic_analytics", "advanced_analytics", "unlimited_seats", "api_access", "sso"]
When a user has an active subscription, AuthGate resolves their plan and returns the list of features they are entitled to. Your application uses these entitlements to show or hide functionality.
Entitlements are fetched from GET /api/proxy/billing/entitlements and include both the plan name and the full list of feature flags.
Entitlements are enforced in AuthGate at the API level and in your application's UI and server-side checks. Never rely solely on client-side entitlement checks to protect sensitive operations — always verify server-side before performing privileged actions.
useEntitlements hook
Fetch the current user's entitlements in any client component:
import { useEntitlements } from "@auth-gate/react";
function AnalyticsSection() {
const { entitlements, loading } = useEntitlements();
if (loading) return null;
if (!entitlements?.features.includes("advanced_analytics")) {
return <UpgradePrompt feature="Advanced Analytics" />;
}
return <AdvancedAnalyticsDashboard />;
}
The hook caches entitlements for the duration of the session and re-fetches when the subscription changes.
Return value
- Name
entitlements- Type
- Entitlements | null
- Description
The user's current entitlements, or
nullif they have no active subscription.
- Name
loading- Type
- boolean
- Description
True while the initial fetch is in progress.
- Name
error- Type
- Error | null
- Description
Set if the fetch failed.
- Name
refresh- Type
- () => void
- Description
Manually re-fetch entitlements. Useful after a subscription change.
The Entitlements object shape:
interface Entitlements {
plan: string; // Plan name, e.g. "pro"
status: string; // Subscription status, e.g. "active"
features: string[]; // Feature flags granted by the plan
}
useBillingAuth hook
A higher-level hook that exposes a has() helper for declarative entitlement checks:
import { useBillingAuth } from "@auth-gate/react";
import { billing } from "../../authgate.billing";
function ExportButton() {
const { has, loading } = useBillingAuth();
if (loading) return null;
if (!has({ feature: billing.features.csv_export })) { // type-safe — no .key needed
return <button disabled title="Upgrade to export">Export CSV</button>;
}
return <button onClick={handleExport}>Export CSV</button>;
}
has(check) helper
- Name
plan- Type
- string
- Description
Check if the user is on this plan or any plan above it in your plan hierarchy. Plans are ordered as defined in the dashboard.
- Name
feature- Type
- string
- Description
Check if the user's current plan includes this feature flag.
Pass both plan and feature to require both conditions simultaneously:
const canExport = has({ plan: billing.plans.pro, feature: billing.features.csv_export }); // type-safe — no .key needed
Server-side checking
Always verify entitlements server-side before performing sensitive operations. Use checkEntitlement from @auth-gate/nextjs:
src/app/api/export/route.ts
import { checkEntitlement } from "@auth-gate/nextjs";
import { getSession } from "@/lib/auth";
import { billing } from "../../authgate.billing";
export async function GET() {
const user = await getSession();
if (!user) return new Response("Unauthorized", { status: 401 });
const entitled = await checkEntitlement(user.id, {
feature: billing.features.csv_export, // type-safe — no .key needed
baseUrl: process.env.AUTHGATE_URL!,
apiKey: process.env.AUTHGATE_API_KEY!,
});
if (!entitled) {
return new Response("Upgrade required", { status: 403 });
}
// ... perform export ...
}
checkEntitlement calls GET /api/proxy/billing/entitlements on behalf of the user and returns a boolean. Results are not cached server-side — each call makes a fresh request.
Declarative gating with BillingGate
For component-level gating, use the <BillingGate> component:
import { BillingGate } from "@auth-gate/react";
import { billing } from "../../authgate.billing";
<BillingGate
requires={{ feature: billing.features.api_access }} // type-safe — no .key needed
fallback={<UpgradeCard feature="API Access" plan="Pro" />}
>
<ApiKeyManager />
</BillingGate>
See SDK Components for full props documentation.
Utility functions
For use outside of React components, @auth-gate/react exports two utility functions that operate on an Entitlements object directly:
import { hasPlan, hasFeature } from "@auth-gate/react";
import { billing } from "../../authgate.billing";
const entitlements = { plan: "pro", status: "active", features: ["api_access", "csv_export"] };
hasPlan(entitlements, billing.plans.starter.key); // true — plain .key still works
hasPlan(entitlements, billing.plans.enterprise.key); // false — plain .key still works
hasFeature(entitlements, billing.features.api_access.key); // true
hasFeature(entitlements, billing.features.sso.key); // false
These are synchronous and useful for transforming entitlement data in non-hook contexts (e.g. server actions, utility modules).