Features & Entitlements
Check feature access and report usage from the SDK
Features & Entitlements
Gate app behavior based on what the user has purchased or been granted. Check feature access locally or in real time, and report usage for metered features.
How feature access works
Feature access is delivered to the SDK through three sources:
- Profile payload -- the primary source. On each profile fetch, the SDK receives the user's current feature access and caches it locally.
- Real-time entitlement checks -- for critical operations, the SDK can query the server directly.
- Purchase sync responses -- when a transaction is synced, the server returns updated feature access that is applied immediately.
The SDK merges these sources so your app always has the freshest available data.
Cache-first feature checks
Use hasFeature() for fast, non-blocking access checks. It reads from the local cache first and falls back to a network check only when needed:
let access = try await NuxieSDK.shared.hasFeature("premium_content")
if access.allowed {
showPremiumContent()
} else {
showUpgradePrompt()
}Checking metered features
For features with a balance (credits, quotas, usage limits), pass a requiredBalance:
let access = try await NuxieSDK.shared.hasFeature(
"ai_generations",
requiredBalance: 5
)
if access.allowed {
generateContent()
}Entity-based balances
For per-entity limits (e.g., per-project quotas), pass an entityId:
let access = try await NuxieSDK.shared.hasFeature(
"api_calls",
requiredBalance: 1,
entityId: "project-456"
)Instant cached lookups
Use getCachedFeature() for a synchronous, non-blocking read that never makes a network call. Returns nil if the feature is not in cache:
let cachedAccess = await NuxieSDK.shared.getCachedFeature("premium_content")
if cachedAccess?.allowed == true {
// Feature is available from cache
}Real-time server checks
Use checkFeature() when you need authoritative server state for critical operations. This always makes a network call:
let result = try await NuxieSDK.shared.checkFeature(
"premium_content",
requiredBalance: nil,
entityId: nil
)To force a fresh check and update the cache, use refreshFeature():
let result = try await NuxieSDK.shared.refreshFeature("premium_content")SwiftUI integration
The SDK provides FeatureInfo, an ObservableObject that updates automatically when feature access changes. Use it for reactive UI:
struct PremiumView: View {
@ObservedObject var features = NuxieSDK.shared.features
var body: some View {
if features.isAllowed("premium_content") {
PremiumContent()
} else {
UpgradePrompt()
}
}
}FeatureInfo provides these convenience methods:
Delegate notifications
If you set a NuxieDelegate on NuxieSDK.shared.delegate, it receives a callback whenever feature access changes:
class AppDelegate: NuxieDelegate {
func featureAccessDidChange(
_ featureId: String,
from oldValue: FeatureAccess?,
to newValue: FeatureAccess?
) {
// React to feature access changes
}
}Reporting usage
Fire-and-forget usage
Use useFeature() to report usage of a metered feature. It decrements the local balance immediately for instant UI feedback and queues a $feature_used event for server processing:
// Consume 1 unit
NuxieSDK.shared.useFeature("ai_generations")
// Consume multiple units
NuxieSDK.shared.useFeature("export_credits", amount: 5)
// Per-entity usage
NuxieSDK.shared.useFeature("api_calls", amount: 1, entityId: "project-123")The server processes the usage event asynchronously. The authoritative balance is reconciled on the next profile refresh.
Confirmed usage
Use useFeatureAndWait() when you need server confirmation that the usage was recorded:
let result = try await NuxieSDK.shared.useFeatureAndWait(
"ai_generations",
amount: 1
)
if result.success {
print("Remaining: \(result.usage?.remaining ?? 0)")
proceedWithGeneration()
}This method sends the event directly to the server, waits for the response, and updates the local balance with the authoritative value from the server.
Next steps
- Purchases -- see how purchases grant feature access
- Monetization -- configure products, features, and entitlements in the dashboard
- Presenting Flows -- trigger a paywall when a feature check fails