Skip to main content
Send any raw content to Supermemory — conversations, documents, files, URLs. We extract the memories automatically.
Use customId to identify your content (conversation ID, document ID, etc.). This enables updates and prevents duplicates.

Quick Start

import Supermemory from 'supermemory';

const client = new Supermemory();

// Add text content
await client.add({
  content: "Machine learning enables computers to learn from data",
  containerTag: "user_123",
  metadata: { category: "ai" }
});

// Add a URL (auto-extracted)
await client.add({
  content: "https://youtube.com/watch?v=dQw4w9WgXcQ",
  containerTag: "user_123"
});
Response:
{ "id": "abc123", "status": "queued" }

Updating Content

Use customId to update existing documents or conversations. When you send content with the same customId, Supermemory intelligently processes only what’s new.

Two ways to update:

Option 1: Send only the new content
// First request
await client.add({
  content: "user: Hi, I'm Sarah.\nassistant: Nice to meet you!",
  customId: "conv_123",
  containerTag: "user_sarah"
});

// Later: send only new messages
await client.add({
  content: "user: What's the weather?\nassistant: It's sunny today.",
  customId: "conv_123",  // Same ID — Supermemory links them
  containerTag: "user_sarah"
});
Option 2: Send the full updated content
// Supermemory detects the diff and only processes new parts
await client.add({
  content: "user: Hi, I'm Sarah.\nassistant: Nice to meet you!\nuser: What's the weather?\nassistant: It's sunny today.",
  customId: "conv_123",
  containerTag: "user_sarah"
});
Both work — choose what fits your architecture.

Replace entire document

To completely replace a document’s content (not append), use memories.update():
// Replace the entire document content
await client.memories.update("doc_id_123", {
  content: "Completely new content replacing everything",
  metadata: { version: 2 }
});
This triggers full reprocessing of the document.

Formatting conversations

Format your conversations however you want. Supermemory handles any string format:
// Simple string
content: "user: Hello\nassistant: Hi there!"

// JSON stringify
content: JSON.stringify(messages)

// Template literal
content: messages.map(m => `${m.role}: ${m.content}`).join('\n')

// Any format — just make it a string
content: formatConversation(messages)

Upload Files

Upload PDFs, images, and documents directly.
import fs from 'fs';

await client.memories.uploadFile({
  file: fs.createReadStream('document.pdf'),
  containerTags: 'user_123'
});

Supported File Types

TypeFormatsProcessing
DocumentsPDF, DOC, DOCX, TXT, MDText extraction, OCR for scans
ImagesJPG, PNG, GIF, WebPOCR text extraction
SpreadsheetsCSV, Google SheetsStructured data extraction
VideosYouTube URLs, MP4Auto-transcription
Limits: 50MB max file size

Parameters

ParameterTypeDescription
contentstringRequired. Any raw content — text, conversations, URLs, HTML
customIdstringRecommended. Your ID for the content (conversation ID, doc ID). Enables updates and deduplication
containerTagstringGroup by user/project. Required for user profiles
metadataobjectKey-value pairs for filtering (strings, numbers, booleans)
Content Types:
// Any text — conversations, notes, documents
{ content: "Meeting notes from today's standup" }
{ content: JSON.stringify(messages) }

// URLs (auto-detected and extracted)
{ content: "https://example.com/article" }
{ content: "https://youtube.com/watch?v=abc123" }

// Markdown, HTML, or any format
{ content: "# Project Docs\n\n## Features\n- Real-time sync" }
Container Tags:
// By user
{ containerTag: "user_123" }

// By project
{ containerTag: "project_alpha" }

// Hierarchical
{ containerTag: "org_456_team_backend" }
Custom IDs (Recommended):
// Use IDs from your system
{ customId: "conv_abc123" }        // Conversation ID
{ customId: "doc_456" }            // Document ID
{ customId: "thread_789" }         // Thread ID
{ customId: "meeting_2024_01_15" } // Meeting ID

// Updates: same customId = same document
// Supermemory only processes new/changed content
await client.add({
  content: "Updated content...",
  customId: "doc_456"  // Links to existing document
});
Metadata:
{
  metadata: {
    source: "slack",
    author: "john",
    priority: 1,
    reviewed: true
  }
}
  • No nested objects or arrays
  • Values: string, number, or boolean only

Processing Pipeline

When you add content, Supermemory:
  1. Validates your request
  2. Stores the document and queues for processing
  3. Extracts content (OCR, transcription, web scraping)
  4. Chunks into searchable memories
  5. Embeds for vector search
  6. Indexes for retrieval
Track progress with GET /v3/documents/{id}:
const doc = await client.memories.get("abc123");
console.log(doc.status); // "queued" | "processing" | "done"
Process multiple documents with rate limiting:
async function batchUpload(documents: Array<{id: string, content: string}>) {
  const results = [];

  for (const doc of documents) {
    try {
      const result = await client.add({
        content: doc.content,
        customId: doc.id,
        containerTag: "batch_import"
      });
      results.push({ id: doc.id, success: true, docId: result.id });
    } catch (error) {
      results.push({ id: doc.id, success: false, error });
    }

    // Rate limit: 1 second between requests
    await new Promise(r => setTimeout(r, 1000));
  }

  return results;
}
Tips:
  • Batch size: 3-5 documents at once
  • Delay: 1-2 seconds between requests
  • Use customId to track and deduplicate
StatusErrorCause
400BadRequestErrorMissing required fields, invalid parameters
401AuthenticationErrorInvalid or missing API key
403PermissionDeniedErrorInsufficient permissions
429RateLimitErrorToo many requests or quota exceeded
500InternalServerErrorProcessing failure
import { BadRequestError, RateLimitError } from 'supermemory';

try {
  await client.add({ content: "..." });
} catch (error) {
  if (error instanceof RateLimitError) {
    // Wait and retry
    await new Promise(r => setTimeout(r, 60000));
  } else if (error instanceof BadRequestError) {
    // Fix request parameters
    console.error("Invalid request:", error.message);
  }
}
Single delete:
await client.memories.delete("doc_id_123");
Bulk delete by IDs:
await client.memories.bulkDelete({
  ids: ["doc_1", "doc_2", "doc_3"]
});
Bulk delete by container tag:
// Delete all content for a user
await client.memories.bulkDelete({
  containerTags: ["user_123"]
});
Deletes are permanent — no recovery.

Next Steps