useFeatureAccess hook lets you read a customer’s feature access and usage from your backend routes and use it directly in your UI.
Setup first: see the React integration guide.
- Single feature access
- All feature access
const result = useFeatureAccess<MyFeatures>("priority_support", options?)
Parameters
keyof MyFeatures
required
Feature key to read. Returns flattened fields for that feature plus
isLoading, error, and refetch.boolean
Enable or disable fetching. Defaults to
true.boolean
When
true, a 404 is surfaced as an error instead of returning null. Defaults to false.SWRConfiguration<MyFeatures | null, Error>
Optional SWR config for caching/revalidation behavior.
Returns
- Boolean feature
- Limit feature
boolean (literal)
Feature type.
boolean
Whether the customer has access to the selected boolean feature.
boolean
Whether data is currently loading.
Error | null
Error from the latest request.
() => Promise<void>
Manually revalidate feature access.
limit (literal)
Feature type.
boolean
Whether the customer has access to the selected limit feature.
hasAccess indicates whether the customer has access to the feature in general. It does not indicate remaining usage. Use usage.hasReachedLimit to determine if usage limit has been reached.boolean
Whether usage is unlimited.
number | null
Configured limit.
null when unlimited.object | undefined
Usage for tracked limit features. Omitted for untracked limit features.
number
Current usage amount in the active period.
number | null
Remaining usage in the active period.
null when unlimited.number
Remaining bonus usage available.
number
Bonus usage already consumed.
boolean
Whether usage has reached the limit.
number | null
Unix timestamp (ms) for next reset.
number | null
Unix timestamp (ms) for previous reset.
boolean
Whether data is currently loading.
Error | null
Error from the latest request.
() => Promise<void>
Manually revalidate feature access.
const result = useFeatureAccess<MyFeatures>(options?)
Parameters
boolean
Enable or disable fetching. Defaults to
true.boolean
When
true, a 404 is surfaced as an error instead of returning null. Defaults to false.SWRConfiguration<MyFeatures | null, Error>
Optional SWR config for caching/revalidation behavior.
Returns
MyFeatures | null
Feature access map keyed by your feature keys.
- Boolean entries
- Limit entries
boolean (literal)
Feature type for boolean entries.
boolean
Whether the customer has access to that boolean feature.
limit (literal)
Feature type for limit entries.
boolean
Whether the customer has access to that limit feature.
hasAccess indicates whether the customer has access to the feature in general. It does not indicate remaining usage. Use usage.hasReachedLimit to determine if usage limit has been reached.boolean
Whether the feature is unlimited.
number | null
Configured limit for that feature.
object | undefined
Usage for tracked limit features.
number | null
Remaining usage for that feature in the active period.
number
Remaining bonus usage for that feature.
boolean
Whether usage has reached the limit for that feature.
boolean
Whether data is currently loading.
Error | null
Error from the latest request.
() => Promise<void>
Manually revalidate feature access.
Examples
Single feature access
- Boolean Example
- Limit Example
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function PrioritySupportButton() {
const { hasAccess, isLoading } = useFeatureAccess<MyFeatures>("priority_support");
const onClick = () => {
if (!hasAccess) {
// Show upgrade flow
return;
}
// Open support flow
};
if (isLoading) return <div>Loading...</div>;
return <button onClick={onClick}>Contact support</button>;
}
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function CreateReportButton() {
const { hasAccess, usage, isUnlimited, limit, isLoading } = useFeatureAccess<MyFeatures>("api_calls");
const remaining = usage?.remaining;
const bonusRemaining = usage?.bonusRemaining ?? 0;
const onClick = () => {
if (!hasAccess) {
// Show upgrade flow
return;
}
if (usage?.hasReachedLimit) {
// Show usage limit message
return;
}
// Create report
};
if (isLoading) return <div>Loading...</div>;
return (
<div>
<p>{isUnlimited ? "Unlimited" : `${remaining ?? 0} / ${limit ?? 0} remaining`}</p>
<p>Bonus remaining: {bonusRemaining}</p>
<button onClick={onClick}>Create report</button>
</div>
);
}
All feature access
- Boolean Example
- Limit Example
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function PrioritySupportButton() {
const { featureAccess, isLoading } = useFeatureAccess<MyFeatures>();
const hasAccess = featureAccess?.priority_support?.hasAccess;
const onClick = () => {
if (!hasAccess) {
// Show upgrade flow
return;
}
// Open support flow
};
if (isLoading) return <div>Loading...</div>;
return <button onClick={onClick}>Contact support</button>;
}
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function CreateReportButton() {
const { featureAccess, isLoading } = useFeatureAccess<MyFeatures>();
const apiCalls = featureAccess?.api_calls;
const remaining = apiCalls?.usage?.remaining;
const bonusRemaining = apiCalls?.usage?.bonusRemaining ?? 0;
const onClick = () => {
if (!apiCalls?.hasAccess) {
// Show upgrade flow
return;
}
if (apiCalls?.usage?.hasReachedLimit) {
// Show usage limit message
return;
}
// Create report
};
if (isLoading) return <div>Loading...</div>;
return (
<div>
<p>API calls remaining: {remaining ?? "Unlimited"}</p>
<p>Bonus remaining: {bonusRemaining}</p>
<button onClick={onClick}>Create report</button>
</div>
);
}
Displaying usage to user
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function UsageBadge() {
const { hasAccess, usage, isUnlimited, limit } = useFeatureAccess<MyFeatures>("api_calls");
if (!hasAccess) return <div>Upgrade required</div>;
if (!usage) return <div>Usage tracking unavailable</div>;
const label = isUnlimited ? `${usage.used} used` : `${usage.used} / ${limit}`;
return <div>{label}</div>;
}
Determine if limit has been hit using PriceOS
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function CreateReportButton() {
const { hasAccess, usage } = useFeatureAccess<MyFeatures>("api_calls");
const onClick = () => {
if (!hasAccess) return;
if (usage?.hasReachedLimit) {
// Block action: limit reached
return;
}
// Continue action
};
return <button onClick={onClick}>Create report</button>;
}
Determine if limit has been hit using your own tracking
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function CreateReportButton({ currentUsage }: { currentUsage: number }) {
const { hasAccess, limit, isUnlimited } = useFeatureAccess<MyFeatures>("api_calls");
const onClick = () => {
if (!hasAccess) return;
if (!isUnlimited && typeof limit === "number" && currentUsage >= limit) {
// Block action: limit reached (your own tracking)
return;
}
// Continue action
};
return <button onClick={onClick}>Create report</button>;
}
Displaying bonuses to users
import { useFeatureAccess } from "priceos/react";
import type { MyFeatures } from "./priceos.types";
export function BonusUsageSummary() {
const { usage } = useFeatureAccess<MyFeatures>("api_calls");
if (!usage) return null;
return (
<div>
<p>Bonus remaining: {usage.bonusRemaining}</p>
<p>Bonus used: {usage.bonusUsed}</p>
</div>
);
}