Skip to content

RevTurbineCustomerSdk

The core RevTurbine customer-facing SDK.

Provides methods for:

  • Identityidentify(), resetIdentity()
  • PlacementsregisterPlacement(), getPlacementDecision(), getPlacement()
  • EntitlementscheckEntitlement(), updateUsage()
  • TrialsgetTrialStatus()
  • Eventscapture(), trackEvent(), emitSemantic()
  • InteractionstrackTreatmentInteraction(), dismiss(), convert()
  • ContextsetUserContext(), setPageContext(), refreshPageContext()
const sdk = initRevTurbine({
tenantId: 'tenant_abc',
apiKey: 'rt_live_xxx',
endpoint: 'https://api.revturbine.io',
mode: 'react',
});
sdk.identify('user_123', { plan: 'pro' });
const decision = await sdk.getPlacementDecision({ placementId, userId: 'user_123' });

can(handle, context?): Promise<{ }>

Check whether the user can do something — the advertised alias of checkEntitlement. Returns the rich EntitlementResult (allowed, status, reason, limits, enforcement). For billing-critical entitlements, confirm enforcement === 'server_required' on your backend.

string

RevTurbineEntitlementContext

Promise<{ }>

const access = await rt.can('generate_image');
if (!access.allowed) showUpgrade();

dispose(): void

Stop background clickstream flushing and release page-unload listeners. Flushes any buffered events one last time. Call when tearing down an SDK instance (e.g. SPA unmount) to avoid a dangling interval/listeners.

void


emitTrigger(trigger, payload?, options?): Promise<void>

Emit a canonical trigger event recognised by the decision engine.

Convenience wrapper over emitSemantic that constrains the event name to RevTurbineTriggerEvent and attaches standard context (user_id, plan, timestamp) automatically.

"trial_midpoint" | "trial_expiring" | "trial_expired" | "usage_limit_approaching" | "usage_limit_reached" | "credit_balance_low" | "seat_limit_reached" | "feature_gated" | "cancel_intent" | "payment_failed" | "auto_renewal_reminder" | "onboarding_complete" | "invite_teammate_prompt" | "referral_offer" | "plan_upgrade_nudge"

RevTurbineTriggerPayload

RevTurbineEventOptions

Promise<void>

await sdk.emitTrigger('usage_limit_approaching', { usage_percent: 85, threshold: 80 });
await sdk.emitTrigger('trial_expiring', { days_remaining: 2 });
await sdk.emitTrigger('feature_gated', { feature: 'advanced_automation' });

explainPlacementDecision(input): Promise<RevTurbinePlacementDecisionExplanation>

Explain why a placement decision was selected.

Returns a structured diagnostic payload that includes:

  • Segment membership evaluation with predicate-level pass/fail details
  • Entitlement-rule matching outcomes for current targeting context
  • Placement decision metadata (rule_id, reason codes, suppression)

Useful for debuggers, QA tooling, and customer-facing explainability UIs.

RevTurbinePlacementDecisionInput

Promise<RevTurbinePlacementDecisionExplanation>


fetchUserContext(userId): Promise<UserTargetingContext>

Fetch the resolved user context from the decision API. Returns the user’s matched segments, traits, plan, and usage — used to determine which placement payloads are eligible for display.

string

Promise<UserTargetingContext>


flushEvents(): Promise<void>

Flush any buffered clickstream events to POST /api/track immediately.

Called on the size threshold, the RevTurbineEventBatchingOptions interval timer, and page-unload. Best-effort and non-throwing — delivery failures are swallowed (plan 95 REQ-3). Safe to call when the buffer is empty (no-op).

Promise<void>


gate<T>(action, fn, context?): Promise<RevTurbineGateResult<T>>

Gate an action behind an entitlement — the advertised gate(action, fn) verb. Checks the entitlement for action; if allowed, runs fn and returns its result; otherwise does NOT run fn and returns the entitlement so the caller can surface a paywall (e.g. render an <RTSlot>). See RevTurbineGateResult.

T

string

() => T | Promise<T>

RevTurbineEntitlementContext

Promise<RevTurbineGateResult<T>>

const gated = await rt.gate('export_pdf', () => exportPdf());
if (!gated.ran) openPaywall(gated.entitlement);

