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

# TypeScript SDK

> Full reference for the thrindex TypeScript/JavaScript SDK — ThrindexClient, all methods, type definitions, and error handling.

## Installation

```bash theme={null}
npm install thrindex
# or
yarn add thrindex
# or
pnpm add thrindex
```

**Requirements:** Node.js 18+ (uses native `fetch`). Zero production dependencies.

***

## Client

```typescript theme={null}
import { ThrindexClient } from 'thrindex';

const client = new ThrindexClient({
  apiKey: 'th_live_...',                    // required
  baseUrl: 'https://api.thrindex.com',      // optional, this is the default
  timeoutMs: 30_000,                        // optional, milliseconds (default 30 000)
  maxRetries: 3,                            // optional (default 3)
});
```

`ThrindexClient` is safe to share across concurrent requests — create one instance per application.

### Constructor options (`ClientOptions`)

| Option       | Type     | Default                      | Description                                        |
| ------------ | -------- | ---------------------------- | -------------------------------------------------- |
| `apiKey`     | `string` | required                     | Your API key beginning with `th_live_`             |
| `baseUrl`    | `string` | `"https://api.thrindex.com"` | Override for self-hosted or test environments      |
| `timeoutMs`  | `number` | `30_000`                     | Per-request timeout in milliseconds                |
| `maxRetries` | `number` | `3`                          | Maximum retry attempts on `5xx` and network errors |

***

## Methods

All methods are `async` and return `Promise<T>`.

### `add()`

Store a memory for asynchronous processing.

```typescript theme={null}
const memoryId: string = await client.add({
  content: 'User prefers weekly email digests.',  // required
  agentId: 'support-agent',                        // required
  userId: 'user-42',                               // required
  confidence: 0.95,                                // optional
  metadata: { source: 'preference-survey' },       // optional
  extract: true,                                   // optional, default true
});

console.log(memoryId); // "3f2e1d0c-..."
```

#### `AddOptions`

| Field        | Type                      | Required | Default           | Description                                                                                                              |
| ------------ | ------------------------- | -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `content`    | `string`                  | yes      | —                 | The memory text. Max 8192 bytes (≈8 KB).                                                                                 |
| `agentId`    | `string`                  | yes      | —                 | Agent identifier. Max 256 chars. Charset: `[A-Za-z0-9._:-]`                                                              |
| `userId`     | `string`                  | yes      | —                 | User identifier. Same constraints as `agentId`.                                                                          |
| `confidence` | `number`                  | no       | `1.0` server-side | Your confidence in this memory's accuracy, `0.0`–`1.0`.                                                                  |
| `metadata`   | `Record<string, unknown>` | no       | —                 | Arbitrary key-value pairs stored with the memory.                                                                        |
| `extract`    | `boolean`                 | no       | `true`            | When `true`, the cognition worker runs LLM extraction on the content. Set to `false` to store verbatim with no LLM call. |

#### Returns

`Promise<string>` — the memory UUID.

***

### `search()`

Retrieve the most relevant memories for a query.

```typescript theme={null}
import type { SearchHit } from 'thrindex';

const results: SearchHit[] = await client.search({
  query: 'how does the user want to be contacted',  // required
  agentId: 'support-agent',                          // required
  userId: 'user-42',                                 // required
  k: 10,                                             // optional, default 10
  taskContext: 'composing a notification email',     // optional
  level: undefined,                                  // optional, filter by level
});

for (const hit of results) {
  console.log(`[${hit.score.toFixed(3)}] ${hit.content}`);
}
```

#### `SearchOptions`

| Field         | Type     | Required | Default        | Description                                                                                     |
| ------------- | -------- | -------- | -------------- | ----------------------------------------------------------------------------------------------- |
| `query`       | `string` | yes      | —              | Natural language query. Max 2048 characters.                                                    |
| `agentId`     | `string` | yes      | —              | Limits search to memories belonging to this agent.                                              |
| `userId`      | `string` | yes      | —              | Limits search to memories belonging to this user.                                               |
| `k`           | `number` | no       | `10`           | Number of results to return. Range: `1`–`100`.                                                  |
| `taskContext` | `string` | no       | —              | A sentence describing what the agent is currently doing. Improves ranking for the current task. |
| `level`       | `number` | no       | — (all levels) | Filter to a specific memory level: `0` (raw), `1` (abstraction).                                |

