SDK Guide

Integrate Bandit into any JavaScript or TypeScript application in minutes.

Installation

Install the SDK with your preferred package manager:

npm

npm install @runbandit/sdk

yarn

yarn add @runbandit/sdk

pnpm

pnpm add @runbandit/sdk

Quick Start

Get up and running with just a few lines of code. The example below initializes the client, requests an assignment, renders the variant, and tracks a conversion event.

import { BanditClient } from '@runbandit/sdk'

const bandit = new BanditClient({
  apiUrl: 'https://runbandit.com',
  apiKey: 'your-api-key'
})

// Get the best variant for a user
const assignment = await bandit.getAssignment('experiment-id', 'user-123')

// Show the variant content
document.querySelector('#headline').textContent = assignment.config.content

// Track a named event — which events count as rewards is configured in the dashboard
bandit.trackNamedEvent({
  assignmentId: assignment.assignmentId,
  name: 'purchase',
  value: 29.99
})

Configuration

Pass a configuration object when creating a new BanditClient instance. Only apiUrl and apiKey are required.

OptionTypeDefaultDescription
apiUrlstringrequiredYour API base URL
apiKeystringrequiredYour API key (from dashboard)
timeoutnumber5000Request timeout in ms
batchSizenumber100Max events per batch
flushIntervalnumber10000Auto-flush interval in ms

Methods

getAssignment(experimentId, userId, context?)

Request a treatment assignment for a user. The bandit algorithm selects the best-performing variant based on historical data. When context is provided, contextual bandit algorithms can use it for smarter decisions.

Returns: Promise<Assignment>

Parameters

NameTypeRequiredDescription
experimentIdstringrequiredThe experiment to get an assignment for
userIdstringrequiredUnique identifier for the user
contextContextualFeaturesoptionalOptional contextual features (device type, location, etc.) for contextual bandit algorithms
// Basic assignment
const assignment = await bandit.getAssignment('exp-headline', 'user-123')

// With contextual features
const assignment = await bandit.getAssignment('exp-headline', 'user-123', {
  deviceType: 'mobile',
  location: 'US',
  timeOfDay: 'evening'
})

// Assignment shape
// {
//   assignmentId: "asgn_abc123",
//   treatmentId: "treat_xyz",
//   experimentId: "exp-headline",
//   userId: "user-123",
//   config: { content: "Try it free today!", color: "#4f46e5" }
// }

trackNamedEvent(event)

Track a named event using assignment-based attribution. Events are free-form named strings — which event names count as rewards and trigger bandit algorithm updates is configured per experiment in the dashboard.

Parameters

NameTypeRequiredDescription
assignmentIdstringrequiredThe assignmentId returned from getAssignment()
namestringrequiredFree-form event name (e.g. "purchase", "signup", "button_click"). Configure which names count as rewards in the dashboard.
valuenumberoptionalNumeric value for the event (e.g. revenue amount)
metadataRecord<string, any>optionalArbitrary key-value metadata to attach to the event
// Track a purchase with revenue
bandit.trackNamedEvent({
  assignmentId: assignment.assignmentId,
  name: 'purchase',
  value: 29.99,
  metadata: { product: 'premium-plan' }
})

// Track a signup
bandit.trackNamedEvent({
  assignmentId: assignment.assignmentId,
  name: 'signup'
})

// Track any custom action
bandit.trackNamedEvent({
  assignmentId: assignment.assignmentId,
  name: 'added_to_cart',
  metadata: { sku: 'WIDGET-42' }
})

track(experimentId, treatmentId, userId, name?, value?, metadata?)

Legacy event tracking method that uses explicit IDs instead of an assignmentId. Events are queued and flushed automatically in batches.

Deprecated: Prefer trackNamedEvent() with an assignmentId for precise attribution. The legacy method can misattribute events when a user participates in multiple experiments simultaneously.

Parameters

NameTypeRequiredDescription
experimentIdstringrequiredThe experiment ID
treatmentIdstringrequiredThe treatment ID shown to the user
userIdstringrequiredThe user ID
namestringoptionalEvent name (e.g. "purchase"). Defaults to "conversion".
valuenumberoptionalNumeric value for the event
metadataRecord<string, any>optionalArbitrary key-value metadata
// Legacy tracking (not recommended)
bandit.track(
  'exp-headline',
  'treat-a',
  'user-123',
  'purchase',
  29.99,
  { product: 'premium-plan' }
)

flush()

Manually flush all queued events to the server. Events are normally sent automatically based on the batchSize and flushInterval configuration, but you can force a flush before a page unload or navigation.

Returns: Promise<void>

// Flush before the user leaves the page
window.addEventListener('beforeunload', () => {
  bandit.flush()
})

destroy()

Stop the auto-flush timer and flush any remaining queued events. Call this when your application unmounts or the client is no longer needed to prevent memory leaks.

Returns: void

// React cleanup example
useEffect(() => {
  const client = new BanditClient({ apiUrl, apiKey })
  // ... use client
  return () => client.destroy()
}, [])

// SPA route change cleanup
router.beforeEach(() => {
  bandit.destroy()
})

Named Events

Events are free-form named strings — use any name that makes sense for your product (e.g. purchase, signup, button_click). Which event names count as rewards and trigger bandit algorithm updates is configured per experiment in the dashboard — the SDK just records what happened.

// Track any named event
bandit.trackNamedEvent({
  assignmentId: assignment.assignmentId,
  name: 'purchase',       // any string you choose
  value: 29.99,           // optional numeric value
  metadata: { sku: 'WIDGET-42' }
})

// In the dashboard, add 'purchase' as a reward event for the experiment
// to have it feed the bandit algorithm automatically.

Best Practices

1

Use assignment-based tracking

Always prefer trackNamedEvent() with an assignmentId over the legacy track() method. Assignment-based tracking prevents misattribution when users participate in multiple experiments.

2

Clean up on unmount

Call destroy() when your component or application unmounts. This stops the auto-flush timer and sends any remaining queued events.

3

Let auto-batching work

The SDK automatically batches events and flushes them at the configured interval. Avoid calling flush() after every event -- let the batch system handle it for better performance and fewer network requests.

4

Store the assignmentId

If a conversion can happen later (e.g. a purchase after browsing), persist the assignmentId in localStorage or your session store. This lets you track the conversion accurately even if the user returns in a different session.

SDK Reference — Bandit