getEntitlements(): Record<string, EntitlementResult>

Return the SDK-resolved entitlement snapshot for the active user.

The returned object is keyed by entitlement handle and reflects the latest results from local/runtime checks tracked by the SDK.

Record<string, EntitlementResult>


getExportedConfig(): { } | undefined

Returns the RevTurbineConfig snapshot loaded at initialization, if any. Available only in local_only mode when exportedConfig was provided.

{ } | undefined


getPersonalizationTokens(payload?): RevTurbinePersonalizationTokens

Return the SDK-resolved personalization token map.

Reads from the transient personalization map on the user context, which holds both SDK-derived tokens (plan_name, usage_current, etc.) and app-provided tokens set via setPersonalization() or identify().

Pass the placement’s payload (its recommendation_strategy / recommendation_plan_override fields) to resolve the {{recommended_plan_handle}} / {{recommended_plan_name}} tokens for that specific placement (plan #47, Appendix C.3). Without a payload the map carries the user-level next_tier_up default; with one, the placement’s authored strategy (e.g. a custom forced plan) overlays those two tokens. All other tokens are unaffected.

Optional placement payload carrying the per-placement recommendation strategy. Omit for the user-level default.

string | null

RecommendationStrategy | null

RevTurbinePersonalizationTokens


getPolicy(): RevTurbinePolicySnapshot

Return current SDK policy snapshot.

RevTurbinePolicySnapshot


getTargeting(): RevTurbineTargeting

Return the SDK-resolved targeting snapshot for the active user.

Includes user id, segment ids, traits, plan, and merged usage so demo surfaces can display the same context used by placement eligibility.

RevTurbineTargeting


getUsage(): RevTurbineUsageSnapshot

Return the SDK-resolved usage snapshot for the active user.

Keys are usage units (derived from configured usage token prefixes when available), and values include current usage plus optional limit when known.

RevTurbineUsageSnapshot


getUserContext(): object

Build the full persistence-ready UserContext from the current SDK state. Includes tenant_id and user_id required for API storage.

object


hydrate(payload): void

Hydrate the SDK with a server-evaluated payload.

Call this on the client after receiving a ServerEvaluationPayload from the server-side SDK. Pre-populates the decision cache, entitlements, trial status, and user context so the client SDK avoids redundant API calls.

void

// In your React component / page hydration:
const sdk = initRevTurbine({ tenantId, apiKey, endpoint, mode: 'react' });
sdk.hydrate(serverPayload);

recordClickThru(placementId, payloadId?, surfaceTemplateId?, metadata?): Promise<void>

Record a placement click-through — the user engaged with the CTA. The placement is permanently retired for this user.

string

The placement’s stable rule_id.

string

Optional payload variant id.

string

Optional surface template id.

RevTurbineImpressionMetadata

Optional metadata persisted with the record.

Promise<void>


recordDismissal(placementId, payloadId?, surfaceTemplateId?, metadata?): Promise<void>

Record a placement dismissal — the user explicitly closed it. The placement is permanently retired for this user; subsequent getPlacementDecision calls return visible: false.

string

The placement’s stable rule_id.

string

Optional payload variant id.

string

Optional surface template id.

RevTurbineImpressionMetadata

Optional metadata persisted with the record.

Promise<void>


recordImpression(placementId, payloadId?, surfaceTemplateId?, metadata?): Promise<void>

Record that a placement was rendered to the user. Plan 43 TASK-9.

Writes an impressed record to the SDK’s ImpressionHistory, which persists to localStorage via StorageImpressionStore (or in-memory storage in non-browser environments). The impression contributes to:

  • Frequency caps (cap.v1) — once-per-period limits count this impression against the user’s quota for the placement.
  • Trial milestone supersession analytics — for trial_progress ladders, the supersession diagnostic uses delivery state to distinguish “replaced an undelivered placement” (counts in superseded_placement_ids) from “lower threshold was already shown” (NOT counted — spec §3.5 “supersession only applies to undelivered placements”).
  • Generic milestone supersession (content.milestone_order) — the order-based variant in applyContentMilestoneSupersession.

Call this from consumer code when the placement is actually shown to the user (e.g., from a React component’s useEffect on mount, or after the rendering call returns). The SDK does NOT auto-record impressions — surfaces are rendered by consumer code, so only the consumer knows when a placement was actually presented (vs. fetched but not displayed).

Safe to call multiple times for the same placement — duplicates append additional impression records (used by frequency caps to count delivery events).

string

The placement’s stable rule_id (e.g. 'pl_trial_progress_70'). Match decision.output.rule_id from getPlacementDecision.

string

Optional payload variant id, for variant-level analytics.

string

Optional surface template id, for per-surface cap accounting.

RevTurbineImpressionMetadata

Optional metadata persisted with the record.

Promise<void>

const decision = await sdk.getPlacementDecision({ placementId: 'slot_trial_modal' });
if (decision.visible && decision.output?.rule_id) {
renderBanner(decision.output);
await sdk.recordImpression(decision.output.rule_id, decision.output.output_id);
}

registerPlacement(config): Promise<string>

RevTurbinePlacementConfig

Promise<string>


reset(): void

Clear the current user — the advertised alias of resetIdentity (e.g. on sign-out).

void


resetUserContext(): void

Hard-reset the user context to a blank slate — removes EVERY user-context value (id, plan, email, account_id, custom, usage, entitlements, personalization) plus usage balances, and clears the decision cache, interaction state, and impression history.

Unlike resetIdentity (a sign-out that re-infers anonymous context when the inferUser policy is on), this performs no inference, so the resulting context is guaranteed empty. Mostly for demo / fixture flows that reset cleanly between scenarios.

void

// Between demo personas:
rt.resetUserContext();
rt.identify('demo_pro', { plan: { id: 'pro', name: 'Pro' } });

track(name, data?): Promise<void>

Track an event — the advertised alias of trackEvent. Powers analytics, frequency caps, attribution, and experiments.

string

SdkEventProperties

Promise<void>

rt.track('ai_generation_completed', { credits: 3 });

trackControlPlaneEvent(eventType, payload?, options?): Promise<void>

Emit a typed control-plane semantic event (plan 112).

The dogfood-faithful surface for RevTurbine’s own product activity: eventType is constrained to the canonical ControlPlaneEventType taxonomy and the system/workflow source classification is stamped automatically. Forwards through the same ingest + consumer path as capture — so the event lands in clickstream AND any registered analytics resolver (e.g. a PostHog provider from createPostHogAnalyticsProvider).

Identity comes from the active user context set via identify / setUserContext: the operator is user_id and the acting RevTurbine customer tenant is account_id. tenant_id is stamped server-side and is never carried on the event (plan 112 REQ-3/REQ-4).

"web_signed_up" | "web_signed_in" | "cli_signed_up" | "cli_signed_in" | "cli_command_executed" | "changeset_submitted" | "changeset_approved" | "changeset_rejected" | "changeset_deployed" | "changeset_launched" | "changeset_parked" | "changeset_resumed" | "changeset_discarded" | "changeset_archived" | "config_imported" | "config_exported" | "entity_created" | "entity_updated" | "entity_deleted"

A canonical control-plane event type.

SdkEventProperties = {}

Optional event-specific properties (e.g. { resource, resource_id }).

RevTurbineEventOptions

Emit options, e.g. { immediate: true } to bypass batching.

Promise<void>

sdk.identify('operator_42', { account_id: 'tn_acme' });
await sdk.trackControlPlaneEvent('changeset_deployed', { change_set_id: 'cs_9' });

update(patch): void

Patch customer-reported usage — the advertised update({ usage }) verb, delegating to updateUsage. For identity or full user-context changes use identify / setUserContext.

RevTurbineUpdateInput

void

rt.update({ usage: { generations: 25 } });

validateUiPathResolvers(options?): Promise<RevTurbineUiPathResolverValidationReport>

Validate that each configured UI path action has a resolver implementation.

By default this validates localRuntime.exportedConfig.content_ui_paths (when present) against:

  • uiPathResolvers passed at SDK init
  • optional resolvers passed to this method
  • CTA handlers from domain providers (domain: 'cta'), unless disabled

RevTurbineUiPathResolverValidationOptions = {}

Promise<RevTurbineUiPathResolverValidationReport>