Use this guide when you are integrating Memvid through HTTP in platforms like n8n, Replit, Lovable, or v0.
This page is the shared contract for API-first integrations. Platform pages should reuse these request shapes and reliability patterns.
Base Setup
- Base URL:
https://api.memvid.com
- Auth header (recommended):
Authorization: Bearer mv2_YOUR_API_KEY
- Alternative auth header:
X-API-Key: mv2_YOUR_API_KEY
Golden Path (Minimal Production Flow)
- Create or select a memory ID
- Ingest documents (JSON text, file, or URL)
- Use
find for retrieval UX
- Use
ask for grounded synthesis
- Return answer with sources in your app UI
Canonical Request Shapes
Create Memory
POST /v1/memories
Content-Type: application/json
{
"name": "Support KB",
"description": "Runbooks and policies"
}
Add Documents (JSON)
POST /v1/memories/:id/documents
Content-Type: application/json
{
"documents": [
{
"title": "P1 Playbook",
"text": "Acknowledge P1 in 10 minutes.",
"tags": ["incident", "support"]
}
]
}
Find
POST /v1/memories/:id/find
Content-Type: application/json
{
"query": "How quickly do we acknowledge P1 incidents?",
"topK": 5
}
Ask
POST /v1/memories/:id/ask
Content-Type: application/json
{
"question": "What is our P1 SLA?",
"options": {
"model": "gpt-4o-mini",
"includeSources": true,
"maxContextChunks": 10
}
}
Typed Client Wrapper (TypeScript)
type MemvidRequestInit = Omit<RequestInit, "headers"> & {
headers?: Record<string, string>;
timeoutMs?: number;
retries?: number;
};
class MemvidHttpError extends Error {
constructor(
public status: number,
public body: string,
public method: string,
public path: string
) {
super(`Memvid ${method} ${path} failed (${status})`);
}
}
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
export async function memvidRequest<T = unknown>(
path: string,
init: MemvidRequestInit = {}
): Promise<T> {
const baseUrl = process.env.MEMVID_API_BASE || "https://api.memvid.com";
const apiKey = process.env.MEMVID_API_KEY;
if (!apiKey) throw new Error("Missing MEMVID_API_KEY");
const retries = init.retries ?? 2;
const timeoutMs = init.timeoutMs ?? 15000;
const method = init.method || "GET";
for (let attempt = 0; attempt <= retries; attempt++) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
const res = await fetch(`${baseUrl}${path}`, {
...init,
signal: controller.signal,
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
...(init.headers || {}),
},
});
if (res.status === 204) return null as T;
const text = await res.text();
if (!res.ok) {
const retryable = res.status === 429 || res.status >= 500;
if (retryable && attempt < retries) {
await sleep(250 * Math.pow(2, attempt));
continue;
}
throw new MemvidHttpError(res.status, text, method, path);
}
return text ? (JSON.parse(text) as T) : (null as T);
} catch (err) {
const retryable = err instanceof Error && err.name === "AbortError";
if (!retryable || attempt >= retries) throw err;
await sleep(250 * Math.pow(2, attempt));
} finally {
clearTimeout(timeout);
}
}
throw new Error("Unexpected retry loop exit");
}
Async Ingestion and Job Polling
Large files may process asynchronously. Poll job status when ingestion returns a job ID.
type JobStatus = "queued" | "processing" | "completed" | "failed";
export async function waitForJob(jobId: string, timeoutMs = 120000) {
const started = Date.now();
while (Date.now() - started < timeoutMs) {
const job = await memvidRequest<{ status: JobStatus; error?: string }>(
`/v1/jobs/${jobId}`
);
if (job.status === "completed") return job;
if (job.status === "failed") throw new Error(job.error || "Memvid job failed");
await sleep(1500);
}
throw new Error(`Timed out waiting for job ${jobId}`);
}
Reliability Checklist
- Keep API keys server-side only.
- Use memory-scoped keys for least privilege.
- Retry
429 and 5xx with backoff.
- Enforce request timeouts to prevent hanging workers.
- Log method, path, status, and request IDs for debugging.
- Show source snippets in UI for grounded trust.
5-Minute Smoke Test
Run these calls in order and verify non-empty responses:
POST /v1/memories -> get memory.id
POST /v1/memories/:id/documents -> ingest sample text
POST /v1/memories/:id/find -> expect at least one hit
POST /v1/memories/:id/ask -> expect answer/text and optional sources
Next Pages