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.


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 null if 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).

Was this page helpful?