Configuration Reference
Complete reference for RevTurbineInitOptions and related configuration types.
RevTurbineInitOptions
Section titled “RevTurbineInitOptions”Required Fields
Section titled “Required Fields”In revturbine_server and custom_endpoints modes the browser needs publicKey; tenantId is optional because the key names its tenant. In local_only mode neither is needed — initRevTurbine({ runtimeMode: 'local_only', localRuntime: { playbook } }) is a complete configuration. For copy-paste examples per runtime, see Initialize the SDK.
| Field | Type | Description |
|---|---|---|
tenantId | string | Your RevTurbine tenant identifier. Optional whenever publicKey is supplied: the key is bound to one tenant and the SDK reads the tenant back from the Playbook it fetches. A tenantId that disagrees with the key’s tenant is ignored with a one-time warning; the key wins. Required by RevTurbineServer, where it must be the server key’s own tenant. |
publicKey | string | In the browser: your public key (rtk_…, type public, minted under Settings → API Token Management → Ingest Keys). Safe to ship in a bundle. Add your app’s origins to the key’s allowed origins, or Playbook delivery is refused with 403 origin_not_allowed. See Production Readiness → Keys. |
apiKey | string | Your server key (rtk_…, type server), minted under Settings → API Token Management → Server Token. Trusted backend initRevTurbine in RuntimeMode.Server uses it for Playbook delivery and event ingest; RevTurbineServer uses it for client sessions and server-only writes. Evaluation remains local. Never ship it to a browser. As of 0.11.0 it is not accepted as a browser credential — pass publicKey there; ingestPublicKey was removed (BL-0113). |
Runtime Configuration
Section titled “Runtime Configuration”| Field | Type | Default | Description |
|---|---|---|---|
runtimeMode | 'revturbine_server' | 'custom_endpoints' | 'local_only' | 'revturbine_server' | How the SDK loads its Playbook; evaluation remains local |
endpoint | string | 'https://revturbine.com/app' | RevTurbine control-plane URL; omit it for the hosted service |
mode | 'react' | 'snippet' | 'iframe' | 'snippet' ('react' when <RevTurbineProvider> initializes the SDK) | Integration label carried in telemetry; no decision depends on it |
endpointOverrides | Partial<RevTurbineEndpointOverrides> | — | Route the SDK’s non-decision calls through your own endpoints (custom_endpoints mode) |
configProvider | RevTurbineConfigProvider | — | Custom provider for the Playbook; implement getPlaybook() |
localRuntime | RevTurbineLocalRuntimeOptions | — | Local-only mode configuration |
Provider Configuration
Section titled “Provider Configuration”| Field | Type | Default | Description |
|---|---|---|---|
provider | RevTurbineSdkProvider | RevTurbineProviderFactory | — | Primary provider override |
providerFallbacks | Array<...> | — | Fallback provider chain |
domainProviders | AnyDomainProvider[] | — | Domain-specific providers |
providerFailureSlotBehavior | 'placeholder' | 'invisible' | 'invisible' | Slot behavior after provider failure |
UI Path Handling
Section titled “UI Path Handling”| Field | Type | Default | Description |
|---|---|---|---|
uiPathResolvers | RevTurbineUiPathResolverMap | — | Map of CTA action types to resolver functions |
Branding
Section titled “Branding”| Field | Type | Default | Description |
|---|---|---|---|
branding | BrandingConfig | Built-in defaults | Optional workspace name, logo and partial theme. An explicit value takes priority over API branding and legacy config themes. |
See Theming for an example. Set colorScheme: 'light' or 'dark' in initialization, use the React provider’s colorScheme prop, or call session.sdk.setColorScheme(scheme) in a headless integration (SDK 0.12.4).
User & Page Context
Section titled “User & Page Context”| Field | Type | Default | Description |
|---|---|---|---|
user | RevTurbineUserContext | — | Initial 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 |
page | RevTurbinePageContext | — | Page context (URL, title, referrer, tags) |
contextPolicy | RevTurbineContextPolicy | { inferUser: true, inferPage: true, routerAutoTrack: true } | Auto-inference behavior |
Server-derived context (clientSession)
Section titled “Server-derived context (clientSession)”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, with the server key; RevTurbineServer does
it for you). 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.
import { initRevTurbine } from '@revturbine/sdk';
export async function startRevTurbine() { return initRevTurbine({ publicKey: process.env.NEXT_PUBLIC_REVTURBINE_PUBLIC_KEY!, // public key — safe in the browser user: { id: 'user_123', plan_handle: 'free' }, clientSession: async () => { const response = await fetch('/api/revturbine-session', { method: 'POST' }); if (!response.ok) throw new Error(`RevTurbine client session failed (${response.status})`); const body: { client_token: string } = await response.json(); return body.client_token; }, });}The route behind /api/revturbine-session is yours: it authenticates your user,
mints with the server key and returns only client_token. The complete route
(Next.js and Express), the failure behavior and the refresh rules are on
Client sessions.
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.
Behavioral Flags
Section titled “Behavioral Flags”| Field | Type | Default | Description |
|---|---|---|---|
placementBehavior | Partial<RevTurbinePlacementBehaviorFlags> | derived from the Playbook | Overrides for flags the SDK derives from what the Playbook authors (see below) |
Storage
Section titled “Storage”| Field | Type | Default | Description |
|---|---|---|---|
persistentStorage | RevTurbineStorage | localStorage | Persistent storage override |
sessionStorage | RevTurbineStorage | sessionStorage | Session storage override |
RevTurbineContextPolicy
Section titled “RevTurbineContextPolicy”| Field | Type | Default | Description |
|---|---|---|---|
inferUser | boolean | true | Auto-detect user info from browser APIs |
inferPage | boolean | true | Auto-capture URL, title, referrer |
routerAutoTrack | boolean | true | Track SPA route changes |
RevTurbineLocalRuntimeOptions
Section titled “RevTurbineLocalRuntimeOptions”| Field | Type | Description |
|---|---|---|
playbook | Playbook | Full Playbook snapshot for local execution |
placements | LocalPlacementDataset | Optional static placements dataset |
initialData | object | Static data for local decisions (see below) |
resolvers | object | Optional resolver callbacks (see below) |
storageKey | string | Optional localStorage key override |
getContext | () => Promise<JsonObject> | Reactive context callback |
initialData
Section titled “initialData”| Field | Type |
|---|---|
placementDecisionsByPlacementId | Record<string, RevTurbinePlacementDecision> |
userContextByUserId | Record<string, UserTargetingContext> |
trialStatus | RevTurbineTrialContext |
Entitlement grants are evaluated from localRuntime.playbook. For a custom
source, implement the documented checkEntitlement resolver; do not seed
grants through initialData.
Placements work the same way: getPlacement is a pure function of the user
context and localRuntime.playbook, evaluated through the same decision path
as getPlacementDecision and the server SDKs. There is no seeded-output lane:
initialData.placementsByLookupKey was removed in 0.12.0 (ignored since
0.11.21). Author the placement in the Playbook instead, or implement the
getPlacement resolver for a custom source.
resolvers
Section titled “resolvers”| Field | Signature |
|---|---|
getPlacementDecision | (input, placement?, context?) => Promise<RevTurbinePlacementDecision> |
getPlacement | (config) => Promise<PlacementOutput | null> |
checkEntitlement | (handle, context?) => Promise<EntitlementResult> |
fetchUserContext | (userId) => Promise<UserTargetingContext> |
getTrialStatus | () => Promise<RevTurbineTrialContext> |
resolvePlaybook | () => Promise<Playbook> |
RevTurbinePlacementBehaviorFlags
Section titled “RevTurbinePlacementBehaviorFlags”Each flag is derived from the loaded Playbook; an explicit value in placementBehavior overrides the derivation. You rarely need to set them.
| Flag | Type | Derived default | Description |
|---|---|---|---|
enableClientCapsEnforcement | boolean | true when any placement payload authors a cap, cooldown, or remind-later | Client-side cap enforcement |
enableAutoGatedPlacement | boolean | true when the Playbook has a gated placement | Auto-render gated placements |
enableTrialAutoTriggers | boolean | true when the Playbook has a trials placement | Auto-derive trial lifecycle triggers |
RevTurbineEndpointOverrides
Section titled “RevTurbineEndpointOverrides”The calls the SDK makes over the network, and the key that reroutes each one in custom_endpoints mode. None of them is a decision — entitlements and placements are evaluated inside your app in every mode. A relative value is appended to endpoint; an absolute URL replaces it.
| Key | What it carries | Default path |
|---|---|---|
clientContext | Server-derived user context, read with an rt_client_ session token | /api/sdk/client-context |
userContext | User context read | /api/sdk/user-context |
trialStatus | Trial status read | /api/sdk/trial-status |
ingestEvents | Clickstream events (track / capture) | /api/track |
touchpointTransition | Placement interactions — impression, dismiss, CTA | /api/events/interactions |
ingestSdkMeta | The anonymous sdk_init beacon | /api/sdk/meta |
surfaceSlots | Surface-slot inventory registration | /api/placements |
placementTypes | Custom placement-type persistence — meaningful only when overridden | /api/sdk/placement-types |
Not overridable: Playbook delivery. The SDK fetches the launched Playbook from endpoint directly (/api/sdk/bootstrap, then the signed manifest and bundle), so custom_endpoints routes context and telemetry through your proxy but not the Playbook itself.
Keep endpoint pointing at RevTurbine and use absolute override URLs for a proxy on another origin. In local mode, import the Playbook checked into your app. In either mode, preserve the validated artifact: do not insert an app endpoint that reshapes or strips Playbook fields before the SDK reads them. See Runtime Modes.
The type also declares decide, decideContext, bootstrapContext, getPlacement and checkEntitlement. They are retired: the SDK never reads them, because there is no decision endpoint. They remain on the type so existing configurations still compile.
RevTurbineStorage
Section titled “RevTurbineStorage”Interface for custom storage providers:
interface RevTurbineStorage { getItem(key: string): string | null; setItem(key: string, value: string): void; removeItem(key: string): void;}Mode-Specific Required Fields
Section titled “Mode-Specific Required Fields”revturbine_server (default)
Section titled “revturbine_server (default)”{ tenantId?: string; // optional: the key names its tenant publicKey: string; // ✅ Required (public key, browser). `apiKey` is not read here: a server uses a Playbook snapshot instead endpoint?: string; // defaults to 'https://revturbine.com/app' mode?: string; // defaults to 'snippet' ('react' via the provider)}local_only
Section titled “local_only”{ runtimeMode: 'local_only'; // ✅ Required localRuntime: { playbook: Playbook; // ✅ Required }; // tenantId, publicKey, endpoint, mode — optional; no account or key is needed}custom_endpoints
Section titled “custom_endpoints”{ tenantId?: string; // optional: the key names its tenant publicKey: string; // ✅ Required (public key, browser) endpoint?: string; // defaults to 'https://revturbine.com/app' mode?: string; // defaults to 'snippet' ('react' via the provider) runtimeMode: 'custom_endpoints'; // ✅ Required endpointOverrides: { // ✅ At least one override required clientContext?: string; ingestEvents?: string; touchpointTransition?: string; };}Related
Section titled “Related”- Runtime Modes — mode comparison and migration
- Error Codes Reference — error handling options