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

# JavaScript SDK

> Node.js and browser SDK for Mengram with full TypeScript support.

## Installation

```bash theme={null}
npm install mengram-ai
```

## Quick Start

```javascript theme={null}
const { MengramClient } = require('mengram-ai');
const m = new MengramClient('om-your-api-key');

// Add memories
await m.add([
    { role: 'user', content: 'Fixed the auth bug using rate limiting.' },
]);

// Semantic search
const results = await m.search('auth issues');

// Unified search — all 3 types
const all = await m.searchAll('deployment issues');
// { semantic: [...], episodic: [...], procedural: [...] }

// Cognitive Profile
const profile = await m.getProfile('alice');
// { system_prompt: "You are talking to Alice..." }
```

## TypeScript

```typescript theme={null}
import { MengramClient, MengramError, QuotaExceededError } from 'mengram-ai';

const m = new MengramClient('om-...');

const results = await m.search('preferences');
const events = await m.episodes({ query: 'deployment' });
const procs = await m.procedures({ query: 'release' });
```

## Constructor

```javascript theme={null}
const m = new MengramClient('om-your-key', {
    baseUrl: 'https://mengram.io',  // default
    timeout: 30000,                  // 30s default
});
```

***

## Core Methods

### add(messages, options?)

Add memories from a conversation. Extracts all 3 memory types.

```javascript theme={null}
const result = await m.add([
    { role: 'user', content: 'We use PostgreSQL and Railway' },
    { role: 'assistant', content: 'Got it.' },
], {
    userId: 'alice',
    agentId: 'support-bot',
    appId: 'production',
    expirationDate: '2027-01-01T00:00:00Z',
    source: 'slack',                          // provenance source
    metadata: { channel: '#engineering' },     // arbitrary metadata
    agentMode: true,                           // extract from all speakers (user + assistant)
});
// { status: 'accepted', job_id: 'job-...' }
```

### addText(text, options?)

Add memories from plain text.

```javascript theme={null}
await m.addText('Meeting notes: decided to use Redis for caching', {
    userId: 'alice',
    source: 'email',
    metadata: { subject: 'Weekly sync' },
});
```

### addFile(file, options?)

Upload a file and extract structured memories. Supports PDF (vision AI), DOCX, TXT, MD. Returns immediately with job\_id.

```javascript theme={null}
// Node.js — pass a file path
const result = await m.addFile('./meeting-notes.pdf');
// { status: 'accepted', job_id: 'job-...', file_type: 'pdf', page_count: 12 }

// Browser — pass a File object from <input type="file">
await m.addFile(fileInput.files[0]);

// Poll for completion
await m.waitForJob(result.job_id);
```

Options: `userId`, `agentId`, `runId`, `appId`, `filename` (override filename for Blob inputs).

**File size limits:** Free 10MB, Pro 50MB, Business 100MB.

### search(query, options?)

Semantic search with re-ranking.

```javascript theme={null}
const results = await m.search('database preferences', {
    limit: 10,
    graphDepth: 3,
    userId: 'alice',
});
```

### searchAll(query, options?)

Unified search across all 3 memory types.

```javascript theme={null}
const all = await m.searchAll('deployment issues', { limit: 5 });
// { semantic: [...], episodic: [...], procedural: [...] }
```

### getAll(options?) / getAllFull(options?)

```javascript theme={null}
const memories = await m.getAll({ userId: 'alice' });
const full = await m.getAllFull({ userId: 'alice' });  // with full facts
```

### get(name, options?) / delete(name, options?)

```javascript theme={null}
const entity = await m.get('PostgreSQL');   // returns null if not found
const ok = await m.delete('PostgreSQL');    // returns true/false
```

### fixEntityType(name, newType, options?)

```javascript theme={null}
await m.fixEntityType('React', 'technology');
```

### stats(options?) / graph(options?)

```javascript theme={null}
const stats = await m.stats();
const graph = await m.graph();  // { nodes: [...], edges: [...] }
```

***

## Cognitive Profile

### getProfile(userId?, options?)

Generate a ready-to-use system prompt from memory.

```javascript theme={null}
const profile = await m.getProfile('alice', { force: true });
console.log(profile.system_prompt);
console.log(profile.facts_used);
```

***

## Episodic Memory

### episodes(options?)

```javascript theme={null}
// Search
const events = await m.episodes({ query: 'deployment', limit: 5 });

// List recent
const recent = await m.episodes({ limit: 20 });

// Time range
const jan = await m.episodes({
    after: '2026-01-01',
    before: '2026-02-01',
});
```

***

## Procedural Memory

### procedures(options?)

```javascript theme={null}
const procs = await m.procedures({ query: 'deploy' });
```

### procedureFeedback(id, options?)

```javascript theme={null}
await m.procedureFeedback(procId, { success: true });
await m.procedureFeedback(procId, {
    success: false,
    context: 'Build OOM at step 3',
    failedAtStep: 3,
});
```

