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

# Node.js SDK

> Complete API reference for the Memvid Node.js SDK

Build web apps, agents, and AI applications with the Memvid Node.js SDK. Native bindings deliver blazing-fast performance with a TypeScript-first API.

## Installation

```bash theme={null}
npm install @memvid/sdk
# or
pnpm add @memvid/sdk
# or
yarn add @memvid/sdk
```

<Info>
  **Requirements:** Node.js 18+, macOS/Linux/Windows. Native bindings included - no extra dependencies needed.
</Info>

***

<Warning title="Don't Lose Your Data!">
  **`create()` will OVERWRITE existing files without warning!**

  | Function             | Purpose                     | If File Exists       | Parameter Order       |
  | -------------------- | --------------------------- | -------------------- | --------------------- |
  | `create(path, kind)` | Create **new** .mv2 file    | **DELETES all data** | path first, then kind |
  | `use(kind, path)`    | Open **existing** .mv2 file | Preserves data       | kind first, then path |

  **Always check if the file exists before choosing** — see example below.
</Warning>

## Quick Start

```typescript theme={null}
import { create, use } from '@memvid/sdk';
import { existsSync } from 'fs';

const path = 'knowledge.mv2';

// CRITICAL: Check if file exists to avoid data loss!
const mem = existsSync(path)
  ? await use('basic', path)    // Open existing file (kind first!)
  : await create(path, 'basic'); // Create new file (path first!)

// Add documents
await mem.put({
  title: 'Meeting Notes',
  label: 'notes',
  text: 'Alice mentioned she works at Anthropic...'
});

// Search works immediately
const results = await mem.find('who works at AI companies?', { k: 5, mode: 'lex' });
console.log(results.hits);

// Ask questions
const answer = await mem.ask('What does Alice do?', { k: 5, mode: 'lex' });
console.log(answer.answer);

// Seal when done (commits changes)
await mem.seal();
```

***

## API Reference

| Category            | Methods                                         | Description                             |
| ------------------- | ----------------------------------------------- | --------------------------------------- |
| **File Operations** | `create`, `open`, `close`, `use`                | Create, open, close memory files        |
| **Data Ingestion**  | `put`, `putMany`, `putFile`, `putFiles`         | Add documents with embeddings           |
| **Search**          | `find`, `ask`, `vecSearch`, `timeline`          | Query your memory                       |
| **Corrections**     | `correct`, `correctMany`                        | Store ground truth with retrieval boost |
| **Memory Cards**    | `memories`, `state`, `enrich`, `addMemoryCards` | Structured fact extraction              |
| **Tables**          | `putPdfTables`, `listTables`, `getTable`        | PDF table extraction                    |
| **Sessions**        | `sessionStart`, `sessionEnd`, `sessionReplay`   | Time-travel debugging                   |
| **Tickets**         | `syncTickets`, `currentTicket`, `getCapacity`   | Capacity management                     |
| **Security**        | `lock`, `unlock`, `lockWho`, `lockNudge`        | Encryption and access control           |
| **Utilities**       | `verify`, `doctor`, `maskPii`                   | Maintenance and utilities               |

***

## Core Functions

### File Operations

```typescript theme={null}
import { create, open, verifyMemvid, doctorMemvid, info } from '@memvid/sdk';

// Create new memory file
const mem = await create('project.mv2');

// Open existing memory
const existing = await open('project.mv2');

// With options
const mem = await create('project.mv2', 'basic', {
  enableLex: true,    // Enable lexical index
  enableVec: true,    // Enable vector index
  memoryId: 'mem_abc' // Bind to dashboard
});

// Verify file integrity
await verifyMemvid('project.mv2', { deep: true });

// Repair and optimize
await doctorMemvid('project.mv2', {
  rebuildTimeIndex: true,
  rebuildVecIndex: true,
  vacuum: true
});

// Get SDK info
const sdkInfo = info();
```

### Framework Adapters

Choose an adapter for your framework:

