Skip to main content
POST
/
v1
/
vectors
/
upsert
Upsert Vectors
curl --request POST \
  --url https://api.example.com/v1/vectors/upsert
import requests

url = "https://api.example.com/v1/vectors/upsert"

response = requests.post(url)

print(response.text)
const options = {method: 'POST'};

fetch('https://api.example.com/v1/vectors/upsert', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/vectors/upsert",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.example.com/v1/vectors/upsert"

req, _ := http.NewRequest("POST", url, nil)

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.example.com/v1/vectors/upsert")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/v1/vectors/upsert")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
Add new vectors or update existing ones in the encrypted index.

Authentication

Required - API key via X-API-Key header:
X-API-Key: cyborg_your_api_key_here
You can get an API key from the CyborgDB Admin Dashboard. For more info, follow this guide.

Request Body

{
  "index_name": "my_index",
  "index_key": "64_character_hex_string_representing_32_bytes",
  "items": [
    {
      "id": "item_1",
      "vector": [0.1, 0.2, 0.3, 0.4],
      "contents": "Hello world!",
      "metadata": {"category": "greeting", "language": "en"}
    },
    {
      "id": "item_2",
      "vector": [0.5, 0.6, 0.7, 0.8],
      "contents": "Bonjour monde!",
      "metadata": {"category": "greeting", "language": "fr"}
    }
  ]
}

Response

Standard Success Response:
{
  "status": "success",
  "message": "Upserted 2 vectors"
}
With Auto-Training Triggered:
{
  "status": "success",
  "message": "Upserted 2 vectors",
  "training_triggered": true,
  "training_message": "Index training has been triggered (vectors: 5000, threshold: 10000)"
}
With Training Check Warning:
{
  "status": "success",
  "message": "Upserted 2 vectors",
  "warning": "Training check failed but upsert succeeded"
}
When the number of vectors in an index exceeds the automatic training threshold, the upsert response will include training_triggered and training_message fields. Training happens asynchronously in the background.In rare cases where the training check encounters an error but the upsert operation itself succeeds, a warning field will be included instead. The vectors are still successfully upserted in this scenario.

Exceptions

  • 401: Authentication failed (invalid API key)
  • 404: Index not found
  • 422: Invalid request parameters or vector dimensions
  • 500: Internal server error

Example Usage

Basic Upsert:
curl -X POST "http://localhost:8000/v1/vectors/upsert" \
     -H "X-API-Key: cyborg_your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "index_name": "my_index",
       "index_key": "your_64_character_hex_key_here",
       "items": [
         {
           "id": "item_1",
           "vector": [0.1, 0.2, 0.3, 0.4],
           "contents": "Hello world!"
         }
       ]
     }'
With Metadata:
curl -X POST "http://localhost:8000/v1/vectors/upsert" \
     -H "X-API-Key: cyborg_your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "index_name": "my_index",
       "index_key": "your_64_character_hex_key_here",
       "items": [
         {
           "id": "doc_1",
           "vector": [0.1, 0.2, 0.3, 0.4],
           "contents": "Important document content",
           "metadata": {
             "category": "documentation",
             "author": "admin",
             "created": "2024-01-15",
             "priority": "high"
           }
         }
       ]
     }'
Auto-Generated Embeddings:
# For indexes created with embedding_model
curl -X POST "http://localhost:8000/v1/vectors/upsert" \
     -H "X-API-Key: cyborg_your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "index_name": "semantic_index",
       "index_key": "your_64_character_hex_key_here",
       "items": [
         {
           "id": "text_1",
           "contents": "This text will be automatically embedded",
           "metadata": {"type": "auto_embedded"}
         }
       ]
     }'
Batch Upsert:
curl -X POST "http://localhost:8000/v1/vectors/upsert" \
     -H "X-API-Key: cyborg_your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "index_name": "my_index",
       "index_key": "your_64_character_hex_key_here",
       "items": [
         {"id": "batch_1", "vector": [0.1, 0.2, 0.3]},
         {"id": "batch_2", "vector": [0.4, 0.5, 0.6]},
         {"id": "batch_3", "vector": [0.7, 0.8, 0.9]},
         {"id": "batch_4", "vector": [0.2, 0.3, 0.4]},
         {"id": "batch_5", "vector": [0.5, 0.6, 0.7]}
       ]
     }'
When embedding_model is configured for the index, the vector parameter becomes optional. If provided, it will be used directly; if omitted, a vector will be auto-generated from the contents field.
For large datasets, use batch upserts with multiple items in a single request to improve performance and reduce network overhead.