Skip to content
Indiana
Dashboard
Docs
Browse docs / Feature access & Paywalls

Feature access & Paywalls

Current feature definitions, access checks, purchase recommendations and verified rechecks.

SDK 0.0.1Updated

Current feature definitions and fixed plan contracts

This page covers the source as of 2026-10-14. Saving updates the feature’s current configuration, with active/archived states and restore before editing. Features no longer use publish. Internal snapshots preserve pricing evidence; products still publish fixed contracts. Default Credit rates affect future consumption; explicit plan rates and frozen operations retain their prices. Archival does not revoke existing customer capacity.

The pinned organizational npm package is 0.0.1, a separate release snapshot from 2026-10-13. Later source additions such as checkEntitlement/showPaywall do not automatically appear in the registry artifact because the source version remains 0.0.1. This flow requires the matching SDK build/release, server deployment and migrations. The default installation remains the published organizational package.

Check access, show a Paywall and recheck

checkEntitlement requires entitlements:read. requirement specifies a stable entitlementId, positive decimal quantity, properties and optional Entity. allowed observes current access; reason distinguishes missing entitlement, insufficient balance, capacity or usage limits. Checks and previews do not consume balances; protected jobs still need backend atomic consumption or reservation.

obtainRetainedPaywallController is a host integration point. Your authenticated backend uses createPaywallStartClient.start, retaining the original requestId, paywallId, requirement, customerToken and commerce scope. The browser constructs a controller using only runToken. Grant sessions:create and funnels:run. Recover the same run after payment return; showPaywall rechecks the same requirement after completion and calls onAccessGranted only when access is allowed. This callback updates presentation rather than authorizing a job.

app/paywall.ts · current-source fragmentTypeScript
import { showPaywall } from "@tinkerlandai/indiana-sdk"; // grow is the identified browser client from the quickstart.// Keep this same requirement in the verified backend start ticket.const requirement = { entitlementId: configuredFeatureId, quantity: "1", properties: {} };const result = await showPaywall(container, {  check: async () => (await grow.checkEntitlement({    requirement, paywallId: configuredPaywallId,    commerce: { provider: "stripe", currency: "USD" },  })).check,  start: () => obtainRetainedPaywallController(),  onAccessGranted: () => refreshAccessDisplay(),  onAuthenticate: () => obtainCurrentUserCustomerToken(),  onCheckout: ({ url }) => window.location.assign(url),  onOpenUrl: ({ url }) => window.location.assign(url),  onError: reportError,});// On route leave, destroy result.host if present and reset its controller.