MemoryKit

Build document Q&A

Let users upload a PDF and search it — build document retrieval in minutes.

Build a "search your PDF" experience: users upload a document, wait for processing, then search and retrieve relevant passages from that document.

Prerequisites

  • A MemoryKit API key (get one here)
  • Node.js 18+ or Python 3.8+

Step 1: Upload and process

Upload the user's file and poll until processing completes.

import { MemoryKit } from "memorykit";
const mk = new MemoryKit({ apiKey: process.env.MEMORYKIT_API_KEY! });
 
async function uploadAndWait(file: Blob, title: string) {
  const memory = await mk.memories.upload({ file, title, tags: ["document-qa"] });
 
  // Poll until ready
  let current = await mk.memories.get(memory.id);
  while (current.status === "processing" || current.status === "pending") {
    await new Promise((r) => setTimeout(r, 2000));
    current = await mk.memories.get(memory.id);
  }
 
  if (current.status === "failed") {
    throw new Error(`Processing failed for ${memory.id}`);
  }
 
  return current; // status === "completed"
}
 
const memory = await uploadAndWait(userFile, "Quarterly Report Q4 2025");
console.log(`Ready: ${memory.id}, ${memory.tokenCount} tokens`);

For production, use webhooks instead of polling. Listen for memory.completed and memory.failed events.

Step 2: Search the document

Use tags and precision to scope retrieval to just this document's content.

async function searchDocument(memoryId: string, question: string) {
  return mk.memories.search({
    query: question,
    tags: `doc_${memoryId}`,
    limit: 5,
    precision: "high",
  });
}
 
const results = await searchDocument(memory.id, "What was the total revenue in Q4?");
for (const hit of results.results) {
  console.log(`[${hit.score.toFixed(2)}] ${hit.content}`);
}

Step 3: Multi-document sessions

Support multiple documents in one session. Upload several files and query across all of them.

// Upload multiple documents
const sessionId = `session_${Date.now()}`;
const memoryIds: string[] = [];
 
for (const file of userFiles) {
  const memory = await uploadAndWait(file.blob, file.name);
  memoryIds.push(memory.id);
}
 
// Search across all documents in this session
const results = await mk.memories.search({
  query: "revenue growth across all reports",
  tags: `session_${sessionId}`,
  limit: 10,
});

Step 4: Clean up

Delete temporary documents when the session ends.

async function cleanupSession(memoryIds: string[]) {
  await Promise.all(memoryIds.map((id) => mk.memories.delete(id)));
  console.log(`Deleted ${memoryIds.length} documents`);
}

Summary

WhatHow
Upload filesupload() with polling or webhooks
Scope to documentsearch() with tags scoped to the document
Search passagessearch() with limit and precision
Multi-documentTag all documents with a session tag, then search by tag
Clean updelete() each memory when done

Key features used: File upload, Search

Edit on GitHub

On this page