```typescript theme={null}
import { use } from '@memvid/sdk';

// Available adapters
const mem = await use('basic', 'file.mv2');
const langchain = await use('langchain', 'file.mv2');
const llamaindex = await use('llamaindex', 'file.mv2');
const vercelai = await use('vercel-ai', 'file.mv2');
const openai = await use('openai', 'file.mv2');
const crewai = await use('crewai', 'file.mv2');
const autogen = await use('autogen', 'file.mv2');
const haystack = await use('haystack', 'file.mv2');
const langgraph = await use('langgraph', 'file.mv2');
const semantickernel = await use('semantic-kernel', 'file.mv2');
const googleadk = await use('google-adk', 'file.mv2');
```

***

## Auto-Embedding

The SDK automatically enables vector embeddings when `OPENAI_API_KEY` is set in your environment:

```typescript theme={null}
// Embeddings are automatically enabled using text-embedding-3-small
await mem.put({ title: 'Doc', text: 'Content here' });
```

**How it works:**

* If `OPENAI_API_KEY` is set and `enableEmbedding` is not specified, embeddings are auto-enabled
* Uses OpenAI's `text-embedding-3-small` model (1536 dimensions)
* If no API key is present and no model specified, falls back to local `bge-small` (384 dimensions)

| Environment                       | Default Behavior                             |
| --------------------------------- | -------------------------------------------- |
| `OPENAI_API_KEY` set              | Auto-enable with `text-embedding-3-small`    |
| No API key                        | Local `bge-small` if `enableEmbedding: true` |
| Explicit `enableEmbedding: false` | No embeddings                                |

<Tip>
  Set `OPENAI_API_KEY` once in your environment and the SDK handles the rest. No need to pass `enableEmbedding: true` or specify models.
</Tip>

***

## Data Ingestion

### put() - Add Single Document

```typescript theme={null}
await mem.put({
  // Required
  title: 'Document Title',

  // Content (one of these)
  text: 'Document content...',
  file: '/path/to/document.pdf',

  // Optional
  uri: 'mv2://docs/intro',
  tags: ['api', 'v2'],
  labels: ['public', 'reviewed'],
  kind: 'markdown',
  track: 'documentation',
  metadata: { author: 'Alice', version: '2.0' },

  // Embeddings
  enableEmbedding: true,
  embeddingModel: 'bge-small',  // or 'openai', 'nomic', etc.
  vectorCompression: true,       // 16x compression with PQ

  // Behavior
  autoTag: true,                 // Auto-generate tags
  extractDates: true             // Extract date mentions
});
```

### putMany() - Batch Ingestion

```typescript theme={null}
const docs = [
  { title: 'Doc 1', text: 'First document content' },
  { title: 'Doc 2', text: 'Second document content' },
  { title: 'Doc 3', text: 'Third document content' }
];

const frameIds = await mem.putMany(docs, {
  enableEmbedding: true,
  compressionLevel: 3,
  embedder: openaiEmbeddings  // Custom embedder
});
```

### putFile() - Document Parsing

Ingest documents directly from files. Supports **PDF**, **DOCX**, **XLSX**, **PPTX**, and more. The SDK automatically extracts text content and creates searchable frames.

```typescript theme={null}
// Single file ingestion
const frames = await mem.putFile('/path/to/report.pdf');
console.log(`Ingested ${frames.length} frames from PDF`);

// With options
const frames = await mem.putFile('/path/to/presentation.pptx', {
  chunkSize: 1000,           // Characters per chunk
  chunkOverlap: 200,         // Overlap between chunks
  enableEmbedding: true,     // Generate embeddings
  embeddingModel: 'bge-small'
});

// Excel/XLSX files
const frames = await mem.putFile('/path/to/data.xlsx');
// Each sheet becomes searchable content

// Word documents
const frames = await mem.putFile('/path/to/document.docx');
```

### putFiles() - Batch Document Ingestion

Ingest multiple documents at once:

```typescript theme={null}
const files = [
  '/path/to/report.pdf',
  '/path/to/slides.pptx',
  '/path/to/data.xlsx',
  '/path/to/notes.docx'
];

const allFrames = await mem.putFiles(files, {
  chunkSize: 1000,
  enableEmbedding: true
});

console.log(`Total frames: ${allFrames.length}`);
```

