Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

gRPC API Reference

All services are defined under the laurus.v1 protobuf package.

Services Overview

ServiceRPCsDescription
HealthServiceCheckHealth checking
IndexServiceCreateIndex, GetIndex, GetSchema, AddField, DeleteFieldIndex lifecycle and schema
DocumentServicePutDocument, AddDocument, PutDocuments, AddDocuments, GetDocuments, DeleteDocuments, Commit, FlushWalDocument CRUD, bulk ingestion, commit, and WAL flush
SearchServiceSearch, SearchStreamUnary and streaming search

HealthService

Check

Returns the current serving status of the server.

rpc Check(HealthCheckRequest) returns (HealthCheckResponse);

Response fields:

FieldTypeDescription
statusServingStatusSERVING_STATUS_SERVING when the server is ready

IndexService

CreateIndex

Create a new index with the given schema. Fails with ALREADY_EXISTS if an index is already open.

rpc CreateIndex(CreateIndexRequest) returns (CreateIndexResponse);

Request fields:

FieldTypeRequiredDescription
schemaSchemaYesIndex schema definition

Schema structure:

message Schema {
  map<string, FieldOption> fields = 1;
  repeated string default_fields = 2;
  map<string, AnalyzerDefinition> analyzers = 3;
  map<string, EmbedderConfig> embedders = 4;
  DynamicFieldPolicy dynamic_field_policy = 5;
}

enum DynamicFieldPolicy {
  DYNAMIC_FIELD_POLICY_UNSPECIFIED = 0;
  DYNAMIC_FIELD_POLICY_STRICT = 1;
  DYNAMIC_FIELD_POLICY_DYNAMIC = 2;
  DYNAMIC_FIELD_POLICY_IGNORE = 3;
}
  • fields — Field definitions keyed by field name.
  • default_fields — Field names used as default search targets when a query does not specify a field.
  • analyzers — Custom analyzer pipelines keyed by name. Referenced by TextOption.analyzer.
  • embedders — Embedder configurations keyed by name. Referenced by vector field options (HnswOption.embedder, etc.).
  • dynamic_field_policy — How the engine treats fields that appear in an ingested document but are absent from fields. UNSPECIFIED is interpreted as DYNAMIC for forward compatibility. See Schema & Fields for the full behaviour matrix and the warning about silent truncation under DYNAMIC.

AnalyzerDefinition:

message AnalyzerDefinition {
  repeated ComponentConfig char_filters = 1;
  ComponentConfig tokenizer = 2;
  repeated ComponentConfig token_filters = 3;
}

ComponentConfig (used for char filters, tokenizer, and token filters):

FieldTypeDescription
typestringComponent type name (e.g. "whitespace", "lowercase", "unicode_normalization")
paramsmap<string, string>Type-specific parameters as string key-value pairs

EmbedderConfig:

