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
| Component | Prop | Use when |
|---|---|---|
FeatureGate | featureSlug | Generic gate for any feature type; gives you onDenied(reason) and a single fallback. |
BooleanGate | slug | An on/off feature flag (e.g. SSO, audit log). |
MeteredGate | slug, requestedUsage | A metered feature with a quota; probe remaining capacity before an action. |
CreditGate | slug, requiredBalance | A credit-backed feature; require a minimum wallet balance. |
ConfigGate | slug | A config-valued feature; render with the resolved value via a render-prop. |
EnumGate | slug, requestedValues | An enum feature; require specific values to be in the allowed set. |
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
The feature’s stable slug.
Metered features: ask “would I have access if I consumed N units now?”. Forces a live
/check capacity probe rather than a cache read.Enum features: check whether these requested values are in the allowed set. Also forces a live
/check.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
Optional filter. When provided, only these slugs are returned; omit it to get the customer’s entire entitlement map.
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).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
The feature’s stable slug.
Rendered when access is granted.
Rendered when access is denied.
Rendered while the entitlement is loading.
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.Metered features: capacity probe — would access be granted after consuming this many units? Forces a live
POST /v1/customers/:id/check.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:
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.