### procedureHistory(id) / procedureEvolution(id)

```javascript theme={null}
const history = await m.procedureHistory(procId);
const evolution = await m.procedureEvolution(procId);
```

***

## Timeline

### timeline(options?)

```javascript theme={null}
const facts = await m.timeline({
    after: '2026-01-01',
    before: '2026-02-01',
    limit: 20,
});
```

***

## Agents

### runAgents(options?)

```javascript theme={null}
await m.runAgents({ agent: 'curator' });
await m.runAgents();  // runs all agents
```

### agentHistory(options?) / agentStatus(options?)

```javascript theme={null}
const history = await m.agentHistory({ limit: 5 });
const status = await m.agentStatus();
```

***

## Insights & Reflections

```javascript theme={null}
await m.reflect();
const insights = await m.insights();
const refs = await m.reflections({ scope: 'cross' });
```

***

## Memory Management

```javascript theme={null}
await m.dedup();                           // merge duplicate entities
await m.dedupAll();                        // dedup facts across all entities
await m.dedupEntity('PostgreSQL');         // dedup one entity
await m.merge('React.js', 'React');        // merge entities
await m.mergeUser();                       // merge "User" into primary
await m.archiveFact('Entity', 'old fact'); // archive a fact
await m.reindex();                         // re-embed all entities
```

### feed(options?)

```javascript theme={null}
const feed = await m.feed({ limit: 20 });
```

***

## Webhooks

```javascript theme={null}
await m.createWebhook({
    url: 'https://your-app.com/hook',
    eventTypes: ['memory_add', 'memory_update'],
    secret: 'hmac-secret',
});
const hooks = await m.listWebhooks();
await m.updateWebhook(1, { active: false });
await m.deleteWebhook(1);
```

***

## Teams

```javascript theme={null}
const team = await m.createTeam('Engineering', 'Shared memory');
await m.joinTeam('invite-code');
const teams = await m.listTeams();
const members = await m.teamMembers(teamId);

await m.shareMemory('PostgreSQL', teamId);
await m.unshareMemory('PostgreSQL', teamId);
await m.leaveTeam(teamId);
await m.deleteTeam(teamId);  // owner only
```

***

## Smart Triggers

```javascript theme={null}
const triggers = await m.getTriggers('alice', { includeFired: true });
await m.processTriggers();
await m.dismissTrigger(triggerId);
await m.detectTriggers('alice');
```

***

## API Keys

```javascript theme={null}
const keys = await m.listKeys();
const newKey = await m.createKey('production');
await m.renameKey(keyId, 'staging');
await m.revokeKey(keyId);
```

***

## Billing

```javascript theme={null}
const billing = await m.getBilling();
const checkout = await m.createCheckout('pro');
const portal = await m.createPortal();
```

***

## Jobs

```javascript theme={null}
const status = await m.jobStatus('job-abc');
const result = await m.waitForJob('job-abc', {
    pollInterval: 1000,
    maxWait: 60000,
});
```

***

## Import Data

```javascript theme={null}
// ChatGPT export (requires jszip)
await m.importChatgpt('~/Downloads/chatgpt-export.zip', {
    chunkSize: 20,
    onProgress: (current, total, title) => console.log(`${current}/${total}: ${title}`),
});

// Obsidian vault
await m.importObsidian('~/Documents/MyVault');

// Text/markdown files
await m.importFiles(['notes.md', 'journal.txt']);
```

***

## Multi-User Isolation

```javascript theme={null}
// Each userId gets its own memory space
await m.add([{ role: 'user', content: 'I prefer dark mode' }], { userId: 'alice' });
await m.add([{ role: 'user', content: 'I prefer light mode' }], { userId: 'bob' });

const alice = await m.searchAll('preferences', { userId: 'alice' });
// Only Alice's memories
```

***

## Error Handling

```javascript theme={null}
const { MengramClient, MengramError, QuotaExceededError } = require('mengram-ai');

try {
    await m.add(messages);
} catch (e) {
    if (e instanceof QuotaExceededError) {
        console.log('Upgrade your plan:', e.message);
    } else if (e instanceof MengramError) {
        console.log(`API error ${e.statusCode}: ${e.message}`);
    }
}
```

***

## Quota Usage

After any API call, check your current quota usage via the `.quota` property:

```javascript theme={null}
await m.search('test');
console.log(m.quota);
// { add: { used: 5, limit: 30 }, search: { used: 12, limit: 100 } }

// Check before hitting the wall
const { search } = m.quota;
if (search && search.used >= search.limit * 0.8) {
    console.warn('Warning: approaching search quota limit');
}
```

The quota is read from response headers (`X-Quota-Add-Used`, `X-Quota-Add-Limit`, `X-Quota-Search-Used`, `X-Quota-Search-Limit`) and reflects usage at the time of the last API call.