FieldTypeDescription
typestringEmbedder type name (e.g. "precomputed", "candle_bert", "candle_colbert", "openai")
paramsmap<string, string>Type-specific parameters (e.g. "model" → "sentence-transformers/all-MiniLM-L6-v2"). "candle_colbert" (Issue #1349) also takes the optional "revision", "query_maxlen" and "doc_maxlen"; the lengths are decimal strings such as "32", and anything else is rejected

Each FieldOption is a oneof with one of the following field types:

Lexical FieldsVector Fields
TextOption (indexed, stored, multi_valued, position_increment_gap, term_vectors, doc_values, analyzer)HnswOption (dimension, distance, m, ef_construction, base_weight, quantizer, embedder, rerank_storage, pq_codebook_path)
IntegerOption (indexed, stored, multi_valued, doc_values)FlatOption (dimension, distance, base_weight, quantizer, embedder, rerank_storage)
FloatOption (indexed, stored, multi_valued, doc_values)IvfOption (dimension, distance, n_clusters, n_probe, base_weight, quantizer, embedder, rerank_storage)
BooleanOption (indexed, stored, multi_valued, doc_values)MultiVectorOption (dimension, distance, embedder, storage)
DateTimeOption (indexed, stored, multi_valued, doc_values)
GeoOption (indexed, stored, multi_valued, doc_values)
Geo3dOption (indexed, stored, multi_valued, doc_values)
BytesOption (stored, multi_valued)

The embedder field in vector options specifies the name of an embedder defined in Schema.embedders. When set, the server automatically generates vectors from document text fields at index time. Leave empty to supply pre-computed vectors directly.

Doc values: doc_values (Issue #1047) is optional bool on every lexical option above except BytesOption, following the same tri-state contract as term_vectors: a client that omits it gets the engine’s default (true), distinguishable from an explicit false. It controls whether the field’s value is also copied into DocValues, the column-oriented store sorting and faceting/aggregation read from — a DocValues column is written only when stored and doc_values are both true. BytesOption carries no such field: a Bytes value is never written to DocValues regardless. Turning doc_values off for a field that is never sorted or faceted on shrinks its segment footprint; the field remains fully searchable and retrievable either way.

Multi-valued geo, datetime, boolean, text and bytes: multi_valued on GeoOption / Geo3dOption (Issue #1174), on DateTimeOption (Issue #1184) and on BooleanOption (Issue #1180) is proto field number 4 — 3 is already taken by doc_values there, unlike IntegerOption / FloatOption; on TextOption (Issue #1175) it is field number 6, because Text already used 3–5 for term_vectors, analyzer and doc_values; on BytesOption (Issue #1176) it is field number 2 — 1 is already taken by stored, and BytesOption has neither an indexed nor a doc_values field. When true, a geo field accepts GeoArrayValue / Geo3dArrayValue (see the Value table below) and distance / bounding-box queries (plus geo3d_nearest) match a document if any of its points satisfies the predicate, scoring it by its closest point. A datetime field accepts DatetimeArrayValue (repeated int64 Unix microseconds UTC, the same encoding as datetime_value) and range queries match a document if any of its instants is in range, with constant scoring; a document is reported once even when several instants match. A boolean field accepts BoolArrayValue (repeated bool) and a term query matches a document if any element equals the queried value; each element is indexed as its own true / false term posting — there are no BKD points for booleans — so repeated elements raise the term frequency (and hence the BM25 score), not the hit count. A text field accepts TextArrayValue (repeated string) and a term query matches a document if any element contains the term; position_increment_gap (field 7, optional uint32) is the number of positions inserted between consecutive elements, which keeps a phrase query from spanning two elements unless its slop reaches the gap. It is optional for the same reason term_vectors / doc_values are: an omitted value means the engine default (100), not 0. A bytes field accepts BytesArrayValue (repeated bytes); since a Bytes value is never lexically indexed, this has no “any match” query semantics at all — it only governs the stored/wire shape and ingestion arity — and, like the scalar bytes_value, the per-element MIME type carried by DataValue::BytesArray is not represented on the wire.

Multi-vector fields: MultiVectorOption (FieldOption field 12, Issue #1177) declares a field that holds each document’s token vectors (for example ColBERT-style per-token embeddings) for late-interaction rescoring. It has no ANN index and is not a vector-search target: a query_vectors entry naming it is rejected. distance must be COSINE (vectors are L2-normalized when written) or DOT_PRODUCT. Values are VectorArrayValues (see the Value table below), and the field is not stored, so documents returned by the server never include it. embedder (field 3, Issue #1349) names a token-level embedder ("candle_colbert") from Schema.embedders; when set, a document may give the field a text_value, which is embedded into token vectors. A MultiVector field accepts only a "candle_colbert" or "precomputed" embedder, and other vector fields do not accept "candle_colbert".

Multi-vector storage: the optional storage field (field 4, enum MultiVectorStorage, Issue #1346) picks the on-disk element kind of every token vector: UNSPECIFIED = same as F32, F32 (default, 4 bytes/element, exact), F16 (2 bytes/element, ~2⁻¹¹ relative error per element), or INT8 (~1 byte/element plus a small per-vector scale overhead — dimension + 2 bytes/row total — using a per-vector scale max(abs(vector)) / 127, not trained per-segment or over the corpus). At 300 tokens × 128 dimensions (~150 KB/document in F32), F16 is ~75 KB/document and INT8 is ~38 KB/document. Unset keeps F32.

Distance metrics: COSINE, EUCLIDEAN, MANHATTAN, DOT_PRODUCT, ANGULAR

Quantization methods: SCALAR_8BIT (default), PRODUCT_QUANTIZATION (Issue #481 Stage 3; supported by the HNSW index — Flat / IVF reject it at write time).

NONE (no quantization) was removed in Issue #481 Stage 1. The proto enum value 0 (QUANTIZATION_METHOD_NONE) is kept as a wire-compat reservation; if the server receives it, it falls back to SCALAR_8BIT via Default::default().

Rerank storage: the optional rerank_storage field (enum RerankStorageKind: UNSPECIFIED = no sidecar, F32) enables the Stage-2 rerank sidecar (Issue #481 / #793). When set to F32 on an HNSW field, commit writes an extra full-precision .hnsw.f32 sidecar so searches that set rerank_factor rescore int8 candidates against the original vectors. Omitting the field (or UNSPECIFIED) keeps Stage-1 int8-only ranking. Since #932 the sidecar is emitted and consumed by all three vector index types (HNSW / Flat / IVF); on Flat/IVF the rescoring applies to field-routed queries.

Shared PQ codebook: the optional pq_codebook_path field on HnswOption (Issue #631) names a storage-relative shared PQ codebook file, trained once via the laurus train pq-codebook CLI command. Segments are then encoded against the pre-trained codebook instead of re-training k-means on every commit and merge. Only meaningful with a PRODUCT_QUANTIZATION quantizer; when set but not yet trained, commits fail with an error naming the training command (no silent fallback to per-segment training). Unset keeps per-segment training.

Base weight: base_weight on HnswOption/FlatOption/IvfOption is optional float (Issue #1084): a client that omits it gets the engine’s default (1.0), distinguishable from an explicit 0.0. It sets the field’s relative scoring priority when a query targets it alongside other vector fields — see Vector Search → Weights for what it does and does not affect.

QuantizationConfig structure:

FieldTypeDescription
methodQuantizationMethodQuantization method (QUANTIZATION_METHOD_SCALAR_8BIT or QUANTIZATION_METHOD_PRODUCT_QUANTIZATION). The reserved value 0 (NONE) is silently coerced to SCALAR_8BIT.
subvector_countuint32Number of subvectors (only used when method is PRODUCT_QUANTIZATION; must evenly divide dimension)

Example:

{
  "schema": {
    "fields": {
      "title": {"text": {"indexed": true, "stored": true, "term_vectors": true}},
      "embedding": {"hnsw": {"dimension": 384, "distance": "DISTANCE_METRIC_COSINE", "m": 16, "ef_construction": 200}}
    },
    "default_fields": ["title"]
  }
}

GetIndex

Get index statistics.

rpc GetIndex(GetIndexRequest) returns (GetIndexResponse);

Response fields:

FieldTypeDescription
document_countuint64Total number of documents in the index
vector_fieldsmap<string, VectorFieldStats>Per-field vector statistics

Each VectorFieldStats contains vector_count and dimension.

AddField

Add a new field to the running index at runtime.

rpc AddField(AddFieldRequest) returns (AddFieldResponse);

Request fields:

FieldTypeDescription
namestringThe field name
field_optionFieldOptionThe field configuration

Response fields:

FieldTypeDescription
schemaSchemaThe updated schema after the field has been added

HTTP gateway: POST /v1/schema/fields

DeleteField

Remove a field from the running index schema.

rpc DeleteField(DeleteFieldRequest) returns (DeleteFieldResponse);

Request fields:

FieldTypeDescription
namestringThe field name to remove

Response fields:

FieldTypeDescription
schemaSchemaThe updated schema after removal

Existing indexed data for the field remains in storage but becomes inaccessible. Per-field analyzers and embedders are unregistered.

HTTP gateway: DELETE /v1/schema/fields/{name}

GetSchema

Retrieve the current index schema.

rpc GetSchema(GetSchemaRequest) returns (GetSchemaResponse);

Response fields:

FieldTypeDescription
schemaSchemaThe index schema

DocumentService

PutDocument

Insert or replace a document by ID. If a document with the same ID already exists, it is replaced.

rpc PutDocument(PutDocumentRequest) returns (PutDocumentResponse);

Request fields:

FieldTypeRequiredDescription
idstringYesExternal document ID
documentDocumentYesDocument content

Document structure:

message Document {
  map<string, Value> fields = 1;
}

Each Value is a oneof with these types:

TypeProto FieldDescription
Nullnull_valueNull value
Booleanbool_valueBoolean value
Integerint64_value64-bit signed integer
Floatfloat64_value64-bit floating point
Texttext_valueUTF-8 string
Bytesbytes_valueRaw bytes
Vectorvector_valueVectorValue (list of floats)
DateTimedatetime_valueUnix microseconds (UTC)
Geogeo_valueGeoPoint (latitude, longitude)
Int64Arrayint64_array_valueInt64ArrayValue (multi-valued integers; requires IntegerOption.multi_valued = true)
Float64Arrayfloat64_array_valueFloat64ArrayValue (multi-valued floats; requires FloatOption.multi_valued = true)
Geo3dgeo3d_valueGeo3dPoint (x, y, z meters; ECEF Cartesian)
GeoArraygeo_array_valueGeoArrayValue (repeated GeoPoint; multi-valued 2D points; requires GeoOption.multi_valued = true)
Geo3dArraygeo3d_array_valueGeo3dArrayValue (repeated Geo3dPoint; multi-valued 3D points; requires Geo3dOption.multi_valued = true)
DateTimeArraydatetime_array_valueDatetimeArrayValue (repeated int64 Unix microseconds; multi-valued instants; requires DateTimeOption.multi_valued = true)
BoolArraybool_array_valueBoolArrayValue (repeated bool; multi-valued booleans; requires BooleanOption.multi_valued = true)
TextArraytext_array_valueTextArrayValue (repeated string; multi-valued text; requires TextOption.multi_valued = true)
BytesArraybytes_array_valueBytesArrayValue (repeated bytes; multi-valued bytes, MIME not carried on the wire; requires BytesOption.multi_valued = true)
VectorArrayvector_array_valueVectorArrayValue (uint32 dimension, repeated float values; token vectors packed row-major, values.len() / dimension vectors; requires a MultiVectorOption field)

Geo3dPoint:

FieldTypeDescription
xdoubleX coordinate in meters (ECEF: equatorial plane, +X toward 0° longitude)
ydoubleY coordinate in meters (ECEF: equatorial plane, +Y toward 90°E)
zdoubleZ coordinate in meters (ECEF: +Z toward the North Pole)

See 3D Geographic Search (ECEF) for the full coordinate system description and the wgs84_to_ecef / ecef_to_wgs84 conversion utilities.

AddDocument

Add a document. Unlike PutDocument, this does not replace existing documents with the same ID — multiple documents can share an ID (chunking pattern).

rpc AddDocument(AddDocumentRequest) returns (AddDocumentResponse);

Request fields are the same as PutDocument.

PutDocuments

Batched upsert. Entries are applied sequentially, in input order, with one WAL fsync for the whole batch — much faster than one PutDocument call per document. Duplicate IDs within one batch dedup exactly like the same puts issued one by one (the last occurrence wins).

rpc PutDocuments(PutDocumentsRequest) returns (PutDocumentsResponse);

message DocumentEntry {
  string id = 1;
  Document document = 2;
}

message PutDocumentsRequest {
  repeated DocumentEntry documents = 1;
}

message PutDocumentsResponse {
  uint32 applied = 1; // equals the request size on success
}

The call fails fast at the first entry that cannot be applied. Already-applied entries are not rolled back — they are durable at the next commit — and the error status message carries the failing position, its ID, and the applied count, so retrying the batch (or its suffix) is idempotent. A batch that fails on a caller mistake (e.g. a schema violation) returns INVALID_ARGUMENT; storage failures return INTERNAL.

AddDocuments

Batched chunk append. Like PutDocuments but never deletes existing documents, so a batch may legitimately repeat an ID to add multiple chunks of the same logical document.

rpc AddDocuments(AddDocumentsRequest) returns (AddDocumentsResponse);

Request/response fields mirror PutDocuments.

GetDocuments

Retrieve all documents matching the given external ID.

rpc GetDocuments(GetDocumentsRequest) returns (GetDocumentsResponse);

Request fields:

FieldTypeRequiredDescription
idstringYesExternal document ID

Response fields:

FieldTypeDescription
documentsrepeated DocumentMatching documents

DeleteDocuments

Delete all documents matching the given external ID.

rpc DeleteDocuments(DeleteDocumentsRequest) returns (DeleteDocumentsResponse);

Commit

Commit pending changes (additions and deletions) to the index. Changes are not visible to search until committed.

rpc Commit(CommitRequest) returns (CommitResponse);

FlushWal

Force buffered WAL records durable without a full commit. Both messages are empty. This is a near no-op under the default per-record sync policy (every write is already fsync’d); under the group-commit policy it flushes the current partial batch on demand, bounding the crash-loss window. Unlike Commit, it does not materialize segments, so buffered changes remain invisible to search until a subsequent Commit.

rpc FlushWal(FlushWalRequest) returns (FlushWalResponse);

message FlushWalRequest {}

message FlushWalResponse {}

The WAL durability policy is configured server-side via the [index.wal] config section. See Configuration → [index.wal] Section and Persistence & WAL → WAL Durability Policy.

HTTP gateway: POST /v1/flush_wal


SearchService

Execute a search query and return results as a single response.

rpc Search(SearchRequest) returns (SearchResponse);

Response fields:

FieldTypeDescription
resultsrepeated SearchResultSearch results ordered by relevance
total_hitsuint64Total number of matching documents (before limit/offset)

SearchStream

Execute a search query and stream results back one at a time.

rpc SearchStream(SearchRequest) returns (stream SearchResult);

SearchRequest Fields

FieldTypeRequiredDescription
querystringNoLexical search query in Query DSL
query_vectorsrepeated QueryVectorNoVector search queries
limituint32NoMaximum number of results (default: engine default)
offsetuint32NoNumber of results to skip
fusionFusionAlgorithmNoFusion algorithm for hybrid search
lexical_paramsLexicalParamsNoLexical search parameters
vector_paramsVectorParamsNoVector search parameters
field_boostsmap<string, float>NoPer-field score boosting
highlightHighlightParamsNoRequest highlighted fragments per field (Issue #1134)
rescoreRescoreParamsNoRescore the top first-stage results with late interaction (Issue #1351)

At least one of query or query_vectors must be provided.

3D Geographic Queries

3D ECEF geographic queries are expressed in the lexical DSL string passed via SearchRequest.query. There is no dedicated message type — the same DSL forms used by the core library work over gRPC. Three forms are available (see Query DSL → 3D Geographic Queries for full syntax):

  • position:geo3d_distance(x, y, z, distance_m) — sphere centered at (x, y, z) with maximum distance in meters
  • position:geo3d_bbox(min_x, min_y, min_z, max_x, max_y, max_z) — 3D axis-aligned bounding box
  • position:geo3d_nearest(x, y, z, k) — k nearest neighbours to (x, y, z)

position is the field name; substitute the actual Geo3d-typed field declared in your schema. All numeric arguments are signed double values; k is an unsigned integer.

QueryVector

FieldTypeDescription
vectorrepeated floatQuery vector
weightfloatWeight for this vector (default: 1.0)
fieldsrepeated stringTarget vector fields (empty = all)

FusionAlgorithm

A oneof with two options:

  • RRF (Reciprocal Rank Fusion): k parameter (default: 60)
  • WeightedSum: lexical_weight and vector_weight

LexicalParams

FieldTypeDescription
min_scorefloatMinimum score threshold
timeout_msuint64Search timeout in milliseconds
parallelboolEnable parallel search
sort_bySortSpecSort by a field instead of score

SortSpec

FieldTypeDescription
fieldstringField name to sort by. Empty string means sort by relevance score
orderSortOrderSORT_ORDER_ASC (ascending) or SORT_ORDER_DESC (descending)

VectorParams

FieldTypeDescription
fieldsrepeated stringTarget vector fields
score_modeVectorScoreModeWEIGHTED_SUM, MAX_SIM, or LATE_INTERACTION
overfetchfloatOverfetch factor (default: 2.0)
min_scorefloatMinimum score threshold
rerank_factoroptional uint32Stage 2 rerank widening factor (Issue #481). When set on a field whose schema enabled rerank_storage, the server widens the int8/PQ candidate fetch to top_k * rerank_factor and rescores the candidates against the original full-precision vectors before returning the top top_k. Honored on all three vector index types since #932 (HNSW, Flat, IVF — on Flat/IVF this applies to field-routed queries); fields without rerank_storage = "F32" silently fall back to int8 ranking — there is no f32 information to recover. A value of 0 or omitting the field disables rerank.
ef_searchoptional uint32Per-query override for the HNSW ef_search candidate-list size (Issue #644). Also gates the PQ → SQ → f32 three-stage rerank chain (Issue #673): on a PQ field with rerank_storage enabled, setting ef_search wider than top_k * rerank_factor activates an extra int8 stage that rescores the graph’s full candidate set — derived from the same rerank_storage sidecar, no extra configuration needed — before the exact stage’s narrower budget is carved out of it. Ignored on non-HNSW fields.

HighlightParams

Requests highlighted fragments for specific fields (Issue #1134). Highlighting uses SearchRequest.query (or the lexical clause of a DSL query), the same query that drives lexical scoring — filter_query never contributes highlighted terms, and a vector-only request (no lexical query) produces no highlights. Only stored: true text fields can be highlighted; other names are silently skipped. See Highlighting for full semantics.

FieldTypeDescription
fieldsrepeated stringStored text fields to highlight. Required — a request with this unset or empty is rejected with INVALID_ARGUMENT
max_fragmentsoptional uint32Maximum fragments per field (default: 5). 0 is rejected
fragment_sizeoptional uint32Target fragment length in characters (default: 150). 0 is rejected
tagoptional stringHTML tag to wrap matches (default: "mark"). An empty string is treated as unset
css_classoptional stringCSS class added to the tag. An empty string is treated as unset
require_field_matchoptional boolOnly use query terms that target the highlighted field (default: true)
max_analyzed_charsoptional uint64Maximum characters of a field’s text to analyze (default: 1,000,000)
return_entire_field_if_no_highlightoptional boolReturn the full field value as one fragment when nothing matched (default: false)

Highlights

FieldTypeDescription
fragmentsrepeated stringHighlighted fragments for one field, best fragment first

RescoreParams

Reorders the top window_size first-stage results (lexical, vector or hybrid) with ColBERT-style late interaction over a MultiVector field (Issue #1351). See Late-Interaction Rescore for the scoring and ordering rules.

FieldTypeDescription
window_sizeoptional uint32How many top first-stage results to rescore, 1 to 10,000. Unset means 100
late_interactionLateInteractionRescoreThe rescorer (a oneof; required)

LateInteractionRescore:

FieldTypeDescription
fieldstringA MultiVector field
vectorsVectorArrayValueThe query’s token vectors, packed row-major like a document value (1 to 1,024 vectors of the field’s dimension). One of vectors and text is required
textstringQuery text, embedded by the field’s token-level embedder (a candle_colbert one)

The engine validates the values: an out-of-range window, a field that is not a MultiVector field, the wrong number or dimension of vectors, text for a field without a token-level embedder, or a rescore combined with lexical_params.sort_by is rejected with INVALID_ARGUMENT, as is a RescoreParams without late_interaction or a query.

SearchResult

FieldTypeDescription
idstringExternal document ID
scorefloatRelevance score; for a rescored result, its late-interaction (MaxSim) score
documentDocumentDocument content
highlightsmap<string, Highlights>Highlighted fragments per field named in SearchRequest.highlight.fields. A field with no highlight is absent from this map

Example

{
  "query": "body:rust",
  "query_vectors": [
    {"vector": [0.1, 0.2, 0.3], "weight": 1.0}
  ],
  "limit": 10,
  "fusion": {
    "rrf": {"k": 60}
  },
  "field_boosts": {
    "title": 2.0
  }
}

Example: Highlighting

{
  "query": "body:rust",
  "limit": 10,
  "highlight": {"fields": ["body"], "max_fragments": 2, "tag": "em"}
}

A matching hit’s SearchResult then carries:

{
  "id": "doc1",
  "score": 1.2,
  "document": {"fields": {"body": {"text_value": "Rust is great"}}},
  "highlights": {"body": {"fragments": ["<em>Rust</em> is great"]}}
}

Example: Rescore

A hybrid first stage whose top 100 results are rescored by a ColBERT embedder on body_colbert:

{
  "query": "body:lifetimes body_vec:\"how do lifetimes work\"",
  "limit": 10,
  "rescore": {
    "window_size": 100,
    "late_interaction": {"field": "body_colbert", "text": "how do lifetimes work"}
  }
}

With pre-computed query token vectors instead of text:

{
  "late_interaction": {
    "field": "body_colbert",
    "vectors": {"dimension": 2, "values": [1.0, 0.0, 0.0, 1.0]}
  }
}

Error Handling

gRPC errors are returned as standard Status codes:

Laurus ErrorgRPC StatusWhen
Schema / Query / Field / Invalid argument / JSONINVALID_ARGUMENTMalformed request or schema, unknown field in a query
No index openFAILED_PRECONDITIONRPC called before CreateIndex
Index already existsALREADY_EXISTSCreateIndex called twice
Not implementedUNIMPLEMENTEDFeature not yet supported
Internal errorsINTERNALI/O, storage, or unexpected errors