#### Returns

`Promise<SearchHit[]>` — ordered by descending relevance score.

#### `SearchHit`

| Field        | Type     | Description                                                                 |
| ------------ | -------- | --------------------------------------------------------------------------- |
| `id`         | `string` | Memory UUID                                                                 |
| `content`    | `string` | The memory text                                                             |
| `agentId`    | `string` | Agent that owns the memory                                                  |
| `userId`     | `string` | User the memory belongs to                                                  |
| `level`      | `number` | `0` or `1`                                                                  |
| `status`     | `string` | `"active"` or `"deprecated"`                                                |
| `importance` | `number` | Importance score `0.0`–`1.0`                                                |
| `confidence` | `number` | Confidence score `0.0`–`1.0`                                                |
| `score`      | `number` | Multi-signal fusion score — use to compare results within a single response |
| `createdAt`  | `string` | ISO 8601 creation timestamp                                                 |

***

### `list()`

List memories with cursor-based pagination.

```typescript theme={null}
import type { ListResponse } from 'thrindex';

let page: ListResponse = await client.list({
  agentId: 'support-agent',  // optional
  userId: 'user-42',         // optional
  limit: 50,                 // optional, default 50
});

for (const record of page.results) {
  console.log(record.id, record.importance);
}

// Iterate through all pages
while (page.nextCursor) {
  page = await client.list({
    agentId: 'support-agent',
    userId: 'user-42',
    cursor: page.nextCursor,
  });
}
```

#### `ListOptions`

| Field     | Type     | Required | Default | Description                                                                      |
| --------- | -------- | -------- | ------- | -------------------------------------------------------------------------------- |
| `agentId` | `string` | no       | —       | Filter to a specific agent. Omit for org-wide listing.                           |
| `userId`  | `string` | no       | —       | Filter to a specific user. Omit for all users.                                   |
| `limit`   | `number` | no       | `50`    | Results per page. Range: `1`–`200`.                                              |
| `cursor`  | `string` | no       | —       | Opaque cursor from `nextCursor` of a previous response. Omit for the first page. |

#### Returns

`Promise<ListResponse>` with:

* `results: MemoryRecord[]` — current page (content excluded)
* `nextCursor?: string` — undefined when no more pages

<Note>
  `content` is excluded from list results. Call `get(memoryId)` to retrieve the full record including content.
</Note>

#### `MemoryRecord`

| Field        | Type     | Description                           |
| ------------ | -------- | ------------------------------------- |
| `id`         | `string` | Memory UUID                           |
| `orgId`      | `string` | Your organization identifier          |
| `agentId`    | `string` | Agent that owns the memory            |
| `userId`     | `string` | User the memory belongs to            |
| `level`      | `number` | `0` or `1`                            |
| `status`     | `string` | `"active"` or `"deprecated"`          |
| `importance` | `number` | Importance score `0.0`–`1.0`          |
| `confidence` | `number` | Confidence score `0.0`–`1.0`          |
| `source`     | `string` | Origin of the memory (e.g. `"agent"`) |
| `createdAt`  | `string` | ISO 8601 creation timestamp           |
| `updatedAt`  | `string` | ISO 8601 last updated timestamp       |

***

### `get()`

Fetch a single memory by ID, including its `content`.

```typescript theme={null}
import type { MemoryDetail } from 'thrindex';

const memory: MemoryDetail = await client.get('3f2e1d0c-...');
console.log(memory.content);
```

#### Parameters

| Parameter  | Type     | Required | Description     |
| ---------- | -------- | -------- | --------------- |
| `memoryId` | `string` | yes      | The memory UUID |

#### Returns

`Promise<MemoryDetail>` — all fields of `MemoryRecord` plus `content: string`. Throws `NotFoundError` if the memory does not exist.

***

### `delete()`

Delete a memory by ID.

```typescript theme={null}
await client.delete('3f2e1d0c-...');                    // soft delete (default)
await client.delete('3f2e1d0c-...', { hard: true });    // hard delete (GDPR erasure)
```

