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.
| Option | Type | Default | Description |
|---|---|---|---|
| apiUrl | string | required | Your API base URL |
| apiKey | string | required | Your API key (from dashboard) |
| timeout | number | 5000 | Request timeout in ms |
| batchSize | number | 100 | Max events per batch |
| flushInterval | number | 10000 | Auto-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
| Name | Type | Required | Description |
|---|---|---|---|
| experimentId | string | required | The experiment to get an assignment for |
| userId | string | required | Unique identifier for the user |
| context | ContextualFeatures | optional | Optional 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
| Name | Type | Required | Description |
|---|---|---|---|
| assignmentId | string | required | The assignmentId returned from getAssignment() |
| name | string | required | Free-form event name (e.g. "purchase", "signup", "button_click"). Configure which names count as rewards in the dashboard. |
| value | number | optional | Numeric value for the event (e.g. revenue amount) |
| metadata | Record<string, any> | optional | Arbitrary 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.
trackNamedEvent() with an assignmentId for precise attribution. The legacy method can misattribute events when a user participates in multiple experiments simultaneously.Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| experimentId | string | required | The experiment ID |
| treatmentId | string | required | The treatment ID shown to the user |
| userId | string | required | The user ID |
| name | string | optional | Event name (e.g. "purchase"). Defaults to "conversion". |
| value | number | optional | Numeric value for the event |
| metadata | Record<string, any> | optional | Arbitrary 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
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.
Clean up on unmount
Call destroy() when your component or application unmounts. This stops the auto-flush timer and sends any remaining queued events.
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.
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.