<Info>
  **Supported Formats:**

  * **PDF** - Text extraction with page-aware chunking
  * **DOCX** - Microsoft Word documents
  * **XLSX** - Excel spreadsheets (all sheets, formulas evaluated)
  * **PPTX** - PowerPoint presentations (slide text and notes)

  **No extra dependencies required** - document parsing is built into the native bindings.
</Info>

<Note>
  For XLSX files with formulas, the SDK extracts the **calculated values**, not the formula text. This ensures searchable, meaningful content.
</Note>

***

## Search & Retrieval

### find() - Hybrid Search

```typescript theme={null}
// Simple search
const results = await mem.find('budget projections');

// With options
const results = await mem.find('financial outlook', {
  mode: 'auto',           // 'lex', 'sem', 'auto', 'clip'
  k: 10,                  // Number of results
  snippetChars: 480,      // Snippet length
  scope: 'track:meetings', // Scope filter

  // Access control (ACL)
  // In "enforce" mode, tenantId is required.
  aclContext: { tenantId: 'tenant-123', roles: ['finance'] },
  aclEnforcementMode: 'enforce',

  // Adaptive retrieval
  adaptive: true,
  minRelevancy: 0.5,
  maxK: 100,
  adaptiveStrategy: 'combined',  // 'relative', 'absolute', 'cliff', 'elbow'

  // Time-travel
  asOfFrame: 100,
  asOfTs: 1704067200,

  // Custom embeddings
  embedder: customEmbedder,
  queryEmbeddingModel: 'openai'
});

console.log(results.hits);
```

<Info>
  **Query Syntax:** Multi-word queries use OR logic by default for better recall. Use `AND` for intersection: `"machine AND learning"`. Use quotes for exact phrases: `'"machine learning"'`.
</Info>

### Permission-Aware Retrieval (ACL)

See [Permission-Aware Retrieval (ACL)](/concepts/permission-aware-retrieval) for the full model.

At a high level:

* Write per-frame ACL metadata during ingestion (`metadata.acl_*`)
* Pass `aclContext` + `aclEnforcementMode: 'enforce'` to `find()` / `ask()`

```typescript theme={null}
import { getAclScopeFromApiKey, aclContextFromScope } from '@memvid/sdk';

const scope = await getAclScopeFromApiKey();
const aclContext = aclContextFromScope(scope);

const hits = await mem.find('budget', {
  mode: 'lex',
  k: 5,
  aclContext,
  aclEnforcementMode: 'enforce',
});
```

### ask() - LLM Q\&A

```typescript theme={null}
const answer = await mem.ask('What was decided about the budget?', {
  k: 8,
  mode: 'auto',

  // LLM settings
  model: 'gpt-4o-mini',
  modelApiKey: process.env.OPENAI_API_KEY,
  llmContextChars: 120000,

  // Privacy
  maskPii: true,

  // Time filters
  since: 1704067200,
  until: 1706745600,

  // Options
  contextOnly: false,   // Set true to skip synthesis
  returnSources: true,  // Include source documents

  // Adaptive retrieval
  adaptive: true,
  minRelevancy: 0.5,

  // Access control (ACL)
  aclContext: { tenantId: 'tenant-123', roles: ['finance'] },
  aclEnforcementMode: 'enforce',
});

console.log(answer.answer);
console.log(answer.sources);
```

### vecSearch() - Pure Vector Search

```typescript theme={null}
const results = await mem.vecSearch('query', queryEmbedding, {
  k: 10,
  adaptive: true,
  minRelevancy: 0.7
});
```

### Grounding & Hallucination Detection

The `ask()` response includes a `grounding` object that measures how well the answer is supported by context:

```typescript theme={null}
const answer = await mem.ask('What is the API endpoint?', {
  model: 'gpt-4o-mini',
  modelApiKey: process.env.OPENAI_API_KEY
});

// Check grounding quality
console.log(answer.grounding);
// {
//   score: 0.85,
//   label: 'HIGH',           // 'LOW', 'MEDIUM', or 'HIGH'
//   sentence_count: 3,
//   grounded_sentences: 3,
//   has_warning: false,
//   warning_reason: undefined
// }

// Check if follow-up is needed
if (answer.follow_up?.needed) {
  console.log('Low confidence:', answer.follow_up.reason);
  console.log('Try these instead:', answer.follow_up.suggestions);
}
```

