API Reference#
Version: 1.0.0
Swagger Plugin#
This guide documents the HTTP endpoints exposed by the Vector Retriever microservice. The OpenAPI specification is the source of truth for request/response schemas.
Endpoints#
GET /healthGET /readyPOST /queryGET /capabilities/filters
GET /health#
Returns service liveness status.
GET /ready#
Returns service readiness. This endpoint checks backend initialization and returns 503 when dependencies are unavailable.
POST /query#
Batch query endpoint. Accepts a list of QueryRequest objects and returns per-query results plus per-query errors.
Request body#
[
{
"query_id": "q1",
"query": "red car",
"where": {
"all": [
{ "field": "tags", "op": "contains_any", "value": ["traffic"] },
{
"field": "created_at",
"op": "between",
"value": ["2026-03-01T00:00:00Z", "2026-03-22T23:59:59Z"]
},
{
"field": "video_id",
"op": "eq",
"value": "traffic_001"
}
]
},
"top_k": 20,
"explain_filters": true
}
]
Compatibility aliases remain supported for now (tags, time_filter, filters) and are normalized into where.
Image query variants#
Instead of a text query, you can supply an image object for visual similarity search.
The image field uses a discriminated union on the type property.
Image URL input:
[
{
"query_id": "img-url-1",
"image": {
"type": "image_url",
"image_url": "https://example.com/photo.jpg"
},
"top_k": 5
}
]
Base64-encoded image input:
[
{
"query_id": "img-b64-1",
"image": {
"type": "image_base64",
"image_base64": "<base64-encoded-image-data>"
},
"top_k": 5
}
]
Note:
queryandimageare mutually exclusive. Providing both in the same query block returns a422validation error. When usingimage, the responsequeryfield is set to[image_url]or[image_base64]to indicate the input modality.
Quick contract reference#
Top-level request fields:
Field |
Type |
Required |
Notes |
|---|---|---|---|
|
string |
No |
Optional per-query identifier. Defaults to the |
|
string |
Conditional |
User search text. Required unless |
|
object |
Conditional |
Image input for visual similarity search. Required unless |
|
integer |
No |
Result count cap for this query. |
|
object |
No |
Primary filter grammar object. |
|
boolean |
No |
When true, response includes backend filter payload and rewrite details. |
|
string[] |
No |
Legacy alias; normalized to |
|
object |
No |
Legacy alias; normalized to |
|
map |
No |
Legacy alias map; normalized to equivalent |
Safety limits:
Limit |
Value |
Why it exists |
|---|---|---|
|
5 |
Prevents deeply nested trees that are expensive and hard to debug. |
|
50 |
Prevents oversized expressions from consuming excessive compute. |
|
100 |
Prevents very large list scans for |
Supported filter operators#
eqincontainsstarts_withgtgteltltebetweencontains_anycontains_allexistsmissing
Dynamic-field safety rules#
Field name regex:
^[A-Za-z0-9_/\\-]{1,128}$Max dynamic filter fields:
20Max
wheredepth:5Max
whereclauses:50Max list size for list operators:
100Unknown fields are allowed if they satisfy validation rules
Response body#
{
"request_id": "uuid",
"results": [
{
"query_id": "q1",
"query": "red car",
"count": 1,
"items": [
{
"score": 0.91,
"metadata": {
"video_id": "traffic_001"
},
"page_content": "..."
}
],
"applied_filters": {
"normalized_where": {
"all": [
{ "field": "tags", "op": "contains_any", "value": ["traffic"] },
{
"field": "created_at",
"op": "between",
"value": ["2026-03-01T00:00:00Z", "2026-03-22T23:59:59Z"]
}
]
},
"warnings": [
"tags -> where(field='tags', op='contains_any', value=<tags>)"
],
"compiled_backend_filter": {
"tags": ["==", "traffic"]
},
"dropped_or_rewritten_clauses": [
"tags -> where(field='tags', op='contains_any', value=<tags>)"
]
}
}
],
"errors": []
}
compiled_backend_filter and dropped_or_rewritten_clauses are only returned when
explain_filters=true. Either field can still be null or empty when nothing was pushed down
or rewritten for that query.
Explain behavior summary:
Response field |
Populated when |
Meaning |
|---|---|---|
|
Always when any filter input is present |
Final interpreted |
|
When normalization or pushdown notes exist |
Human-readable notes about alias rewrites and pushdown limits. |
|
|
Backend-native filter payload sent to vector store. |
|
|
Clauses rewritten from aliases or evaluated only in fallback path. |
Pushdown, fallback, and over-fetch behavior#
The service executes filtering in two stages:
Build backend pushdown filter from a safe subset of predicates.
Apply
whereagain in the service fallback path against returned metadata.
This fallback stage is always the final source of truth for result inclusion.
When fallback risk is high (for example no backend filter was compiled, or warnings indicate
partial pushdown), the service over-fetches candidates before fallback evaluation. In practice,
fetch_k is increased beyond top_k (capped by MAX_TOP_K) to reduce false negatives.
Implications for explain_filters=true:
compiled_backend_filtercan still benullwhen no backend-native filter is produced.dropped_or_rewritten_clausescan be empty when no alias rewrite occurred and no clause was explicitly marked as dropped.pushdown_operatorsin capabilities indicate backend support class, but actual pushdown can still vary by field/operator combination and backend translator behavior.
GET /capabilities/filters#
Returns filter grammar capabilities and limits for each backend.
Optional query parameter:
backend: scope to one backend (for examplebackend=milvus)
Capabilities response example#
{
"active_backend": "vdms",
"backends": [
{
"backend": "vdms",
"top_level_fields": ["query", "image", "top_k", "where"],
"logical_blocks": ["all", "any", "not"],
"supported_operators": [
"eq",
"in",
"contains",
"starts_with",
"gt",
"gte",
"lt",
"lte",
"between",
"contains_any",
"contains_all",
"exists",
"missing"
],
"pushdown_operators": ["gte"],
"known_fields": {
"tags": "array<string>",
"created_at": "datetime"
},
"max_where_depth": 5,
"max_where_clauses": 50,
"max_where_list_size": 100
}
]
}
Backend filter semantics#
The API surface is uniform, but translation is backend-specific:
vdms: translated to list-style VDMS filtersmilvus: translated to expression string (expr)pgvector: translated to document-style filter operatorsfaiss: translated to dict-based metadata filters