Skip to content

JavaScript SDK

beginner

Complete reference for the @engramma/sdk package — TypeScript-first, browser and Node.js support, error handling, interceptors, and streaming.

Installation

npm install @engramma/sdk

Requires Node.js 18+ or any modern browser with fetch support. Full TypeScript types included.


Initialization

import { Engramma } from '@engramma/sdk';

const client = new Engramma({
  apiKey: process.env.ENGRAMMA_API_KEY
});
ParameterTypeDefaultDescription
apiKeystringYour API key (nx_live_ or nx_test_ prefix)
baseUrlstringhttps://api.engramma-memory.comAPI base URL
timeoutnumber30000Request timeout in milliseconds
maxRetriesnumber3Automatic retries on 5xx and 429
orgIdstring?undefinedDefault organization for all requests
fetchtypeof fetch?globalThis.fetchCustom fetch implementation

Memory operations

store

const result = await client.store({
  text: 'The deployment window is Tuesday 2-4pm UTC',
  metadata: { category: 'ops', priority: 'high' },
  importance: 0.9
});
console.log(result.patternId);  // 'pat_7f3a2b'
console.log(result.confidence); // 0.93
ParameterTypeRequiredDescription
textstringYesThe content to store
metadataRecord<string, string>NoKey-value metadata
importancenumberNoOverride importance (0.0–1.0)
contextstringNoAdditional context for encoding

batchStore

const results = await client.batchStore([
  { text: 'Alice joined the team on Jan 5' },
  { text: 'Project deadline is March 15', importance: 0.95 },
  { text: 'Budget approved for Q2', metadata: { dept: 'finance' } }
]);
console.log(`Stored ${results.stored} patterns`);

retrieve

const results = await client.retrieve({
  query: 'When can we deploy?',
  topK: 5,
  minConfidence: 0.5,
  pathway: 'auto'
});
for (const r of results) {
  console.log(`${r.text} (confidence: ${r.confidence}, pathway: ${r.pathway})`);
}
ParameterTypeRequiredDescription
querystringYesNatural-language question
topKnumberNoMax results (default: 5)
minConfidencenumberNoMinimum confidence threshold
pathwaystringNoForce pathway: auto, exact, energy, attention
metadataFilterRecord<string, string>NoFilter by metadata fields

recall

const results = await client.recall({
  query: 'What happened before the outage?',
  temporalWeight: 0.8,
  causalWeight: 0.7,
  limit: 10
});
for (const r of results) {
  console.log(`${r.text} (relevance: ${r.relevanceScore})`);
}

explain

const explanation = await client.explain({
  query: 'When can we deploy?',
  level: 'detailed' // 'brief' | 'detailed' | 'debug'
});
console.log(explanation.summary);
console.log(explanation.pathwayScores);
console.log(explanation.reasoningChain);

forget

await client.forget('pat_7f3a2b');
// or soft-delete
await client.forget('pat_7f3a2b', { soft: true });

Text operations

// Search
const results = await client.text.search({
  query: 'deployment',
  filters: { category: 'ops' },
  sort: 'relevance',
  limit: 20
});

// Summarize
const summary = await client.text.summarize({
  topic: 'Q1 project updates',
  maxLength: 200
});

// Compare
const comparison = await client.text.compare({
  patternIdA: 'pat_abc123',
  patternIdB: 'pat_def456'
});

// Tag
await client.text.tag('pat_abc123', ['important', 'ops']);

// Link
await client.text.link({
  sourceId: 'pat_abc123',
  targetId: 'pat_def456',
  relation: 'caused_by'
});

// Timeline
const timeline = await client.text.timeline({
  topic: 'deployment',
  from: '2026-01-01',
  to: '2026-01-31'
});

Engine operations

// Consolidation preview
const preview = await client.engine.consolidation.preview();
console.log(`Would merge: ${preview.mergeCandidates}`);

// Trigger consolidation
const result = await client.engine.consolidation.merge();
console.log(`Merged: ${result.merged}, Pruned: ${result.pruned}`);