**Grounding Fields:**

| Field                | Type      | Description                               |
| -------------------- | --------- | ----------------------------------------- |
| `score`              | `number`  | Grounding score from 0.0 to 1.0           |
| `label`              | `string`  | Quality label: `LOW`, `MEDIUM`, or `HIGH` |
| `sentence_count`     | `number`  | Sentences in the answer                   |
| `grounded_sentences` | `number`  | Sentences supported by context            |
| `has_warning`        | `boolean` | True if answer may be hallucinated        |
| `warning_reason`     | `string?` | Explanation if warning is present         |

**Follow-up Fields:**

| Field              | Type       | Description                      |
| ------------------ | ---------- | -------------------------------- |
| `needed`           | `boolean`  | True if answer confidence is low |
| `reason`           | `string`   | Why confidence is low            |
| `hint`             | `string`   | Helpful hint for the user        |
| `available_topics` | `string[]` | Topics in this memory            |
| `suggestions`      | `string[]` | Suggested follow-up questions    |

### correct() - Ground Truth Corrections

Store authoritative corrections that take priority in future retrievals:

```typescript theme={null}
// Store a correction
const frameId = await mem.correct('Ben Koenig reported to Chloe Nguyen before 2025');

// With options
const frameId = await mem.correct('The API rate limit is 1000 req/min', {
  source: 'Engineering Team - Jan 2025',
  topics: ['API', 'rate limiting'],
  boost: 2.5  // Higher retrieval priority (default: 2.0)
});

// Batch corrections
const frameIds = await mem.correctMany([
  { statement: 'OAuth tokens expire after 24 hours', topics: ['auth', 'OAuth'] },
  { statement: 'Production DB is db.prod.example.com', source: 'Ops Team' }
]);

// Verify correction is retrievable
const results = await mem.find('Ben Koenig reported to');
console.log(results.hits[0].snippet);  // Should show the correction
```

<Tip>
  Use `correct()` to fix hallucinations or add verified facts. Corrections receive boosted retrieval scores and are labeled `[Correction]` in results.
</Tip>

***

## Memory Cards (Entity Extraction)

### Automatic Enrichment

```typescript theme={null}
// Extract facts using rules engine (fast, offline)
const result = await mem.enrich('rules');

// View extracted cards
const { cards, count } = await mem.memories();

// Filter by entity
const aliceCards = await mem.memories('Alice');

// Get entity state (O(1) lookup)
const alice = await mem.state('Alice');
console.log(alice.slots);
// { employer: 'Anthropic', role: 'Engineer', location: 'SF' }

// Get stats
const stats = await mem.memoriesStats();
console.log(stats.entityCount, stats.cardCount);

// List all entities
const entities = await mem.memoryEntities();
```

### Manual Memory Cards

```typescript theme={null}
// Add SPO triplets directly
const result = await mem.addMemoryCards([
  { entity: 'Alice', slot: 'employer', value: 'Anthropic' },
  { entity: 'Alice', slot: 'role', value: 'Senior Engineer' },
  { entity: 'Bob', slot: 'team', value: 'Infrastructure' }
]);

console.log(result.added, result.ids);
```

### Export Facts

```typescript theme={null}
// Export to JSON
const json = await mem.exportFacts('json');

// Export to CSV
const csv = await mem.exportFacts('csv', 'Alice');

// Export to N-Triples (RDF)
const ntriples = await mem.exportFacts('ntriples');
```

***

## Table Extraction

```typescript theme={null}
// Extract tables from PDF
const result = await mem.putPdfTables('financial-report.pdf', true);
console.log(`Extracted ${result.tables_count} tables`);

// List all tables
const tables = await mem.listTables();
for (const table of tables) {
  console.log(table.table_id, table.n_rows, table.n_cols);
}

// Get table data
const data = await mem.getTable('tbl_001', 'dict');
const csv = await mem.getTable('tbl_001', 'csv');
```

***

## Time-Travel & Sessions

### Timeline Queries

```typescript theme={null}
const timeline = await mem.timeline({
  limit: 50,
  since: 1704067200,
  until: 1706745600,
  reverse: true,
  asOfFrame: 100
});
```

