useCustomer — one HTTP call serves every hook and gate on the page, so you can scatter as many as you like without extra round-trips.
Every hook returns isLoading: boolean and error: Error | null — see Introduction. The typed hooks and gates also share two conventions, so they’re stated once here rather than repeated per feature type:
fallback— a type-safe default value returned while loading, on error, or when the customer has no entitlement for the slug. When a fallback value is returned instead of a live one, the hook’sisFallbackistrue.- Gate slots — every gate renders
childrenon access,noAccessComponent(defaultnull) on denial, andloadingComponent(defaultnull) while resolving. The typed gates takefallbackfor the same purpose as the hooks. (FeatureGateis the exception — it usesfallbackfor the denied slot; see below.)
FeatureGate takes featureSlug. Every typed gate (BooleanGate, MeteredGate, CreditGate, ConfigGate, EnumGate) takes slug.The six gates
useEntitlement
Reads one feature’s entitlement by slug and returns the raw, type-discriminated value. By default it serves the read from the bulkuseCustomer cache. Pass requestedUsage (metered) or requestedValues (enum) to force a live POST /v1/customers/:id/check capacity probe instead.
Prefer one of the typed wrappers below when you know the feature type.
Parameters
string
required
The feature’s stable slug.
number
Metered features: ask “would I have access if I consumed N units now?”. Forces a live
/check capacity probe rather than a cache read.string[]
Enum features: check whether these requested values are in the allowed set. Also forces a live
/check.EntitlementValue
Value used while loading, on error, or on a cache miss. When returned,
isFallback is true.entitlement—EntitlementValue | null— the resolved value. Narrow onentitlement.type('boolean' | 'metered' | 'credit' | 'config' | 'enum') to read the type-specific fields — e.g.remainingfor metered,creditBalancefor credit,valuefor config,enumValuesfor enum.isFallback—boolean—truewhenentitlementcame fromoptions.fallbackrather than a live read.
useEntitlements
Reads multiple features at once. By default it adds zero HTTP — it derives fromuseCustomer().entitlements, optionally filtered to the slugs you pass — and returns both the keyed map and a slug-sorted list for feature matrices. Pass { fresh: true } to force a live batch check (e.g. right after a mutation).
Parameters
string[]
Optional filter. When provided, only these slugs are returned; omit it to get the customer’s entire entitlement map.
boolean
When
true, skip the local cache and call POST /v1/customers/:id/check/batch for slugs. Requires a non-empty slugs argument (the server caps a batch at 50).Record<string, EntitlementValue>
Per-slug values used while loading, on error, or for slugs the customer doesn’t have.
entitlements—Record<featureSlug, EntitlementValue>— the filtered map, each value discriminated bytype.list—Array<{ featureSlug } & EntitlementValue>— the same data sorted alphabetically byfeatureSlug. Ideal for iterating a table.
FeatureGate
The generic, type-agnostic gate: renders its children only when the customer has access to a feature, regardless of the feature’s type. It resolves throughuseEntitlement (served from the useCustomer cache) and exposes an onDenied callback that fires once with a typed reason when access is refused.
Props
string
required
The feature’s stable slug.
ReactNode
required
Rendered when access is granted.
ReactNode
default:"null"
Rendered when access is denied.
ReactNode
default:"null"
Rendered while the entitlement is loading.
(reason: AccessDeniedReason) => void
Called once when access is denied (and again only after access is regained and lost again). The
reason is one of: no_entitlement, no_active_subscription, usage_exceeded, credit_exhausted, not_loaded.number
Metered features: capacity probe — would access be granted after consuming this many units? Forces a live
POST /v1/customers/:id/check.EntitlementValue
Type-safe entitlement default used while loading or on a cache miss. For ergonomics, prefer the typed gates and their
fallback prop.Boolean features
An on/off feature flag — SSO, audit log, priority support.useBooleanEntitlement(slug, options?) returns a flat access boolean — true when the customer has the feature, false otherwise (or for any non-boolean / missing entitlement). Its options.fallback is { access: boolean }.
BooleanGate renders children only when access is true.
Metered features
A metered feature with a per-period quota — API calls, seats, exports.useMeteredEntitlement(slug, options?) returns the full meter picture: access, remaining (quota left this period — granted − usage, the canonical “what’s left”), usage, limit (granted allowance), percentage (usage / limit × 100, 0 when unlimited), isUnlimited (when true, ignore limit/remaining/percentage), and nextResetAt (ISO timestamp of the next reset, or null). Pass options.requestedUsage to force a live /check capacity probe; options.fallback is { access: boolean; remaining?: number; isUnlimited?: boolean; limit?: number; usage?: number }.
MeteredGate renders children only when access exists; pass requestedUsage so it succeeds only when that many units could still be consumed this period.
requestedUsage to either the hook or the gate forces a server-side check — “do we have headroom for N more units?” — instead of reading the static remaining from cache:
Credit features
A credit-backed feature drawing from a wallet — AI credits, generation credits, prepaid balance.useCreditEntitlement(slug, options?) returns access and creditBalance (the wallet balance backing this feature). Render creditBalance with formatCredits(n) for unit denominations or as money for fiat denominations — never mix the two. Its options.fallback is { access: boolean; creditBalance: number }.
CreditGate renders children only when access exists and the balance is at least requiredBalance (default 1).
CreditGate’s extra prop:
number
default:"1"
Minimum credit balance required to render children.
Config features
A config-valued feature whose entitlement carries a tunablevalue — “max file size”, “support tier” — a plan sets per tier.
useConfigEntitlement(slug, options?) returns access and value (a number or string, or null when there’s no config entitlement). Its options.fallback is { access: boolean; value: number | string }.
ConfigGate renders a render-prop children — a function (value: number | string) => ReactNode called with the resolved value when access is granted; noAccessComponent renders when access is denied or the value is null.
Enum features
An enum feature whose entitlement is a set of allowed string values — allowed regions, export formats, model tiers.useEnumEntitlement(slug, options?) returns access and enumValues (the array of allowed strings, empty for any non-enum / missing entitlement). Pass options.requestedValues to probe whether specific values are permitted (forces a live /check) — access then reflects whether those values are in the allowed set. Its options.fallback is { access: boolean; enumValues: string[] }.
EnumGate renders children only when access exists; pass requestedValues to require specific values to be in the allowed set.
See also
Customer
useCustomer loads the entitlement cache these hooks and gates read from, plus a synchronous check().Subscriptions
The subscriptions that grant these entitlements.