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.

Terminal
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.

TypeScript
import { SwarmV } from "@swarmv/sdk";

// On your backend: uses the API key in process.env.SWARMV_API_KEY
const memory = new SwarmV();
Python
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.

TypeScript
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.

Python
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.

TypeScript
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 });
Python
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.

TypeScript
// 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 });
Python
# Same for the Python client (sync and async). Default max_retries=6.
memory = SwarmV(max_retries=10)

Errors

StatusMeaningWhat to do
400Invalid request: wrong vector dimension, nested or oversized metadata, a filter value over 128 bytesFix the request
401 / 403Missing, expired or revoked credentials; missing scope; no edit permission on the containerCheck the key or token and its permissions
413 index_fullThe 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_limitNo active plan, or the Basic plan's monthly reads or writes are used upChoose or upgrade a plan in the dashboard (not retried)
429Too many requests per minuteRetry later (SDKs do)
503Write backlog full, or a temporary failureRetry 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.

claude_desktop_config.json
{
  "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.