API Reference

Configuration

When initializing Renumerate, pass a configuration object with the following options:

Option Type Description
getAuthToken () => Promise<string> Required. Returns a handshake token from your backend
debug boolean Enable debug logging (optional)
fallbackEmail string Fallback support email for service failures (optional)
callbacks CallbackOptions Default callbacks for all flows (optional)

getAuthToken (Required)

The getAuthToken callback is called by the SDK when it needs to establish or refresh a session. Your callback should fetch a handshake token from your backend API.

const renumerate = new Renumerate({
  getAuthToken: async () => {
    const response = await fetch('/api/renumerate-token');
    const { token } = await response.json();
    return token;
  },
  fallbackEmail: 'support@yourcompany.com'
});

fallbackEmail

The fallbackEmail option provides a safety net for your customers in the rare event that Renumerate's service experiences an extended outage. When the service is unavailable, customers will see a friendly error message with your support email.

Recommended

We recommend always setting a fallbackEmail to ensure your customers can reach you even if our service is temporarily unavailable.


Handshake Token Structure

Handshake tokens are HMAC-signed tokens that authenticate your users to Renumerate. They consist of two parts separated by a dot: {base64url(payload)}.{base64url(signature)}

Payload Fields

Field Type Description
brandPub string Your brand's public key (e.g., pk_live_xxx)
subscriberId string The customer's Stripe customer ID
timestamp number Unix timestamp in milliseconds
nonce string Random string for replay prevention

Token Security

  • Tokens are valid for 5 minutes from the timestamp
  • Each token should have a unique nonce to prevent replay attacks
  • The private key must be kept secret on your backend
  • Tokens should only be generated for authenticated users

Callbacks

Add callback functions to respond to retention flow events:

Callback Description
onComplete Called when the flow is finished
onRetained Called when the customer is retained
onCancelled Called when the customer cancels
renumerate.showRetentionView(undefined, {
  onRetained: () => window.location.reload(),
  onCancelled: () => window.location.href = "/goodbye",
  onComplete: () => console.log("Retention flow completed")
});

Session Management

The SDK automatically manages sessions for you:

  1. When you call any method that requires authentication, the SDK calls your getAuthToken callback
  2. The SDK exchanges the handshake token for a session via POST /v1/session/exchange
  3. Sessions are cached in sessionStorage and reused until they expire (24 hours)
  4. If a session expires, the SDK automatically calls getAuthToken again to refresh

Manual Session Control

// Get current session (establishes if needed)
const session = await renumerate.getSession();

// Force refresh the session
const newSession = await renumerate.refreshSession();

// Clear the session
renumerate.clearSession();

React Components

RenumerateProvider

Context provider that must wrap all Renumerate components:

<RenumerateProvider config={{ getAuthToken }}>
  {children}
</RenumerateProvider>

SubscriptionHub

Embeds the full subscription management widget:

<SubscriptionHub
  wrapperClassName="h-96 w-full"
  iframeClassName="w-full h-full"
  loadingComponent={<div>Loading...</div>}
  errorComponent={<div>Error loading hub</div>}
  callbacks={{ onCancelled: () => {} }}
/>

CancelButton

Renders a cancel button that triggers the retention flow:

<CancelButton
  className="btn-cancel"
  subscriptionId="sub_xxx"
  callbacks={{ onRetained: () => {} }}
>
  Cancel Subscription
</CancelButton>

React Hooks

useRenumerate

const { open, isReady } = useRenumerate({
  subscriptionId?: string,
  callbacks?: CallbackOptions
});

useRenumerateContext

const {
  session,
  isSessionLoading,
  sessionError,
  refreshSession
} = useRenumerateContext();

Vanilla JS Methods

mountSubscriptionHub

renumerate.mountSubscriptionHub(
  elementId: string,
  wrapperClasses?: string,
  iframeClasses?: string,
  callbacks?: CallbackOptions
): Promise<void>

mountCancelButton

renumerate.mountCancelButton(
  elementId: string,
  options?: {
    classes?: string,
    subscriptionId?: string,
    ...CallbackOptions
  }
): void

showRetentionView

renumerate.showRetentionView(
  subscriptionId?: string,
  callbacks?: CallbackOptions
): Promise<void>

Incentivized Surveys

Display proactive feedback surveys with discount incentives to gather customer insights. Surveys are configured in the Renumerate dashboard under Pulse.

React: SurveyPrompt Component

Automatically shows a survey prompt when one is available:

<SurveyPrompt
  lookupKey="feedback"      // Only show surveys with this key
  onComplete={() => {}}     // Called when survey is completed
  onDismiss={() => {}}      // Called when user dismisses
  autoShow={true}           // Auto-show when available (default: true)
/>

React: useSurveys Hook

For manual control over survey display:

const {
  survey,              // SurveySession | null - available survey
  brandStyles,         // BrandStyles - for custom rendering
  isLoading,           // boolean
  error,               // Error | null
  showSurveyPrompt,    // (callbacks?) => Promise<void>
  dismissSurveyPrompt, // () => Promise<void>
  refresh              // () => Promise<void> - re-check for surveys
} = useSurveys({ lookupKey: 'feedback' });

// Show survey when ready
if (survey) {
  await showSurveyPrompt({
    onComplete: () => console.log('Done!'),
    onDismiss: () => console.log('Dismissed')
  });
}

SurveySession Object

Field Type Description
lookupKey string Unique identifier for this survey type
sessionId string Survey session ID (srv_...)
name string | null Customer-facing survey name
description string | null Customer-facing description
incentiveTeaser string | null Discount teaser (e.g., "15% off")
enabledComponents string[] Which survey sections are enabled

Vanilla JS: checkSurveys

const { survey, brandStyles } = await renumerate.checkSurveys({
  lookupKey?: string  // Optional: only check for this survey key
});

// survey is SurveySession | null
// brandStyles contains colors for custom rendering

Vanilla JS: showSurveyPrompt

await renumerate.showSurveyPrompt(
  survey: SurveySession,
  brandStyles: BrandStyles,
  callbacks?: {
    onComplete?: () => void,
    onDismiss?: () => void
  }
)

Vanilla JS: dismissSurveyPrompt

await renumerate.dismissSurveyPrompt()

Survey Callbacks

Callback Description
onComplete Called when the survey is completed (discount applied/offered)
onDismiss Called when the user dismisses the survey prompt