Relaystation logo Relaystation

Vector search & RAG

One retrieval story, three moving parts: a vector baton (a prepaid, durable index with a frozen shape), a query op (top-k similarity search — pass a raw text query and it’s embedded for you), and rag/answer (embed the question, retrieve the top-k chunks, and answer from only those chunks with source ids). You can use the pieces separately or let rag/answer run the whole loop under one charge.

1. Create a vector baton

A vector baton is a normal prepaid baton with the vector preset and a frozen index shape — its dims and distance metric are set at create and can’t change afterward.

curl -X POST https://api.relaystation.ai/v1/baton \
  -H 'Authorization: Bearer rs_live_<key>' \
  -H 'Idempotency-Key: mk-vector-20260707' \
  -H 'Content-Type: application/json' \
  -d '{ "preset": "vector", "tier": "standard",
        "vector": { "dims": 1024, "metric": "cosine" },
        "name": "docs-index" }'
  • vector.dims must be one of the allowlisted sizes (256 / 512 / 1024 — the embed model’s output sizes). Defaults to 1024.
  • vector.metric is cosine (default) or euclidean.
  • Storage is prepaid at create — it’s a baton, so its capacity, lifetime, and egress are baton economics (see Baton pricing). Pick a tier (or a customShape) that fits your index.

The response carries the baton id you use for the vector routes below.

2. Write vectors

POST /v1/baton/{id}/vectors batch-writes vectors into the index. Each item is { id, vector, metadata? }; a batch is 1–1000 items, each vector must match the baton’s frozen dims.

curl -X POST https://api.relaystation.ai/v1/baton/<id>/vectors \
  -H 'Authorization: Bearer rs_live_<key>' \
  -H 'Idempotency-Key: put-batch-20260707' \
  -H 'Content-Type: application/json' \
  -d '{ "vectors": [
        { "id": "chunk-1", "vector": [0.01, -0.02, ...], "metadata": { "text": "…", "source": "doc-A" } },
        { "id": "chunk-2", "vector": [0.03,  0.04, ...], "metadata": { "text": "…", "source": "doc-B" } }
      ] }'

Returns { batonId, written, bytesCharged, dims }. Writes draw the baton’s prepaid size quota (that storage was already paid for at create); the write op itself is metered per batch. Store the chunk text in metadata so retrieval — and rag/answer — can read it back.

3. Query top-k

POST /v1/baton/{id}/vectors/query runs a top-k similarity search. Pass a vector you embedded yourself, or pass raw text and it’s embedded for you before the search.

curl -X POST https://api.relaystation.ai/v1/baton/<id>/vectors/query \
  -H 'Authorization: Bearer rs_live_<key>' \
  -H 'Idempotency-Key: query-20260707' \
  -H 'Content-Type: application/json' \
  -d '{ "text": "how do refunds work?", "topK": 5 }'

Returns { batonId, matches: [...], embedded? } — the nearest neighbors (with their ids, scores, and metadata), and an embedded marker when the query text was vectorized for you. The query is a flat per-call charge; when you pass text, the embedding units to vectorize it are added. Response bytes draw the baton’s egress budget, exactly like a content read.

4. Answer, grounded

POST /v1/rag/answer runs the full retrieval-augmented loop in one call: it embeds the question, queries the vector baton’s index top-k, and answers from only the retrieved chunks — returning the answer together with the source ids it grounded on.

FieldTypeNotes
batonIdstring, requiredthe vector baton to retrieve from
questionstring, requiredthe question (1–65536 chars)
topKintegerhow many chunks to retrieve (1–1000)
tierenumbudget | value | best — the answer model’s spend ceiling
curl -X POST https://api.relaystation.ai/v1/rag/answer \
  -H 'Authorization: Bearer rs_live_<key>' \
  -H 'Idempotency-Key: rag-20260707' \
  -H 'Content-Type: application/json' \
  -d '{ "batonId": "<id>", "question": "What is the refund window?", "topK": 5, "tier": "value" }'

Returns { answer, sources, usage } — the grounded answer, the sources (the chunk ids it used), and a usage object whose chargedMicros is never above the authorized ceilingMicros. The retrieved chunks are fed to the model as untrusted data — the instruction to answer only from them is ours, not the chunks’.

Billing

  • Storage (the vector baton) — prepaid at create; baton economics (capacity / lifetime / egress). See Baton pricing.
  • Writes (vectors) — metered per batch, and draw the baton’s prepaid size quota.
  • Query (vectors/query) — a flat per-query charge, plus embedding units when you pass raw text; response bytes draw egress.
  • rag/answersettle-at-actual (cost-plus): you authorize a ceiling (embedding + retrieval + the answer model’s tier ceiling) and pay the actual, itemized on the receipt, never above the ceiling.

No hard prices here — see Pricing for the current rates, or send an unauthenticated POST to read the exact price from the 402 challenge. Every billable call needs an Idempotency-Key; a same-key retry returns the cached result without re-charging.

MCP tools

Callable over MCP at https://api.relaystation.ai/mcp: vector_put and vector_query (under the baton family), and rag_answer. Same auth, same pricing as the HTTP routes.

Next

Embeddings · Batons · LLM tasks · Quickstart · x402 wire format · API reference