Skip to content

Configuration Reference

Complete reference for RevTurbineInitOptions and related configuration types.

FieldTypeDescription
tenantIdstringYour RevTurbine tenant identifier
apiKeystringAPI key (rt_live_*, rt_test_*, or 'local' for local mode)
endpointstringRevTurbine API endpoint URL
mode'react' | 'snippet' | 'iframe'SDK integration mode
FieldTypeDefaultDescription
runtimeMode'revturbine_server' | 'custom_endpoints' | 'local_only''revturbine_server'How the SDK resolves decisions
endpointOverridesPartial<RevTurbineEndpointOverrides>Custom endpoint URLs (for custom_endpoints mode)
configProviderRevTurbineConfigProviderCustom provider for Playbook
localRuntimeRevTurbineLocalRuntimeOptionsLocal-only mode configuration
FieldTypeDefaultDescription
providerRevTurbineSdkProvider | RevTurbineProviderFactoryPrimary provider override
providerFallbacksArray<...>Fallback provider chain
domainProvidersAnyDomainProvider[]Domain-specific providers
providerFailureSlotBehavior'placeholder' | 'invisible''invisible'Slot behavior after provider failure
FieldTypeDefaultDescription
uiPathResolversRevTurbineUiPathResolverMapMap of CTA action types to resolver functions
FieldTypeDefaultDescription
userRevTurbineUserContextInitial user context. plan_handle is the plan’s unique_handle — the value plan-scoped rules match on
clientSession() => string | Promise<string>Mints a client-session token so the SDK keeps server-derived context fresh on its own. See Server-derived context
pageRevTurbinePageContextPage context (URL, title, referrer, tags)
contextPolicyRevTurbineContextPolicy{ inferUser: true, inferPage: true, routerAutoTrack: true }Auto-inference behavior

Your app tells RevTurbine who the user is. Some of that state, though, is only knowable on your server — the plan a Stripe webhook just changed, trial status, a payment that failed. clientSession is how the SDK gets it without you wiring a refresh loop.

Supply a function that returns a client-session token minted by your backend (POST /api/sdk/client-sessions). The SDK calls it when it first needs a token, again after identify(), and again if the control plane reports one expired — then fetches GET /api/sdk/client-context and folds the result into its decisions. A purchase updates what the user can do with no further app code.

initRevTurbine({
publishableKey: 'rt_pub_…',
user: { id: 'user_123', plan_handle: 'free' },
clientSession: () =>
fetch('/api/revturbine-session', { method: 'POST' })
.then((r) => r.json())
.then((j) => j.client_token),
});

It is a function, not a token, because these tokens are short-lived (~10 minutes) — a value captured at init would go stale mid-session, and refreshing it would become your problem.

The token is a transport credential, never user context: held in memory only, never persisted, never logged, never placed in a URL. If your minter throws or the fetch fails, the SDK keeps using the context your app supplied — enrichment is best-effort and never breaks your app.

Omit clientSession and none of this happens: no token is requested and no client-context call is made. Server-derived context is opt-in.

FieldTypeDefaultDescription
placementBehaviorPartial<RevTurbinePlacementBehaviorFlags>Opt-in pipeline flags
FieldTypeDefaultDescription
persistentStorageRevTurbineStoragelocalStoragePersistent storage override
sessionStorageRevTurbineStoragesessionStorageSession storage override

FieldTypeDefaultDescription
inferUserbooleantrueAuto-detect user info from browser APIs
inferPagebooleantrueAuto-capture URL, title, referrer
routerAutoTrackbooleantrueTrack SPA route changes

FieldTypeDescription
playbookPlaybookFull Playbook snapshot for local execution
placementsLocalPlacementDatasetOptional static placements dataset
initialDataobjectStatic data for local decisions (see below)
resolversobjectOptional resolver callbacks (see below)
storageKeystringOptional localStorage key override
getContext() => Promise<JsonObject>Reactive context callback
FieldType
placementDecisionsByPlacementIdRecord<string, RevTurbinePlacementDecision>
placementsByLookupKeyRecord<string, PlacementOutput | null>
entitlementByHandleRecord<string, EntitlementResult>
userContextByUserIdRecord<string, UserTargetingContext>
trialStatusRevTurbineTrialContext
FieldSignature
getPlacementDecision(input, placement?, context?) => Promise<RevTurbinePlacementDecision>
getPlacement(config) => Promise<PlacementOutput | null>
checkEntitlement(handle, context?) => Promise<EntitlementResult>
fetchUserContext(userId) => Promise<UserTargetingContext>
getTrialStatus() => Promise<RevTurbineTrialContext>
resolveExportedConfig() => Promise<Playbook>

FlagTypeDefaultDescription
enableClientCapsEnforcementbooleanfalseClient-side cap enforcement
enableAutoGatedPlacementbooleanfalseAuto-render gated placements
enableTrialAutoTriggersbooleanfalseAuto-derive trial lifecycle triggers

Override individual API endpoints for custom_endpoints mode:

FieldDefault Path
decideContext/api/decide-context
bootstrapContext/api/bootstrap-context
decide/api/decide
getPlacement/api/placement
checkEntitlement/api/entitlement
userContext/api/user-context
trialStatus/api/trial-status
ingestEvents/api/events
touchpointTransition/api/touchpoint-transition
placementTypes/api/placement-types
surfaceSlots/api/surface-slots

Interface for custom storage providers:

interface RevTurbineStorage {
getItem(key: string): string | null;
setItem(key: string, value: string): void;
removeItem(key: string): void;
}

{
tenantId: string; // ✅ Required
apiKey: string; // ✅ Required (rt_live_* or rt_test_*)
endpoint: string; // ✅ Required
mode: string; // ✅ Required
}
{
tenantId: string; // ✅ Required (can be 'demo')
apiKey: string; // ✅ Required (can be 'local')
endpoint: string; // ✅ Required (can be 'http://localhost')
mode: string; // ✅ Required
runtimeMode: 'local_only'; // ✅ Required
localRuntime: {
playbook: Playbook; // ✅ Required
};
}
{
tenantId: string; // ✅ Required
apiKey: string; // ✅ Required
endpoint: string; // ✅ Required
mode: string; // ✅ Required
runtimeMode: 'custom_endpoints'; // ✅ Required
endpointOverrides: { // ✅ At least one override required
decide?: string;
getPlacement?: string;
checkEntitlement?: string;
};
}