MemorySyncMemorySync
Node SDK

Overview

The memorysync-sdk package on npm is a single typed client that ships a CommonJS build, an ESM build, and complete .d.ts declarations. There is no separate “sync” and “async” class — every method is a normal Promise, the way Node code already works.

How to import it

TYPESCRIPT
// ESM / TypeScript
import { MemorySyncClient } from "memorysync-sdk";
// CommonJS
const { MemorySyncClient } = require("memorysync-sdk");

The exports also include the six error classes and every named response type:

TYPESCRIPT
import {
MemorySyncClient,
// errors
MemorySyncError, AuthError, NotFoundError,
ValidationError, RateLimitError, ServerError,
// types
type AddRequest, type AddResponse, type AddSkippedResponse,
type BulkAddItem, type BulkAddResponse, type BulkAddItemResult,
type QueryRequest, type QueryResponse,
type UpdateRequest, type SummarizeRequest,
type ComposeRequest, type ComposeResponse,
type RelationshipType, type RelationCreateRequest, type RelationRecord,
type ExportResponse, type MemoryRecord, type QueryFilters,
} from "memorysync-sdk";

Every method on the client

MethodReturnsHTTP route
add(req: AddRequest)Promise<AddResponse>POST /memory/add
bulkAdd(items, opts?)Promise<BulkAddResponse>POST /memory/bulk-add
query(req: QueryRequest)Promise<QueryResponse>POST /memory/query
get(memoryId: number)Promise<MemoryRecord>GET /memory/{id}
update(memoryId, req: UpdateRequest)Promise<MemoryRecord>PATCH /memory/{id}
forget(memoryIds, reason?)Promise<number[]>DELETE /memory/forget
summarize(req: SummarizeRequest)Promise<MemoryRecord>POST /memory/summarize
compose(req: ComposeRequest)Promise<ComposeResponse>POST /memory/compose
exportAll()Promise<ExportResponse>GET /memory/export
createRelation(fromId, req)Promise<RelationRecord>POST /memory/{id}/relations

A minimal program, end to end

TYPESCRIPT
import { MemorySyncClient, AuthError, RateLimitError } from "memorysync-sdk";
const client = new MemorySyncClient({
apiKey: process.env.MEMORYSYNC_API_KEY!,
baseUrl: "https://api.memorysync.io",
endUserId: "user_123", // required for API-key auth
});
try {
await client.add({ text: "Decided to ship behind a flag." });
const hits = await client.query({ query: "decision behind a flag", k: 5 });
for (const m of hits.memories) {
console.log(m.id, m.text, m.score);
}
} catch (e) {
if (e instanceof AuthError) console.error("bad key");
else if (e instanceof RateLimitError) console.error("retry in", e.retryAfterSeconds);
else throw e;
}

camelCase on the wire? No — we translate

Method arguments use camelCase (sessionId, endUserId, traversalDepth) but the JSON body the SDK puts on the wire uses the snake_case the server expects. Same for responses. You write idiomatic TypeScript; the client speaks the server’s dialect.

Runtime requirements

  • A modern Node runtime that ships global fetch and AbortController. Anything from the last few LTS lines qualifies.
  • Or any TypeScript runtime where fetch is a global (Deno, Bun, browsers, edge runtimes). You can also pass a custom fetch via the constructor.
  • No native dependencies. The package is pure JavaScript with type declarations.

Errors are typed and instanceof-checkable

Use instanceof, not status codes
The status code is on every error if you need it, but most code is cleaner with e instanceof RateLimitError, e instanceof AuthError, etc. The class hierarchy matches the Python SDK exactly.

Read these next