Getting Started
Welcome to the SwarmV documentation. Get up and running with our serverless vector database in minutes.
Installation
SwarmV provides native SDKs for both TypeScript and Python. They handle connection reuse, authentication, token refresh and batching for you.
npm install @swarmv/sdk # or for Python pip install swarmv
Two kinds of credentials
- API keys (
evx_live_…) belong on your backend. Create them in the dashboard under API Keys, each with only the permissions it needs. - User tokens are short-lived (at most one hour) and act as a single user. Your backend creates them with an API key and hands them to agents, MCP servers and client apps. Never give an agent an API key.
The Authentication guide covers permissions, user tokens, access control, rotation and revocation.
Basic Initialization
On your backend, set SWARMV_API_KEY in the environment and the SDK picks it up automatically.
import { SwarmV } from "@swarmv/sdk";
// On your backend: uses the API key in process.env.SWARMV_API_KEY
const memory = new SwarmV();from swarmv import SwarmV # On your backend: uses the API key in the SWARMV_API_KEY environment variable memory = SwarmV()
High-Performance Ingestion
💡 Best Practice: Batching
Use insertMany / insert_many for bulk uploads instead of a loop of single requests. Document IDs must be numeric strings (unsigned 32-bit integers), and a document can't later be moved to a different container.
const vectors = [
// ids are numeric strings (unsigned 32-bit integers);
// container_id decides who can see the vector (see Authentication)
{ id: "1001", vector: [0.1, 0.2 /* ... */], metadata: { container_id: "container:handbook", type: "doc" } },
// ... up to 500 vectors per batch
];
// GOOD: send one explicit batch. A batch is all-or-nothing: if any record is
// rejected, none of that batch is written and the error says which one.
await memory.insertMany(vectors);
// ALSO GOOD: insert() buffers and sends batches of 500 automatically.
for (const v of vectors) await memory.insert(v);
await memory.flush(); // send the rest before your script exits🛡️ Python SDK: numpy support
The Python SDK accepts numpy.ndarray vectors directly, without casting. NaN or infinite values are rejected before anything is sent.
import numpy as np
from swarmv import SwarmV
memory = SwarmV()
# numpy arrays work as vectors directly
memory.insert_many([
{"id": "1002", "vector": np.random.rand(768), "metadata": {"container_id": "container:handbook"}},
])Search
Search returns the closest records with their distance and the metadata you stored with them, so you can keep a chunk of text or a source reference right next to its vector. Metadata is flat (string, number or boolean values), up to 8 KB per record, and filter matches values exactly. Filters work on values up to 128 bytes (ids, tags, categories); longer values such as document text are still stored and returned, but can't be filtered on.
New writes reach the search index at every edge location in the background, usually within a minute. A search with fresh: true also includes writes that haven't arrived yet, so an agent can read what it (or another agent) just wrote. It adds a little latency, so use it where read-after-write matters; the MCP servers always use it.
const hits = await memory.search(queryVector, { topK: 5, filter: { type: "doc" } });
// [{ id: "1001", distance: 0.12, metadata: { container_id: "container:handbook", type: "doc" } }, ...]
// distance: lower is closer. Metadata values come back as strings.
// Pass includeMetadata: false for smaller responses when you only need ids.
// Read your own writes: include writes from the last few seconds
const latest = await memory.search(queryVector, { topK: 5, fresh: true });hits = memory.search(query_vector, top_k=5, filter={"type": "doc"})
for h in hits:
print(h.id, h.distance, h.metadata) # metadata values are strings
# include_metadata=False for smaller responses when you only need ids
# Read your own writes: include writes from the last few seconds
latest = memory.search(query_vector, top_k=5, fresh=True)Scale, limits and errors
Index size and sharding
An index holds up to 1,000,000 vectors, and you don't need to do anything as it grows. Up to 100,000 vectors it is searched at the Cloudflare location nearest the caller. Past that, new documents go into additional shards of up to 100,000 vectors each, and a search queries every shard in parallel in a Cloudflare region and merges the results. Updates and deletes go to the shard that holds the document, so document IDs, containers and filters work exactly the same. A sharded search adds the round trip to that region, which depends on how far the caller is from it (about 120 ms in our tests from South America to the North American region). Need more than 1,000,000 vectors in one index? Contact us.
Search quality
Vectors are stored compressed so large indexes fit at the edge, and every search re-checks its best candidates against a more precise copy, so results are close to an exact search (about 0.97–0.99 of the true top 10 in our tests). nprobe (default 16, max 64) sets how much of the index each search scans; raising it rarely helps and costs latency.
Write throughput and backpressure
Writes are accepted immediately and become searchable in the background. One index absorbs about 350 vectors per second sustained, and bursts of up to 20,000 pending writes. Past that, writes are refused with 503 and a Retry-After header until the backlog drains. The SDKs retry these automatically, so a bulk load simply slows down instead of failing; if you call the HTTP API directly, wait as Retry-After asks and resend.
// Retries temporary failures (429, 5xx, network errors), waiting as long as
// the server's Retry-After asks. Default 6 retries (about 30 s at most).
const memory = new SwarmV({ maxRetries: 10 });# Same for the Python client (sync and async). Default max_retries=6. memory = SwarmV(max_retries=10)
Errors
| Status | Meaning | What to do |
|---|---|---|
| 400 | Invalid request: wrong vector dimension, nested or oversized metadata, a filter value over 128 bytes | Fix the request |
| 401 / 403 | Missing, expired or revoked credentials; missing scope; no edit permission on the container | Check the key or token and its permissions |
413 index_full | The index is at its size limit (updates of existing documents still work) | Delete documents you no longer need, or contact us for a larger limit |
402 plan_required / plan_limit | No active plan, or the Basic plan's monthly reads or writes are used up | Choose or upgrade a plan in the dashboard (not retried) |
| 429 | Too many requests per minute | Retry later (SDKs do) |
| 503 | Write backlog full, or a temporary failure | Retry after Retry-After (SDKs do) |
MCP Servers (Claude & Cursor)
SwarmV provides official Model Context Protocol (MCP) servers for Node.js and Python, so agents like Claude Desktop or Cursor can read and write your memory. Each MCP server acts as one user, with that user's permissions, using a short-lived token from your backend.
{
"mcpServers": {
"swarmv": {
"command": "npx",
"args": ["-y", "@swarmv/mcp-server"],
"env": {
"SWARMV_TOKEN_URL": "https://your-backend.example.com/swarmv-token",
"SWARMV_TOKEN_URL_AUTH": "<the signed-in user's session credential>"
}
}
}
}See MCP & AI Agents for the Python server, the token endpoint and local development.