Skip to content

Getting Started

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:

Terminal window
npm install -g @revturbine/cli
revturbine --help

Add the SDK to your React app:

Terminal window
npm install @revturbine/sdk

Create an account in the studio, then connect the CLI to it.

  1. Create your account. Sign up at the studio — www.revturbine.com/app — or headlessly from the terminal:

    Terminal window
    revturbine signup
  2. Authorize the CLI on this machine. This opens a browser device-flow login against your account:

    Terminal window
    revturbine login

    Your token is stored at ~/.revturbine/credentials.json (mode 0600) and scoped to your tenant.

  3. Confirm you’re connected. status shows your active config and recent releases:

    Terminal window
    revturbine status

Wrap your app once, then add slots (where placements render) and gates (entitlement checks).

  1. 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).

    src/App.tsx
    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>
    );
    }
  2. 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.

    src/components/Dashboard.tsx
    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.

  3. Gate a feature. Use useEntitlement to check access by entitlement handle and react to the result. When denied, surface an upgrade prompt.

    src/components/BatchExport.tsx
    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):

Terminal window
revturbine verify ./exported_config.json # schema-validate locally, no writes
revturbine diff # compare your file against the live config
revturbine upload ./exported_config.json # stage a draft change set
revturbine deploy # submit → approve → deploy the draft

Decisioning, 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 |