> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neuronsearchlab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK

> Install, configure, and use the official NeuronSearchLab JavaScript SDK in your applications.

<Note>
  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](/sdk/php) or install it from [Packagist](https://packagist.org/packages/neuronsearchlab/sdk-php).
</Note>

## Installation

```bash theme={null}
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](/authentication) and pass it when creating the client:

```ts theme={null}
import NeuronSDK from "@neuronsearchlab/sdk";

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

### Configuration options

| Option                             | Type    | Default  | Description                                                        |
| ---------------------------------- | ------- | -------- | ------------------------------------------------------------------ |
| `baseUrl`                          | string  | required | API base URL                                                       |
| `accessToken`                      | string  | required | Bearer token from the auth token endpoint                          |
| `timeoutMs`                        | number  | `10000`  | HTTP request timeout in ms                                         |
| `maxRetries`                       | number  | `2`      | Retry count on 429/5xx/timeouts                                    |
| `collateWindowSeconds`             | number  | `3`      | Buffer events for this many seconds before flushing                |
| `maxBatchSize`                     | number  | `200`    | Flush immediately when buffer reaches this size                    |
| `maxBufferedEvents`                | number  | `5000`   | Drop oldest events beyond this limit                               |
| `propagateRecommendationRequestId` | boolean | `true`   | Auto-attach `request_id` from recommendations to subsequent events |
| `autoSessionId`                    | boolean | `true`   | Auto-generate a session UUID                                       |

***

## Get recommendations

```ts theme={null}
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.

## Search

Use `search` when the user supplies a free-text query and you want ranked catalog items back through the Core API data plane:

```ts theme={null}
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.

```ts theme={null}
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:

```ts theme={null}
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.

```ts theme={null}
await sdk.trackEvent({
  type: "click",
  userId: "user-123",
  itemId: "7f3a2c9e",
});
```

### How batching works

<Steps>
  <Step title="Buffer events">
    Events are buffered with a timestamp that maps to `occurred_at` in the API.
  </Step>

  <Step title="Flush on window or batch size">
    The buffer flushes when the collate window elapses (default 3s) or the buffer reaches `maxBatchSize`.
  </Step>

  <Step title="Flush during page unload">
    On page unload (`beforeunload`, `pagehide`), remaining events are flushed automatically.
  </Step>

  <Step title="Retry failed sends">
    Failed sends are retried with exponential backoff.
  </Step>
</Steps>

You can flush manually at any time:

```ts theme={null}
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.

```ts theme={null}
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

```ts theme={null}
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

```ts theme={null}
await sdk.patchItem({
  itemId: "7f3a2c9e",
  active: false, // disable the item
});
```

Or use the convenience helper:

```ts theme={null}
await sdk.setItemActive("7f3a2c9e", false);
```

### Delete items

```ts theme={null}
await sdk.deleteItems({ itemId: "7f3a2c9e" });

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

***

## Error handling

The SDK exports two error classes:

```ts theme={null}
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:

```ts theme={null}
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:

```ts theme={null}
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:

```ts theme={null}
sdk.setSessionId("custom-session-id");
console.log(sdk.getSessionId());
```

***

## Next steps

* View the [PHP SDK guide](/sdk/php) if you are integrating from Laravel or another PHP service.
* View the [API documentation](/api-reference/introduction) for the underlying REST endpoints.
* Set up the [MCP integration](/sdk/mcp) to use NeuronSearchLab from AI assistants like Claude.
* Reach out to [contact@neuronsearchlab.com](mailto:contact@neuronsearchlab.com) if you need help.
