SDK Documentation
Published npm packages provide typed client libraries for integrating with the RecomNext engine. Installing a package constitutes acceptance of the SDK License Agreement.
SDK baseUrl for this environment
| Engine API base URL | Admin UI |
|---|---|
| https://api.recomnext.com | https://admin.recomnext.com |
Use the engine base URL as baseUrl in widgets and SDKs.
Browser SDK
Lightweight browser SDK focused on recommendations, real-time event tracking, and scenario attribution. Designed for client-side React, Vue, or vanilla JavaScript applications.
Installation
npm install @recomnext/browser
Setup
import { RecomnextBrowserClient } from '@recomnext/browser';
const recomnext = new RecomnextBrowserClient({
baseUrl: 'https://api.recomnext.com', // see environment table above
tenantId: 'my-tenant',
publicToken: 'rnx_pub_...', // when browser signing is enabled
userId: 'user-123', // optional — your stable ID
});Unified Recommend API
// The preferred way to fetch recommendations
const response = await recomnext.recommend({
scenario: 'homepage-for-you',
count: 8,
returnProperties: true,
includedProperties: ['attributes.name', 'attributes.price', 'attributes.image', 'category'],
});
for (const item of response.items) {
console.log(item.itemId);
}Lean Projection Mode
// Lean mode for minimal payload transfer
const lean = await recomnext.recommend({
scenario: 'pdp-similar',
count: 10,
returnProperties: false,
});
for (const item of lean.items) {
const scoreLabel = item.score != null ? item.score.toFixed(2) : 'N/A';
console.log(item.itemId, scoreLabel);
}Signed Request Placement (publicToken)
Browser signing follows strict placement: GET recommendation routes sign projection in query, and POST items-to-items signs projection in the JSON body.
Omit projection keys for backward-compatible full payloads. Set returnProperties=false for lean identity-first payloads when your UI does not require attributes.
User identity
Pass your own user ID at init or after login. When userId is omitted, the SDK generates a browser session ID (sess_… in sessionStorage) and uses it for recommendations and event tracking.
// Optional at init
const recomnext = new RecomnextBrowserClient({
baseUrl: 'https://api.recomnext.com',
tenantId: 'my-tenant',
userId: 'customer-42',
});
// Or set after you know the authenticated user
recomnext.setUserId('customer-42');
// Link anonymous session history to the logged-in account (call once after login)
await recomnext.mergeIdentity('customer-42');Widgets accept the same IDs via data-user-id or the React userId prop — see the Widgets user identity guide. After login, call mergeIdentity so anonymous session history attaches to the authenticated user. When your tenant has auto user provisioning enabled (the default), the engine creates a minimal catalog user on identity merge and on the first known interaction — use upsertUsers when you need to sync attributes or bulk-import users from your IDP.
Browser SDK — event tracking
All tracking methods accept an optional scenarioSlug parameter. Omit it for site-wide events (search, direct PDP, order webhooks). Provide it when the item came from a named recommendation placement.
// Site-wide — no scenario
recomnext.trackView('prod-001');
recomnext.trackCart('prod-001');
recomnext.trackPurchase('prod-001');
// With placement attribution
recomnext.trackView('prod-001', 'homepage-for-you');
recomnext.trackCart('prod-001', 'pdp-related');
recomnext.trackPurchase('prod-001', 'cart-upsell');Impression Tracking
Uses `IntersectionObserver` to automatically detect when recommendation cards become visible. Impressions are batched and flushed every 2 seconds for efficiency.
const cleanup = recomnext.trackImpressions(document.querySelector('.recs'), {
scenario: 'home-for-you',
itemSelector: '[data-item-id]', // CSS selector for individual item cards
threshold: 0.5, // 50% visibility required
once: true, // Only track the first time an item is seen
});
// Call cleanup when the component unmounts
cleanup();Key Methods
| Method | Description |
|---|---|
| recommend(opts) | Unified recommendation fetcher — uses scenario or logicType |
| getRecommendations(userId, count, scenario?) | Legacy personalized "For You" fetcher |
| getRelatedItems(itemId, count, scenario?) | Legacy item-to-item fetcher |
| getSimilarProducts(itemId, count, scenario?) | Legacy vector-similar fetcher |
| getItemsToItems(itemIds, opts?) | Legacy cart-style fetcher (POST body supports projection keys) |
| trackView(itemId, scenarioSlug?) | Log item view interaction event |
| trackCart(itemId, scenarioSlug?) | Log cart interaction event |
| trackPurchase(itemId, scenarioSlug?) | Log purchase interaction event |
| trackImpressions(container, opts) | Start automatic impression tracking for a list of items |
| mergeIdentity(authenticatedUserId) | Link anonymous session history to the logged-in user ID |
| setUserId(newUserId) | Update the user ID for the current session |
Projection and Type Notes
| Type/Option | Details |
|---|---|
| returnProperties?: boolean | Default true. false returns lean item payload for lower transfer cost. |
| includedProperties?: string[] | Exact raw item paths only (for example attributes.name). Field mapper aliases are not auto-resolved. |
| RecommendedItem.score?: number | Migration note: score changed from required to optional. Guard all access (item.score != null ? item.score.toFixed(2) : "N/A") to avoid runtime failures. |
| RecommendedItem.externalId | Deprecated alias in recommendation responses only. Catalog ingestion still uses externalId as the item identity key. Prefer itemId in new response consumers. |
Node.js SDK
Server-side Node.js/TypeScript SDK with built-in retry logic, timeouts, and full coverage of the engine REST API. Requires Node.js 18+ for native fetch support.
Installation
npm install @recomnext/node
Setup
import { RecomnextClient } from '@recomnext/node';
const client = new RecomnextClient({
baseUrl: 'https://api.recomnext.com',
tenantId: 'my-tenant',
retries: 3, // default: 3
timeout: 10000, // default: 10s
});API Namespaces
| Namespace | Description | Key Methods |
|---|---|---|
| client.ingestion | Data synchronization | upsertItems(), upsertUsers(), logInteractions(), logImpressions() |
| client.recommendations | Fetching results | recommend(), userToItem(), itemToItem(), itemsToItems(), similarProducts() |
| client.scenarios | Logic management | list(), get(), create(), update(), delete() |
| client.segmentations | Diversity config | list(), get(), create(), listSegments() |
| client.catalog | Inspecting data | listItems(), getItem(), listUsers(), getUser() |
| client.identity | User mapping | merge() |
Tenant settings APIs are currently documented in the HTTP API reference (GET/PUT /catalog/tenant-settings). The Node SDK catalog namespace does not yet expose dedicated helpers for these endpoints.
Bulk Ingestion Example
// Sync items to RecomNext
await client.ingestion.upsertItems([
{
externalId: 'prod-001', // catalog identity key (not deprecated for ingestion)
category: 'electronics',
attributes: {
name: 'Smartphone Pro',
price: 999.99,
tags: ['5g', 'high-performance']
}
}
]);
// Log batch of interactions
await client.ingestion.logInteractions([
{ userId: 'user-1', itemId: 'prod-001', type: 'view' },
{ userId: 'user-2', itemId: 'prod-001', type: 'purchase', weight: 10 }
]);Recommendation Projection Example
const response = await client.recommendations.recommend({
scenario: 'pdp-similar',
itemId: 'prod-001',
count: 6,
returnProperties: true,
includedProperties: ['attributes.name', 'attributes.price', 'attributes.image', 'category'],
});
for (const item of response.items) {
const scoreLabel = item.score != null ? item.score.toFixed(3) : 'N/A';
console.log(item.itemId, scoreLabel);
}Signed Request Placement Contract
When using signing tokens, SDKs keep projection placement aligned with engine verification: GET recommendation routes sign projection in query, while POST items-to-items signs projection in the request body.
Scenario Management Example
// Create a scenario programmatically
const scenario = await client.scenarios.create({
name: 'Search Boosted Results',
slug: 'search-boosted',
logicType: 'user-to-item',
filter: "'stock' > 0",
boosters: ["boost by 1.5 where 'promo' = true"],
constraints: { maxPerCategory: 2 }
});
// Update an existing scenario
await client.scenarios.update('search-boosted', {
minItems: 4
});