Ingest Operations

The ingest endpoints allow you to add data to an index through an init → ingest → finalize workflow.

Initialize Ingest

Start an ingest session on an index. This must be called before any ingest operations.
POST /init

Request Body

{
  "index_name": "my_index",
  "mode": "build"
}
FieldTypeRequiredDescription
index_namestringYesName of the index
modestringYesOne of: "build", "insert", "upsert"

Ingest Modes

ModeDescription
buildCreate a new index from scratch
insertAdd new vectors to an existing index
upsertAdd new vectors or update existing ones

Response

{
  "success": true,
  "message": "Index 'my_index' initialized in 'build' mode",
  "index_name": "my_index"
}

Errors

StatusCondition
404Index not found
400Invalid mode or initialization failed

Ingest Single Vector

Add a single vector to an index. The ingest session must have been initialized first.
POST /ingest

Request Body

{
  "index_name": "my_index",
  "external_id": "item_001",
  "vector": [0.1, 0.2, 0.3, 0.4, 0.5]
}
FieldTypeRequiredDescription
index_namestringYesName of the index
external_idstringYesUnique identifier for this vector
vectorfloat[]YesVector data as an array of floats

Response

{
  "success": true
}

Errors

StatusCondition
400Missing required fields or invalid vector
404Index not found (implicitly, via engine lookup)

Batch Ingest (Binary)

Ingest multiple vectors efficiently using a binary protocol. This is significantly faster than individual ingest calls for large batches.
POST /ingest/batch?index_name=my_index
Content-Type: application/octet-stream

Query Parameters

ParameterTypeRequiredDescription
index_namestringYesName of the index

Binary Format

The request body is a sequence of rows, where each row consists of:
  1. 32 bytes — External ID as ASCII text, null-padded to 32 bytes
  2. dim * 4 bytes — Vector data as float32 little-endian values
For a 128-dimensional index, each row is 32 + 128*4 = 544 bytes.

Example Binary Layout (dim=4)

Row 1: [item_001\x00...\x00] [0.1f32] [0.2f32] [0.3f32] [0.4f32]
Row 2: [item_002\x00...\x00] [0.5f32] [0.6f32] [0.7f32] [0.8f32]

Response

{
  "success": true,
  "count": 1000
}
FieldTypeDescription
successbooleanWhether the operation succeeded
countintegerNumber of vectors ingested

Errors

StatusCondition
400Missing index_name, misaligned payload, or ingest error

Finalize Ingest

Complete an ingest session and build the HNSW graph from the ingested data.
POST /finalize

Request Body

{
  "index_name": "my_index",
  "optimize": true,
  "params": {
    "M": 48,
    "ef_construction": 1024,
    "ef_search": 512,
    "rng_seed": 0
  }
}
FieldTypeRequiredDefaultDescription
index_namestringYesName of the index
optimizebooleanNofalseWhether to optimize the graph after build
paramsobjectNodefaultsOptional HNSW parameters override

Response

{
  "success": true,
  "message": "Finalized ingest for index 'my_index' (optimize=true)",
  "index_name": "my_index"
}

Errors

StatusCondition
400Finalization failed