### Session Recording

```typescript theme={null}
// Start recording
const sessionId = await mem.sessionStart('qa-test');

// Perform operations
await mem.find('test query');
await mem.ask('What happened?');

// Add checkpoint
await mem.sessionCheckpoint();

// End session
const summary = await mem.sessionEnd();

// List sessions
const sessions = await mem.sessionList();

// Replay session with different params
const replay = await mem.sessionReplay(sessionId, 10, true);
console.log(replay.match_rate);

// Delete session
await mem.sessionDelete(sessionId);
```

***

## Encryption & Security

```typescript theme={null}
import { lock, unlock, lockWho, lockNudge } from '@memvid/sdk';

// Encrypt to .mv2e capsule
const encryptedPath = await lock('project.mv2', {
  password: 'secret',
  force: true
});

// Decrypt back to .mv2
const decryptedPath = await unlock('project.mv2e', {
  password: 'secret'
});

// Check who has the lock
const lockInfo = await lockWho('project.mv2');

// Nudge stale lock
const released = await lockNudge('project.mv2');
```

***

## Tickets & Capacity

```typescript theme={null}
// Get current capacity
const capacity = await mem.getCapacity();

// Get current ticket info
const ticket = await mem.currentTicket();

// Sync tickets from dashboard
const result = await mem.syncTickets('mem_abc123', apiKey);

// Apply ticket manually
await mem.applyTicket(ticketString);

// Get memory binding
const binding = await mem.getMemoryBinding();

// Unbind from dashboard
await mem.unbindMemory();
```

***

## Cloud Project & Memory Management

Programmatically create projects and memories on the Memvid dashboard, then bind local `.mv2` files to them.

### Configure SDK

```typescript theme={null}
import { configure } from '@memvid/sdk';

configure({
  apiKey: 'mv2_your_api_key_here',
  dashboardUrl: 'https://memvid.com'
});
```

### Create and List Projects

```typescript theme={null}
import { createProject, listProjects } from '@memvid/sdk';

// Create a new project
const project = await createProject({
  name: 'My AI Project',
  description: 'Knowledge base for my AI agent'
});
console.log(`Project ID: ${project.id}`);
console.log(`Slug: ${project.slug}`);

// List all projects
const projects = await listProjects();
for (const proj of projects) {
  console.log(`${proj.name} (${proj.id})`);
}
```

**Project Response Fields:**

| Field            | Type      | Description          |
| ---------------- | --------- | -------------------- |
| `id`             | `string`  | Unique project ID    |
| `organisationId` | `string`  | Organisation ID      |
| `slug`           | `string`  | URL-friendly slug    |
| `name`           | `string`  | Project name         |
| `description`    | `string?` | Optional description |
| `createdAt`      | `string`  | ISO 8601 timestamp   |
| `updatedAt`      | `string`  | ISO 8601 timestamp   |

### Create and List Memories

```typescript theme={null}
import { createMemory, listMemories } from '@memvid/sdk';

// Create a memory in a project
const memory = await createMemory({
  name: 'Agent Memory',
  description: 'Long-term memory for chatbot',
  projectId: project.id
});
console.log(`Memory ID: ${memory.id}`);
console.log(`Display Name: ${memory.displayName}`);

// List all memories
const allMemories = await listMemories();

// List memories in a specific project
const projectMemories = await listMemories({ projectId: project.id });
```

### Bind Local File to Cloud Memory

```typescript theme={null}
import { create } from '@memvid/sdk';

// Create local .mv2 file bound to cloud memory
const mv = await create('./agent.mv2', 'basic', { memoryId: memory.id });
await mv.enableLex();  // Enable lexical search

// Add content
await mv.put({ title: 'Meeting Notes', label: 'notes', text: 'Today we discussed...' });

// Search
const results = await mv.find('discussed', { k: 5 });

// Close
await mv.seal();
```

### Complete Example

