Skip to main content
The SDK is a lightweight TypeScript client with built-in event batching, automatic retries, and structured logging for the NeuronSearchLab API.Need PHP instead? View the PHP SDK guide or install it from Packagist.

Installation

npm install @neuronsearchlab/sdk
The SDK ships with TypeScript declarations — no additional type packages needed.

Initialize the client

The SDK uses a Bearer token for authentication. Obtain an access token by exchanging your SDK credentials and pass it when creating the client:
import NeuronSDK from "@neuronsearchlab/sdk";

const sdk = new NeuronSDK({
  baseUrl: "https://api.neuronsearchlab.com/v1",
  accessToken: "<your_access_token>",
});

Configuration options

OptionTypeDefaultDescription
baseUrlstringrequiredAPI base URL
accessTokenstringrequiredBearer token from the auth token endpoint
timeoutMsnumber10000HTTP request timeout in ms
maxRetriesnumber2Retry count on 429/5xx/timeouts
collateWindowSecondsnumber3Buffer events for this many seconds before flushing
maxBatchSizenumber200Flush immediately when buffer reaches this size
maxBufferedEventsnumber5000Drop oldest events beyond this limit
propagateRecommendationRequestIdbooleantrueAuto-attach request_id from recommendations to subsequent events
autoSessionIdbooleantrueAuto-generate a session UUID

Get recommendations

const result = await sdk.getRecommendations({
  userId: "user-123",
  contextId: "101",
  limit: 10,
});

console.log(result.recommendations);
// [{ id, object, item_id, rank, score, item, metadata }, ...]
Each recommendation includes id, object, item_id, rank, score, and an embedded item object with the metadata you stored. The response also includes a request_id for event attribution. Use search when the user supplies a free-text query and you want ranked catalog items back through the Core API data plane:
const results = await sdk.search({
  query: "waterproof trail shoes",
  userId: "user-123",
  contextId: "101",
  limit: 10,
  filter: ["category:footwear"],
});

console.log(results.data);
The SDK posts to https://api.neuronsearchlab.com/v1/search, not the console Platform API. Search responses use the same item shape as recommendations and include query, request_id, data, and recommendations.

Search-to-click loop

For search-backed surfaces, treat search and events as one attribution loop:
  1. Run search with the user’s query and optional context.
  2. Render results from data or recommendations.
  3. Capture request_id from the search response.
  4. Send that requestId back with the click, view, or purchase event.
This keeps attribution tied to the exact result set the user saw.
const search = await sdk.search({
  query: "wireless headphones",
  userId: "user-123",
  limit: 8,
});

const first = search.data[0];

if (first) {
  await sdk.trackEvent({
    type: "click",
    userId: "user-123",
    itemId: first.item_id,
    requestId: search.request_id,
  });
}

Auto-generated sections

Use getAutoRecommendations for paginated, auto-titled recommendation sections — ideal for infinite-scroll feeds:
const section = await sdk.getAutoRecommendations({
  userId: "user-123",
  limit: 5,
  windowDays: 7,
});

console.log(section.section?.title);
// e.g. "Because you liked Running Shoes"

// Load next section
if (section.next_cursor) {
  const next = await sdk.getAutoRecommendations({
    userId: "user-123",
    cursor: section.next_cursor,
  });
}

Track events

Events provide the feedback loop that powers personalization. The SDK buffers events in memory and flushes them in batches for efficiency.
await sdk.trackEvent({
  type: "click",
  userId: "user-123",
  itemId: "7f3a2c9e",
});

How batching works

1

Buffer events

Events are buffered with a timestamp that maps to occurred_at in the API.
2

Flush on window or batch size

The buffer flushes when the collate window elapses (default 3s) or the buffer reaches maxBatchSize.
3

Flush during page unload

On page unload (beforeunload, pagehide), remaining events are flushed automatically.
4

Retry failed sends

Failed sends are retried with exponential backoff.
You can flush manually at any time:
await sdk.flushEvents();

Request ID propagation

When propagateRecommendationRequestId is enabled (the default), the SDK captures the request_id from getRecommendations() or search() and automatically attaches it to subsequent trackEvent() calls. This links events back to the result set that produced them.
const recs = await sdk.getRecommendations({ userId: "user-123", limit: 5 });

// request_id is auto-attached — no need to pass it
await sdk.trackEvent({
  type: "click",
  userId: "user-123",
  itemId: recs.recommendations[0].item_id,
});

Manage catalog items

Create an item

await sdk.upsertItem({
  itemId: "7f3a2c9e",
  name: "Nike Running Shoes",
  description: "High-performance running shoes for daily training.",
  metadata: { category: "Footwear", brand: "Nike", price: 109.99 },
});
The description field is used to generate embeddings for similarity matching.

Update an item

await sdk.patchItem({
  itemId: "7f3a2c9e",
  active: false, // disable the item
});
Or use the convenience helper:
await sdk.setItemActive("7f3a2c9e", false);

Delete items

await sdk.deleteItems({ itemId: "7f3a2c9e" });

// Batch delete
await sdk.deleteItems([
  { itemId: "7f3a2c9e" },
  { itemId: "a8d1b247" },
]);

Error handling

The SDK exports two error classes:
import NeuronSDK, { SDKHttpError, SDKTimeoutError } from "@neuronsearchlab/sdk";

try {
  await sdk.getRecommendations({ userId: "user-123" });
} catch (err) {
  if (err instanceof SDKHttpError) {
    console.error(`HTTP ${err.status}: ${err.statusText}`, err.body);
  } else if (err instanceof SDKTimeoutError) {
    console.error(`Request timed out after ${err.timeoutMs}ms`);
  }
}
Transient errors (429, 5xx, timeouts) are retried automatically with exponential backoff up to maxRetries times.

Logging

Configure structured logging for debugging and observability:
import { configureLogger } from "@neuronsearchlab/sdk";

configureLogger({
  level: "DEBUG",
  enableNetworkBodyLogging: true,
  enablePerformanceLogging: true,
});
Available log levels: TRACE, DEBUG, INFO (default), WARN, ERROR, FATAL. You can also provide a custom transport to send logs to your own logging infrastructure:
configureLogger({
  level: "WARN",
  transport: (entry) => {
    // entry: { level, message, timestamp, context }
    myLogger.log(entry);
  },
});

Session management

The SDK auto-generates a session UUID on initialization (when autoSessionId is true). All events include the session ID automatically. You can override or read it:
sdk.setSessionId("custom-session-id");
console.log(sdk.getSessionId());

Next steps