#### Parameters

| Parameter      | Type      | Required | Default | Description                                                                      |
| -------------- | --------- | -------- | ------- | -------------------------------------------------------------------------------- |
| `memoryId`     | `string`  | yes      | —       | The memory UUID                                                                  |
| `options.hard` | `boolean` | no       | `false` | `false` = soft delete. `true` = permanent erasure from all stores. Irreversible. |

#### Returns

`Promise<void>`. Throws `NotFoundError` if the memory does not exist.

***

### `batchAdd()`

Add multiple memories sequentially with per-item retry.

```typescript theme={null}
import type { BatchAddItem } from 'thrindex';

const ids: string[] = await client.batchAdd(
  [
    { content: 'User timezone is Europe/Berlin.' },
    { content: 'User language is German.', confidence: 0.9 },
    { content: 'User prefers dark mode.', extract: false },
  ],
  {
    agentId: 'support-agent',  // default for all items
    userId: 'user-42',         // default for all items
    extract: true,             // default extraction behaviour
  },
);
```

#### `BatchAddItem`

| Field        | Type                      | Required | Description                              |
| ------------ | ------------------------- | -------- | ---------------------------------------- |
| `content`    | `string`                  | yes      | The memory text                          |
| `agentId`    | `string`                  | no       | Overrides the batch-level `agentId`      |
| `userId`     | `string`                  | no       | Overrides the batch-level `userId`       |
| `confidence` | `number`                  | no       | Per-item confidence score                |
| `metadata`   | `Record<string, unknown>` | no       | Per-item metadata                        |
| `extract`    | `boolean`                 | no       | Overrides the batch-level `extract` flag |

#### Returns

`Promise<string[]>` — memory UUIDs in the same order as the input. Throws on the first unretriable failure.

***

## Error handling

```typescript theme={null}
import {
  ThrindexError,
  AuthError,
  NotFoundError,
  RateLimitError,
} from 'thrindex';

try {
  const results = await client.search({ query: '...', agentId: '...', userId: '...' });
} catch (err) {
  if (err instanceof AuthError) {
    // 401 — invalid or revoked API key
    console.error('Check your API key.');
  } else if (err instanceof NotFoundError) {
    // 404 — memory does not exist
    console.error('Memory not found.');
  } else if (err instanceof RateLimitError) {
    // 429 — rate limit exceeded (SDK already retried max_retries times)
    console.error(`Rate limited. Retry after ${err.retryAfter}s.`);
  } else if (err instanceof ThrindexError) {
    // All other errors (400, 500, network failures)
    console.error(`Error ${err.statusCode}: ${err.message}`);
  }
}
```

### Error classes

| Class            | HTTP | Properties                                           |
| ---------------- | ---- | ---------------------------------------------------- |
| `ThrindexError`  | any  | `statusCode: number \| undefined`, `message: string` |
| `AuthError`      | 401  | Extends `ThrindexError`                              |
| `NotFoundError`  | 404  | Extends `ThrindexError`                              |
| `RateLimitError` | 429  | `retryAfter: number` (seconds)                       |

### Retry behaviour

The SDK automatically retries transient failures:

* **5xx errors** (`500`, `502`, `503`, `504`): up to `maxRetries` times
* **429 Rate limited**: waits `Retry-After` seconds, then retries
* **Network / timeout errors**: retries with exponential backoff

`4xx` errors (except `429`) are never retried. Backoff: `min(500ms × 2^attempt + jitter, 30s)`.

***

## LLM integrations

Drop-in wrappers for OpenAI, Anthropic, and LangChain are available as named exports from subpaths. See [Integrations](/sdks/integrations) for full details.

```typescript theme={null}
import { ThrindexOpenAI } from 'thrindex/integrations/openai';
import { ThrindexAnthropic } from 'thrindex/integrations/anthropic';
import { ThrindexLangChainRetriever } from 'thrindex/integrations/langchain';
```

Peer dependencies (`openai`, `@anthropic-ai/sdk`, `@langchain/core`) are optional and only required when you use the corresponding integration.