```typescript theme={null}
import { configure, createProject, createMemory, create } from '@memvid/sdk';

// 1. Configure SDK
configure({ apiKey: process.env.MEMVID_API_KEY });

// 2. Create project
const project = await createProject({
  name: 'Knowledge Base',
  description: 'Company docs'
});

// 3. Create cloud memory in project
const memory = await createMemory({
  name: 'Docs Memory',
  projectId: project.id
});

// 4. Create local file bound to cloud memory
const mv = await create('./docs.mv2', 'basic', { memoryId: memory.id });
await mv.enableLex();

// 5. Add content
await mv.put({ title: 'API Guide', label: 'docs', text: 'API documentation...' });
await mv.put({ title: 'FAQ', label: 'docs', text: 'Frequently asked questions...' });

// 6. Search
const results = await mv.find('API', { k: 5 });
console.log(`Found ${results.hits?.length || 0} results`);

// 7. Clean up
await mv.seal();
```

***

## Embedding Providers

### External Providers

```typescript theme={null}
import {
  OpenAIEmbeddings,
  GeminiEmbeddings,
  MistralEmbeddings,
  CohereEmbeddings,
  VoyageEmbeddings,
  NvidiaEmbeddings,
  getEmbedder
} from '@memvid/sdk';

// OpenAI
const openai = new OpenAIEmbeddings({
  apiKey: process.env.OPENAI_API_KEY,
  model: 'text-embedding-3-small'  // or 'text-embedding-3-large'
});

// Gemini
const gemini = new GeminiEmbeddings({
  apiKey: process.env.GEMINI_API_KEY,
  model: 'text-embedding-004'
});

// Mistral
const mistral = new MistralEmbeddings({
  apiKey: process.env.MISTRAL_API_KEY
});

// Cohere
const cohere = new CohereEmbeddings({
  apiKey: process.env.COHERE_API_KEY,
  model: 'embed-english-v3.0'
});

// Voyage
const voyage = new VoyageEmbeddings({
  apiKey: process.env.VOYAGE_API_KEY,
  model: 'voyage-3'
});

// NVIDIA
const nvidia = new NvidiaEmbeddings({
  apiKey: process.env.NVIDIA_API_KEY
});

// Factory function
const embedder = getEmbedder('openai', { apiKey: '...' });

// Use with putMany
await mem.putMany(docs, { embedder: openai });

// Use with find
await mem.find('query', { embedder: gemini });
```

### Local Embeddings (No API Required)

```typescript theme={null}
import { LOCAL_EMBEDDING_MODELS } from '@memvid/sdk';

await mem.put({
  text: 'content',
  enableEmbedding: true,
  embeddingModel: LOCAL_EMBEDDING_MODELS.BGE_SMALL  // 384d, fast
});

// Available local models
LOCAL_EMBEDDING_MODELS.BGE_SMALL   // 384d - fastest
LOCAL_EMBEDDING_MODELS.BGE_BASE    // 768d - balanced
LOCAL_EMBEDDING_MODELS.NOMIC       // 768d - general purpose
LOCAL_EMBEDDING_MODELS.GTE_LARGE   // 1024d - highest quality
```

***

## Error Handling

```typescript theme={null}
import {
  MemvidError,
  CapacityExceededError,    // MV001
  TicketInvalidError,       // MV002
  TicketReplayError,        // MV003
  LexIndexDisabledError,    // MV004
  TimeIndexMissingError,    // MV005
  VerifyFailedError,        // MV006
  LockedError,              // MV007
  ApiKeyRequiredError,      // MV008
  MemoryAlreadyBoundError,  // MV009
  FrameNotFoundError,       // MV010
  VecIndexDisabledError,    // MV011
  CorruptFileError,         // MV012
  VecDimensionMismatchError // MV014
} from '@memvid/sdk';

try {
  await mem.put({ title: 'Large file', file: 'huge.bin' });
} catch (err) {
  if (err instanceof CapacityExceededError) {
    console.log('Storage capacity exceeded (MV001)');
  } else if (err instanceof LockedError) {
    console.log('File locked by another process (MV007)');
  } else if (err instanceof VecIndexDisabledError) {
    console.log('Enable vector index first (MV011)');
  }
}
```

***

## Asset Extraction

