Query
Top-K vector similarity search. Served from a hot FAISS cache when the shard is loaded, or queued onto an ephemeral runner on a cold dataset. The contract is identical either way.
POST /v1/query
Run a search
Pass the dataset name, a query vector whose length equals the dataset's dimension, and an optional top_k. The dataset must be status: indexed before results come back.
curl -s -X POST http://localhost:8080/v1/query \
-H "Authorization: Bearer $RB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataset": "products",
"vector": [0.12, -0.04, 0.88, 0.31, -0.57, 0.09],
"top_k": 3
}'Response (HTTP 200):
{
"matches": [
{ "id": "doc-42", "score": 0.013, "metadata": { "title": "Atlas of birds" } },
{ "id": "doc-7", "score": 0.046, "metadata": { "title": "Field guide" } },
{ "id": "doc-3", "score": 0.118, "metadata": { "title": "Migration patterns" } }
],
"latency_ms": 23,
"mode": "hot"
}Understanding the response
matches— results ranked nearest-first. The first entry is the closest vector to your query.id— the original id you supplied at upload time, so you can join back to your own records.score— a distance: lower means closer, somatches[0]always has the smallest score.metadata— exactly the object you attached to that record (ornullif you attached none).latency_ms— server-side search time for this request, in milliseconds.mode— how the query was served:hotfrom the in-memory FAISS cache,coldwhen a shard was freshly loaded, orephemeralwhen enqueued for on-demand compute.
Metadata filtering
Pass an optional filter object to restrict matches to records whose metadata satisfies it. The filter is a flat object of field → value pairs with AND-of-equals semantics: a record is included only if, for every key in filter, its metadata contains that key with an exactly-equal value.
curl -s -X POST http://localhost:8080/v1/query \
-H "Authorization: Bearer $RB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataset": "products",
"vector": [0.12, -0.04, 0.88, 0.31, -0.57, 0.09],
"top_k": 10,
"filter": { "category": "books", "year": 2024 }
}'- Exact value and exact type. Comparison is strict and never coerced — string compares to string, number to number. The filter value
"2024"(string) does not match metadata2024(number). - A missing key excludes the record. If a record's
metadatalacks a filtered key, it is dropped. - A
nullfilter value never matches.{ "filter": { "category": null } }is accepted by validation but matches nothing —nullis not a meaningful equality target in v1. The query still succeeds with HTTP 200 (typically"matches": []). - Scalars only. v1 supports no ranges, no
OR, and no nesting. A nested object or array as a filter value is rejected with400 invalid_request. - Omit
filter, or sendnullor{}, to apply no filtering and scan the whole dataset.
Partial results are expected. Filtering happens after the nearest-neighbour search (FAISS cannot filter by metadata): the service over-fetches a candidate set, applies the predicate, then truncates to top_k. A selective filter can legitimately return fewer than top_k matches — that is not an error. A filter matching nothing returns "matches": [] with HTTP 200.
Ephemeral results
When a shard isn't resident, the query is enqueued rather than served inline. If mode is ephemeral, the immediate response carries an empty matches array and a job_id:
{
"matches": [],
"latency_ms": 12,
"mode": "ephemeral",
"job_id": "job_01H..."
}Poll until the job is ready:
curl -s http://localhost:8080/v1/query/status/job_01H... \ -H "Authorization: Bearer $RB_API_KEY"
Response (HTTP 200) while still computing:
{ "ready": false }Response (HTTP 200) once done:
{
"ready": true,
"matches": [
{ "id": "doc-42", "score": 0.013, "metadata": { "title": "Atlas of birds" } }
],
"latency_ms": 142,
"mode": "ephemeral"
}Re-issue the status request until ready: true, then read matches from the same response.
Parameters
dataset— required. The name of one of your datasets.vector— required. An array of floats; its length must equal the dataset'sdimension.top_k— optional. Number of matches to return. Defaults to10, maximum1000.filter— optional. A flat object of metadata field → value pairs with AND-of-equals semantics — see Metadata filtering for the full rules.
Errors
All failures use the standard error envelope (see Authentication).
dimension_mismatch— the query vector's length doesn't match the dataset dimension (HTTP 400)dataset_not_found— the dataset doesn't exist or isn't owned by you (HTTP 404)top_k_out_of_range—top_kis below 1 or above 1000 (HTTP 400)invalid_request— the request body is malformed, e.g. afiltervalue that is a nested object or array (HTTP 400)query_quota_exceeded— the daily query cap is reached; Rate limits & quotas (HTTP 429)
Before you query
A dataset must reach status: indexed before a query returns results — until then there is no queryable shard. Upload your vectors, then poll the dataset through its status lifecycle until it is indexed.