Skip to main content

VectorDB quickstart

In about five minutes you will create a vector index, insert two points, run a similarity search, browse what is stored, and clean up.

Before you begin

  • You have a platform account and can sign in. If not, ask your administrator for an account or an invitation link — see Create an account.

  • You have installed the platformctl CLI and run platformctl login.

  • For the curl tabs, you need your project ID. It is a UUID — a 36-character random identifier such as 7f3c1e02-9b5d-4a11-8c6f-2d0e5a91b4cc. Read it out of the console URL (#/projects/<uuid>/...), or run platformctl projects list.

    export VDB="https://api.codyhill.dev" # VectorDB is served on the shared public API
    export CAI_PROJECT="00000000-0000-0000-0000-000000000000" # your project UUID
    export CAI_TOKEN="<your session token or API key>"

    The platformctl tabs need none of this.

The CLI takes JSON from anywhere

vectordb upsert and query take their JSON through --points and --vector. Each of those flags accepts a literal string, @file to read a file, or - to read standard input. So any body written for the curl tabs pipes straight in.

Step 1: Create an index

Only the name is required. This example uses 4 dimensions so the demo vectors are short enough to type by hand. Real embedding models produce hundreds or thousands of numbers per vector, which is what you get if you leave dimensions out — the width of the platform's own hosted model.

platformctl vectordb create docs --dimensions 4 --distance cosine

The API answers before the index is usable. state starts at pending, then moves to ready once the platform has finished building the storage behind it.

Distance accepts cosine, dot, or euclid, and the usual aliases (dot_product, l2) are understood. dimensions and distance cannot be changed later — only replicas and payload_on_disk are mutable.

If you embed with the platform's own model, dimensions is 4096 — not the default

This walkthrough uses 4 dimensions so the vectors are short enough to type. For real work, omit dimensions entirely: you get the width of the platform's hosted model, qwen-embedding, which is what POST /v1/embeddings returns. Set a width explicitly only when your vectors come from somewhere else.

Take the default while embedding with qwen-embedding and every upsert fails:

{"error":"point 0 has 4096 dimensions; index \"my-corpus\" expects 4","request_id":"..."}

Since dimensions is fixed at creation, recovery means deleting the index and loading the whole corpus again. Set it up front:

platformctl vectordb create my-corpus --dimensions 4096 --distance cosine

Measure any model's width rather than trusting a number — platformctl inference embed "hello" prints a DIMENSIONS column. See Inference.

Step 2: Wait for it to be ready

platformctl vectordb get docs

Repeat until READY reads yes.

If you write points before that, the API answers with a clear 409:

{"error":"index is not ready yet; its collection has not been created","request_id":"..."}

Step 3: Insert points

A point is a vector plus an optional JSON payload and an optional id. An id must be either an unsigned integer — a whole number, zero or greater — or a UUID string. Leave the id out and the platform generates a UUID for you.

platformctl vectordb upsert docs --points '{"points":[
{"id":1,"vector":[0.1,0.2,0.3,0.4],"payload":{"tag":"alpha"}},
{"vector":[0.9,0.8,0.7,0.6],"payload":{"tag":"beta"}}]}'

What failure looks like

Every vector must match the index's width exactly. Send a 3-number vector into this 4-dimension index and the whole batch is rejected. Nothing is partially written:

{"error":"point 0 has 3 dimensions; index \"docs\" expects 4","request_id":"..."}

This is the most common first-run error with real embeddings too, and the usual cause is an index whose width does not match the model that produced the vectors. Fix it by creating a new index with the right dimensions — or by omitting dimensions, which sizes the index for the platform's own model. You cannot change that value later.

Query with a vector, ask for the top 5 nearest, and filter to points whose payload has tag = alpha.

platformctl vectordb query docs \
--vector '[0.1,0.2,0.3,0.4]' --top-k 5 \
--filter '{"must":[{"key":"tag","match":{"value":"alpha"}}]}'

You should see:

ID SCORE PAYLOAD
1 1.0000 {"tag":"alpha"}

The query vector is identical to point 1's vector, so with cosine distance its score is a perfect 1.0. Point 2 exists but is filtered out by the payload filter.

Step 5: Browse what is stored

Scroll lists points in id order and needs no query vector. Use it to eyeball what is actually there.

platformctl vectordb scroll docs --limit 50

And confirm the index itself:

platformctl vectordb list

You should see:

NAME DIMENSIONS DISTANCE STATE READY POINTS
docs 4 cosine ready yes 2
points_count is a periodic sweep, not a live counter

The points_count on an index — the POINTS column above — is refreshed on a schedule rather than updated on every write. Immediately after an upsert it can still read the old number. scroll reads the points themselves and is always current.

Clean up

Deleting an index destroys the index and every vector in it. There is no undo and no snapshot. Index deletion requires the project admin role.

platformctl vectordb delete docs

To remove points without dropping the index, use :delete-points with either ids or a filter.

Next steps

  • Indexes and points — dimensions, distance metrics, ids, payloads, and what's immutable.
  • Search — filters, scores, thresholds, and browsing in depth.
  • Use with agents — give a deployed agent long-term memory.
  • API reference — the complete endpoint list.