vectordb-client
v1.1.0
Published
TypeScript/JavaScript SDK for the VectorDB REST API
Maintainers
Readme
vectordb-client
TypeScript/JavaScript SDK for the VectorDB REST API.
Fully typed, works in Node.js 18+, Deno, and edge runtimes (Cloudflare Workers, Vercel Edge).
Installation
npm install vectordb-client
# or
yarn add vectordb-client
# or
pnpm add vectordb-clientQuick Start
import { VectorDBClient } from "vectordb-client";
const client = new VectorDBClient({
baseUrl: "https://your-vectordb.onrender.com",
apiKey: "your-api-key",
});
// Create a collection
await client.collections.create("articles", 384, "cosine");
// Store a vector
await client.vectors.upsert("articles", "doc-1", [0.1, 0.2, 0.9 /* ...384 dims */], {
title: "Hello World",
author: "Alice",
});
// Search
const results = await client.search.search("articles", queryVector, { k: 5 });
for (const r of results.results) {
console.log(r.external_id, r.score, r.metadata);
}Auth
// Register a new user
const { user, api_key } = await client.auth.register("[email protected]", "password123");
console.log(api_key.key); // save this
// Login
const { user, api_key } = await client.auth.login("[email protected]", "password123");Collections
// Create
// distance_metric: "cosine" (default) | "l2" | "ip"
const col = await client.collections.create("articles", 384, "cosine");
// List
const cols = await client.collections.list();
for (const c of cols) {
console.log(c.name, c.dim, c.vector_count);
}
// Get
const col = await client.collections.get("articles");
console.log(col.name, col.dim, col.vector_count);
// Update description
await client.collections.update("articles", "News articles corpus");
// Export all vectors
const exported = await client.collections.export("articles", 10000);
for (const v of exported.vectors) {
console.log(v.external_id, v.vector.slice(0, 3));
}
// Delete
await client.collections.delete("articles");Vectors
// Upsert (insert or update)
const result = await client.vectors.upsert(
"articles",
"doc-1",
[0.1, 0.2, 0.9 /* ...384 dims */],
{ title: "Hello", tags: ["ml", "nlp"] }
);
console.log(result.status); // "inserted" | "updated"
// Upsert with auto-embedding (server-side, if embedding provider configured)
await client.vectors.upsert("articles", "doc-1", undefined, undefined, undefined, {
text: "Hello world",
});
// Bulk upsert
const bulk = await client.vectors.bulkUpsert("articles", [
{ external_id: "doc-1", vector: [...], metadata: { title: "A" } },
{ external_id: "doc-2", vector: [...], metadata: { title: "B" } },
{ external_id: "doc-3", text: "auto-embed this" },
]);
console.log(bulk.results.length);
// Fetch a single vector by ID
const vec = await client.vectors.getVector("articles", "doc-1");
// Fetch multiple vectors by ID
const vecs = await client.vectors.batchFetch("articles", ["doc-1", "doc-2", "doc-3"]);
// Scroll through all vectors (cursor-based pagination)
let page = await client.vectors.scroll("articles", { limit: 100 });
while (page.has_more) {
for (const v of page.vectors) {
console.log(v.external_id);
}
page = await client.vectors.scroll("articles", { limit: 100, cursor: page.next_cursor });
}
// Scroll with metadata filter
const page = await client.vectors.scroll("articles", {
limit: 50,
filters: { author: "Alice" },
});
// Delete one
await client.vectors.delete("articles", "doc-1");
// Batch delete
await client.vectors.deleteBatch("articles", ["doc-1", "doc-2", "doc-3"]);Search
// KNN search
const results = await client.search.search("articles", queryVector, { k: 10 });
for (const r of results.results) {
console.log(r.external_id, r.score, r.metadata);
}
// Search with metadata filters
const results = await client.search.search("articles", queryVector, {
k: 10,
filters: { author: "Alice", year: 2024 },
});
// Search with pagination
const results = await client.search.search("articles", queryVector, {
k: 10,
offset: 20,
});
// Search by text (server-side embedding)
const results = await client.search.search("articles", undefined, {
text: "machine learning",
k: 5,
});
// Recommendations — similar to a stored vector, excludes itself
const recs = await client.search.recommend("articles", "doc-1", { k: 5 });
// Cosine similarity between two stored vectors
const score = await client.search.similarity("articles", "doc-1", "doc-2");
console.log(`Similarity: ${score.toFixed(4)}`);
// Rerank candidates against a query vector
const reranked = await client.search.rerank(
"articles",
queryVector,
["doc-1", "doc-2", "doc-3", "doc-4"]
);
for (const r of reranked) {
console.log(r.external_id, r.score);
}
// Hybrid search — vector + keyword via Reciprocal Rank Fusion
const hybrid = await client.search.hybridSearch(
"articles",
"transformer models attention",
queryVector,
{
k: 10,
alpha: 0.7, // 0 = keyword only, 1 = vector only, 0.5 = balanced
}
);
// Bulk search — multiple queries in one request
const results = await client.search.bulkSearch("articles", [
{ vector: query1, k: 5 },
{ vector: query2, k: 5, filters: { author: "Alice" } },
]);
// results[0] = hits for query1, results[1] = hits for query2RAG — Documents & Query
// Upload a document (auto-chunked and stored)
const upload = await client.documents.upload("articles", "./paper.txt");
console.log(`Created ${upload.chunks_created} chunks, doc_id=${upload.document_id}`);
// Semantic search returning text chunks
const result = await client.query.query(
"What is attention mechanism?",
"articles",
{ top_k: 5 }
);
for (const chunk of result.results) {
console.log(chunk.score, chunk.text);
}
// LLM-powered answer with source citations
const answer = await client.query.ask(
"Explain transformers in simple terms",
"articles",
{ k: 5 }
);
console.log(answer.answer);
for (const src of answer.sources) {
console.log(src.external_id, src.score);
}GraphRAG (Pro/Scale tier)
// Check graph status
const status = await client.graph.status("articles");
console.log(`Entities: ${status.entity_count}, Edges: ${status.edge_count}`);
console.log(`Pending jobs: ${status.jobs.pending}`);
// Search the knowledge graph
const graphResults = await client.graph.search("articles", "transformer architecture", {
topK: 10,
});
for (const entity of graphResults.entities) {
console.log(entity.entity, entity.entity_type, entity.score);
for (const rel of entity.relations) {
console.log(` → ${rel.relation} → ${rel.target}`);
}
}
// Find shortest path between two entities
const path = await client.graph.path("articles", "BERT", "GPT-4", { maxHops: 3 });
for (const route of path.paths) {
for (const step of route) {
console.log(`${step.source} --[${step.relation}]--> ${step.target}`);
}
}
// Louvain community detection (Scale tier)
const summary = await client.graph.summarize("articles", { resolution: 1.0 });
for (const community of summary.communities) {
console.log(`Community ${community.id}: ${community.entities.slice(0, 3).join(", ")}...`);
}
// Full GraphRAG answer (Scale tier)
const answer = await client.graph.ask("articles", "How does BERT relate to GPT?", {
topKEntities: 5,
maxHops: 2,
});
console.log(answer.answer);
console.log(`Used ${answer.entities_used.length} entities, ${answer.paths_used} paths`);
// Hybrid vector + graph answer (Scale tier)
const hybrid = await client.graph.hybridAsk(
"articles",
"What are attention mechanisms?",
{ topK: 5, alpha: 0.5 }
);
console.log(hybrid.answer);
for (const src of hybrid.sources) {
console.log(src.external_id, src.source, src.score); // source: "vector" | "graph"
}
// Update graph config
await client.graph.config("articles", { model: "gpt-4o-mini", chunk_size: 512 });Usage & Quotas
// Current usage
const usage = await client.usage.getCurrent();
console.log(`Tier: ${usage.tier}`);
console.log(`Requests: ${usage.request_count}/${usage.max_requests}`);
console.log(`Vectors: ${usage.vector_count}/${usage.max_vectors}`);
for (const warning of usage.warnings) {
console.warn(warning);
}
// Usage history
const history = await client.usage.getHistory(30); // last 30 days
// Admin: upgrade a user's tier
await client.usage.updateUserTier(42, "pro");
// Admin: trigger cleanup of expired data
await client.usage.triggerCleanup();API Keys
// Create a key
const key = await client.keys.create("my-app", "readwrite", 90); // expires in 90 days
console.log(key.key); // shown only once
// List all keys
const keys = await client.keys.list();
for (const k of keys) {
console.log(k.id, k.name, k.role, k.is_active);
}
// Get one key
const key = await client.keys.get(3);
// Update
await client.keys.update(3, { name: "renamed", role: "readonly" });
// Revoke / restore
await client.keys.revoke(3);
await client.keys.restore(3);
// Rotate (generates new key value)
const newKey = await client.keys.rotate(3);
console.log(newKey.key); // new value, shown once
// Per-key usage stats
const stats = await client.keys.getUsage(3);
console.log(stats.total_requests, stats.last_24h, stats.by_endpoint);
// Overall usage summary
const summary = await client.keys.getUsageSummary();
// Delete
await client.keys.delete(3);Observability
// Health check
const health = await client.observability.health();
console.log(health.status); // "ok"
console.log(health.total_vectors);
console.log(health.total_collections);
// Prometheus metrics (raw text)
const metrics = await client.observability.metrics();
console.log(metrics);Error Handling
import {
VectorDBError,
NotFoundError,
AlreadyExistsError,
DimensionMismatchError,
AuthenticationError,
RateLimitError,
ValidationError,
} from "vectordb-client";
try {
await client.collections.create("articles", 384);
} catch (err) {
if (err instanceof AlreadyExistsError) {
console.log("Collection already exists");
} else if (err instanceof DimensionMismatchError) {
console.log(`Wrong vector size: ${err.message}`);
} else if (err instanceof AuthenticationError) {
console.log("Invalid or expired API key");
} else if (err instanceof RateLimitError) {
console.log("Too many requests — back off and retry");
} else if (err instanceof NotFoundError) {
console.log("Collection or vector not found");
} else if (err instanceof VectorDBError) {
console.log(`API error ${err.statusCode}: ${err.message}`);
}
}Node.js < 18 (custom fetch)
import fetch from "node-fetch";
import { VectorDBClient } from "vectordb-client";
const client = new VectorDBClient({
baseUrl: "http://localhost:8000",
apiKey: "your-api-key",
fetch: fetch as unknown as typeof globalThis.fetch,
});TypeScript Types
All request and response shapes are fully typed and exported:
import type {
Collection,
SearchResult,
VectorResult,
UpsertResult,
BulkUpsertResult,
ScrollResult,
UsageInfo,
GraphStatusResponse,
GraphSearchResponse,
GraphPathResponse,
GraphSummarizeResponse,
GraphAskResponse,
HybridAskResponse,
AskResult,
ApiKey,
HealthStats,
DocumentUploadResult,
QueryResult,
} from "vectordb-client";Configuration
| Option | Type | Description |
|--------|------|-------------|
| baseUrl | string | VectorDB server URL |
| apiKey | string | API key (x-api-key header) |
| fetch | FetchFn | Custom fetch (optional, for Node < 18) |
Requirements
- Node.js 18+ (uses native
fetch) - Or any runtime with a global
fetch(Deno, Cloudflare Workers, Vercel Edge)