```typescript theme={null}
// Get frame content
const content = await mem.view(frameId);
const contentByUri = await mem.viewByUri('mv2://docs/intro');

// Extract binary assets (PDF, images)
const asset = await mem.extractAsset(frameId);
console.log(asset.mimeType, asset.filename, asset.data);

// Get frame metadata
const info = await mem.getFrameInfo(frameId);
console.log(info.uri, info.title, info.timestamp);
```

***

## Environment Variables

| Variable            | Description                |
| ------------------- | -------------------------- |
| `MEMVID_API_KEY`    | Dashboard API key for sync |
| `OPENAI_API_KEY`    | OpenAI embeddings and LLM  |
| `GEMINI_API_KEY`    | Gemini embeddings          |
| `MISTRAL_API_KEY`   | Mistral embeddings         |
| `COHERE_API_KEY`    | Cohere embeddings          |
| `VOYAGE_API_KEY`    | Voyage embeddings          |
| `NVIDIA_API_KEY`    | NVIDIA embeddings          |
| `ANTHROPIC_API_KEY` | Claude for entities        |
| `MEMVID_MODELS_DIR` | Model cache directory      |
| `MEMVID_OFFLINE`    | Use cached models only     |

***

## Deploying to Vercel

The Memvid Node.js SDK uses native bindings (N-API) for optimal performance. When deploying to Vercel's serverless environment, you need to configure Next.js to bundle the native binary correctly.

### next.config.ts Configuration

Add `outputFileTracingIncludes` to ensure the native `.node` files are bundled with your serverless functions:

```typescript theme={null}
// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    outputFileTracingIncludes: {
      '/api/*': [
        './node_modules/@memvid/sdk-linux-x64-gnu/**/*',
        './node_modules/@memvid/sdk/**/*',
      ],
    },
  },
};

export default nextConfig;
```

### Explicit Platform Package (Optional)

For more reliable deployments, explicitly add the Linux platform package to your dependencies:

```json theme={null}
{
  "dependencies": {
    "@memvid/sdk": "^2.0.146",
    "@memvid/sdk-linux-x64-gnu": "^2.0.146"
  }
}
```

<Note>
  Vercel's serverless runtime uses Amazon Linux 2 (x64). The SDK automatically selects the correct platform binary, but explicit inclusion ensures bundling works correctly.
</Note>

### Serverless /tmp Storage

Vercel's serverless functions have ephemeral `/tmp` storage that doesn't persist between invocations. For production apps:

1. **Use cloud storage** (S3, R2, etc.) to persist `.mv2` files
2. **Download on-demand** when the function cold starts
3. **Pass files as buffers** between API routes instead of file paths

```typescript theme={null}
// Example: Download from S3 if not in /tmp
import { existsSync } from 'fs';
import { writeFile } from 'fs/promises';

const localPath = `/tmp/${memoryId}.mv2`;

if (!existsSync(localPath)) {
  const buffer = await downloadFromS3(userId, memoryId);
  await writeFile(localPath, buffer);
}

const mem = await open(localPath);
```

### Troubleshooting

| Error                                             | Solution                                                 |
| ------------------------------------------------- | -------------------------------------------------------- |
| `Native binary not found for platform: linux-x64` | Add `outputFileTracingIncludes` config                   |
| `GLIBC_2.35 not found`                            | Ensure you're using SDK v2.0.146+ (built for glibc 2.26) |
| `ENOENT: no such file or directory`               | Files in `/tmp` don't persist; use cloud storage         |

***

## TypeScript Types

```typescript theme={null}
import type {
  PutInput,
  PutManyInput,
  FindInput,
  AskInput,
  MemoryCard,
  MemoryCardInput,
  EntityState,
  FrameInfo,
  TableInfo,
  SessionSummary,
  MemvidErrorCode
} from '@memvid/sdk';
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart/five-minute-guide">
    Build your first AI memory in 5 minutes
  </Card>

  <Card title="Embedding Providers" icon="cube" href="/concepts/embedding-models">
    Compare local and external embedding options
  </Card>

  <Card title="Framework Integrations" icon="puzzle-piece" href="/frameworks/overview">
    LangChain, LlamaIndex, Vercel AI, and more
  </Card>

  <Card title="Memory Cards" icon="brain" href="/concepts/entity-extraction">
    O(1) entity lookups and fact extraction
  </Card>
</CardGroup>