// Diagnostics
await client.engine.diagnostics.prefetch({ queries: ['deployment', 'budget'] });
await client.engine.diagnostics.warmup();
const structure = await client.engine.diagnostics.structure();

Organization & billing

// List organizations
const orgs = await client.organizations.list();

// Usage summary
const usage = await client.usage.summary();
console.log(`Patterns: ${usage.patterns.used}/${usage.patterns.limit}`);

// Notifications
const notifications = await client.notifications.list({ unreadOnly: true });
console.log(`Unread: ${notifications.unreadCount}`);

GDPR

// List consents
const consents = await client.gdpr.consents();

// Request data export
const exportReq = await client.gdpr.export({ format: 'json' });
console.log(`Export ready in ~${exportReq.estimatedTimeMinutes} min`);

// Request erasure
await client.gdpr.erasure({ confirm: true, reason: 'Account closure' });

TypeScript types

All methods return fully typed responses. Types are exported for use in your application:

import type {
  StoreResult,
  RetrieveResult,
  RecallResult,
  Explanation,
  UsageSummary,
  ConsentRecord,
  Pathway,
  EngrammaConfig
} from '@engramma/sdk';

// All responses are strongly typed
const result: StoreResult = await client.store({ text: 'typed' });
result.patternId;   // string
result.confidence;  // number
result.pathway;     // 'exact' | 'energy' | 'attention'

// Generic support for metadata
interface MyMeta { category: string; priority: string }
const results = await client.retrieve<MyMeta>({
  query: 'test'
});
results[0].metadata.category; // typed as string

Error handling

The SDK throws typed errors for all failure cases:

import {
  EngrammaError,        // Base error class
  AuthenticationError,  // 401
  PermissionError,      // 403
  NotFoundError,        // 404
  ValidationError,      // 422
  RateLimitError,       // 429
  ServerError           // 5xx
} from '@engramma/sdk';

try {
  const results = await client.retrieve({ query: 'test' });
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter}s`);
  } else if (error instanceof AuthenticationError) {
    console.log('Invalid API key');
  } else if (error instanceof EngrammaError) {
    console.log(`Error ${error.statusCode}: ${error.message}`);
  }
}
Error ClassHTTP StatusWhen
AuthenticationError401Invalid or expired API key
PermissionError403Key lacks required scope
NotFoundError404Resource does not exist
ValidationError422Invalid request parameters
RateLimitError429Too many requests
ServerError5xxInternal server error

Interceptors

Add request/response interceptors for logging, metrics, or custom headers:

const client = new Engramma({
  apiKey: process.env.ENGRAMMA_API_KEY
});

// Request interceptor
client.interceptors.request.use((config) => {
  console.log(`[${config.method}] ${config.url}`);
  config.headers['X-Request-Id'] = crypto.randomUUID();
  return config;
});

// Response interceptor
client.interceptors.response.use(
  (response) => {
    console.log(`Response: ${response.status} in ${response.duration}ms`);
    return response;
  },
  (error) => {
    console.error(`Failed: ${error.message}`);
    throw error;
  }
);

Retry policy

The SDK automatically retries failed requests with exponential backoff:

ConditionRetriedBackoff
429 (Rate Limit)YesUses Retry-After header
500, 502, 503, 504YesExponential: 1s, 2s, 4s
Network timeoutYesExponential: 1s, 2s, 4s
4xx (other)No

Configure retry behavior:

const client = new Engramma({
  apiKey: 'nx_live_...',
  maxRetries: 5,           // default: 3
  retryBackoff: 2.0,       // backoff multiplier
  retryMaxWait: 30000      // max wait between retries (ms)
});

Browser vs Node.js

The SDK works in both environments with zero configuration:

FeatureNode.jsBrowser
fetchNative (18+) or polyfillNative
StreamingYes (ReadableStream)Yes
File uploadsYes (Buffer/Stream)Yes (Blob/File)
Environment variablesprocess.envBuild-time injection
Warning

Never expose your API key in client-side browser code. Use a backend proxy or edge function to forward requests.

Next steps