RevTurbine UI (studio)
Edit visually at www.revturbine.com/app — define plans, entitlements, targeting rules, and placements, preview their impact, and deploy. Export an exported_config.json snapshot anytime for local mode.
RevTurbine is web SaaS monetization in a single SDK: placement decisioning, entitlements, and conversion experiments — without a code deploy for every change. This guide takes you from install to a live placement and entitlement gate, then shows how to manage your monetization config.
It’s additive — if RevTurbine is disconnected, misconfigured, or every placement is paused, your product keeps working and slots simply render nothing.
Two packages, both on the public npm registry — no auth token or registry config.
@revturbine/cli — manage your monetization config (plans, entitlements, placements) and change sets from the terminal.@revturbine/sdk — render placements and check entitlements in your app.Install the CLI globally:
npm install -g @revturbine/clirevturbine --helpAdd the SDK to your React app:
npm install @revturbine/sdkpnpm add @revturbine/sdkyarn add @revturbine/sdkCreate an account in the studio, then connect the CLI to it.
Create your account. Sign up at the studio — www.revturbine.com/app — or headlessly from the terminal:
revturbine signupAuthorize the CLI on this machine. This opens a browser device-flow login against your account:
revturbine loginYour token is stored at ~/.revturbine/credentials.json (mode 0600) and scoped to your tenant.
Confirm you’re connected. status shows your active config and recent releases:
revturbine statusWrap your app once, then add slots (where placements render) and gates (entitlement checks).
Wrap your app in RevTurbineProvider. This example runs in local_only mode — no backend, no network calls — from an exported_config.json you ship with your app (see step 4 for where it comes from).
import { RevTurbineProvider } from '@revturbine/sdk';import exportedConfig from './exported_config.json';import { useMemo } from 'react';
function App() { const options = useMemo(() => ({ localRuntime: { exportedConfig }, user: { id: 'user_123', context: { plan_handle: 'starter' } }, // UI path resolvers connect placement CTAs to your app's navigation. uiPathResolvers: { navigate_to_plans: () => { window.location.href = '/pricing'; }, open_checkout_modal: (ctx) => { console.log('Checkout:', ctx.plan_handle); }, }, }), []);
return ( <RevTurbineProvider options={options}> <YourApp /> </RevTurbineProvider> );}Add a slot. Drop a surface slot where you want a placement to appear. It renders the matching placement for the current user — or nothing.
import { FixedSurfaceSlot } from '@revturbine/sdk';
function Dashboard() { return ( <div> <h1>Dashboard</h1> {/* RevTurbine renders an upgrade banner here — or nothing */} <FixedSurfaceSlot id="dashboard_top_banner" surfaceTemplateIds={["banner_placement"]} /> </div> );}FixedSurfaceSlot covers banners, modals, in-page content, and buttons. For event-triggered messages use MessageSurfaceSlot, or drive rendering yourself with the usePlacement hook.
Gate a feature. Use useEntitlement to check access by entitlement handle and react to the result. When denied, surface an upgrade prompt.
import { useEntitlement } from '@revturbine/sdk';
function BatchExport() { const { allowed, denied, limited, result } = useEntitlement({ handle: 'batch_export' });
if (denied) return <UpgradePrompt reason={result?.reason} />; if (limited) return <UsageWarning remaining={result?.remaining} />; return <BatchExportButton enabled={allowed} />;}To render a configured upgrade placement automatically on denial, use AccessGateSurfaceSlot instead — it resolves and renders the deny-state placement for you. For an imperative check (e.g. server-side or in an event handler), call sdk.checkEntitlement('batch_export'). See the Entitlements guide.
Your monetization model — plans, entitlements, entitlement rules, segments, surface templates, and placements — is a single portable snapshot called an ExportedConfig. It’s what the SDK reads (bundled in local mode, or served live), and you can author it two ways.
RevTurbine UI (studio)
Edit visually at www.revturbine.com/app — define plans, entitlements, targeting rules, and placements, preview their impact, and deploy. Export an exported_config.json snapshot anytime for local mode.
RevTurbine CLI + Agent
Treat config as code. Author or edit it by hand — or with the RevTurbine AI agent (in the studio, or via an MCP-connected coding agent) — then validate and ship it from the terminal.
The CLI ships config through reviewable change sets (draft → submit → approve → deploy):
revturbine verify ./exported_config.json # schema-validate locally, no writesrevturbine diff # compare your file against the live configrevturbine upload ./exported_config.json # stage a draft change setrevturbine deploy # submit → approve → deploy the draftDecisioning, not just rendering
RevTurbine decides — caps, cooldowns, eligibility, priority across competing placements, and ML-scored propensity for conversion, expansion, and retention nudges. One getPlacement() call returns the winner. No client-side orchestration, no homegrown segment logic.
Entitlements and placements in one engine, linked to billing
getPlacement() surfaces usage warnings, trial nudges, and lifecycle prompts tied to billing state; checkEntitlement() confirms or denies feature access. Pair them to gate a feature and surface the customer-specific upgrade prompt that converts it. Like RevenueCat for SaaS.
PM- and marketer-controlled, dev-decoupled
Drop a slot once. Your PM, growth, marketing, or CRO team changes content, targeting, and CTAs in the studio — no engineering tickets, no deploys. UI path resolvers keep the navigation contract in your code; everything else iterates without you.
| Capability | Method | Description |
|---|---|---|
| Placements | getPlacement() | Render upgrade banners, modals, toasts, and buttons based on targeting rules |
| Entitlements | checkEntitlement() | Gate features, enforce usage limits, check credits and seats |
| Usage tracking | updateUsage() | Track consumption for quota meters and passive placement triggers |
| Events | trackEvent() | Behavioral signals for propensity scoring |
| Interactions | dismiss() / snooze() / convert() | CTA lifecycle tracking |
| Trial status | getTrialStatus() | Current trial state and countdown |