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
country: 'IN', // optional ISO-2 default for recommend + track*
});Unified Recommend API
// The preferred way to fetch recommendations
const response = await recomnext.recommend({
scenario: 'homepage-for-you',
count: 8,
country: 'IN', // optional — overrides the client default
returnProperties: true,
includedProperties: ['attributes.name', 'attributes.price', 'attributes.image', 'category'],
// Optional request-time overrides (omit to keep scenario values):
// filter: "'stock' > 0",
// boosters: ["boost by 1.2 where 'featured' = true"],
// rulesSlugs: ['in-stock'],
});
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');
// Optional market default for recommend + track* (ISO-2; invalid/OTH → global)
recomnext.setCountry('IN');
// 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 and optional country. Omit the slug for site-wide events (search, direct PDP, order webhooks). Provide it when the item came from a named recommendation placement. Omit country (or send OTH) to tag the event as global.
// 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');
// Per-call country override (otherwise the client default is sent)
recomnext.trackView('prod-001', { scenarioSlug: 'homepage-for-you', country: 'DE' });
recomnext.trackPurchase('prod-001', { country: 'IN' });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',
country: 'IN', // optional — overrides the client default
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; opts.country overrides the client default |
| 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? | opts) | Log item view; opts.country overrides the client default |
| trackCart(itemId, scenarioSlug? | opts) | Log cart; same country override as trackView |
| trackPurchase(itemId, scenarioSlug? | opts) | Log purchase; same country override as trackView |
| trackImpressions(container, opts) | Start automatic impression tracking; opts.country optional |
| mergeIdentity(authenticatedUserId) | Link anonymous session history to the logged-in user ID |
| setUserId(newUserId) | Update the user ID for the current session |
| setCountry(code) | Default ISO-2 for recommend + track* until overridden per call |
Projection and Type Notes
| Type/Option | Details |
|---|---|
| country?: string | ISO-3166-1 alpha-2 on the client, recommend(), and track*. Missing, invalid, or OTH ranks/tags globally. |
| 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', country: 'IN' },
{ 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,
country: 'IN', // optional ISO-2; omit for global ranking
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',
// contains/not_contains: array item attrs only (fail-closed if missing)
filter: "'allowed_countries' contains 'IN'",
boosters: ["boost by 1.5 where 'promo' = true"],
constraints: { maxPerCategory: 2 }
});
// Update an existing scenario
await client.scenarios.update('search-boosted', {
minItems: 4
});Recommendation filter / boosters are opaque nextQL strings. Use contains / not_contains only for array item attributes; use in / not_in when the filter supplies the list. Missing or non-array attrs fail closed — for denylists every item must have the array ([] = not blocked).
Filter auto-relax (query planning)
Opt-in scenario flags autoRelaxFilters / relaxEntireFilterOnEmpty (default off). Put durable clauses on the left, soft ones on the right. When relaxation applies, read filterRelaxation.droppedClauses / effectiveFilter for UX copy. Full checklist: Scenarios — Query planning for filter auto-relax.
const res = await client.recommendations.recommend({ scenario: 'pdp', itemId: 'x', count: 8 });
if (res.filterRelaxation?.droppedClauses?.length) {
console.log('Showing without:', res.filterRelaxation.droppedClauses);
}