> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyborg.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Upsert

Adds vectors to the index, or replaces existing vectors with the same ID. `Upsert` takes either `VectorItems` (sent as JSON) or `BinaryUpsertParams` (sent as binary); `UpsertVectors` is a shortcut for the binary form.

```go theme={null}
func (e *EncryptedIndex) Upsert(ctx context.Context, input UpsertInput) error
func (e *EncryptedIndex) UpsertVectors(ctx context.Context, ids []string, vectors [][]float32, metadata []map[string]interface{}) error
```

### Parameters

#### VectorItems

`VectorItems` is a `[]VectorItem`:

| Field | Type | Description |
| - | - | - |
| `Id` | `string` | Unique identifier. Required. |
| `Vector` | `[]float32` | Vector data. May be empty if the index has an embedding model and the item has contents. |
| `Metadata` | `map[string]interface{}` | *(Optional)* Key-value pairs for filtering. |
| `Contents` | `NullableContents` | *(Optional)* Text to store with the item, and to embed on an index with an embedding model. Set it with `item.SetContentsString(s)`; see [Set contents on a VectorItem](#set-contents-on-a-vectoritem). |

#### BinaryUpsertParams

Vectors are sent as base64-encoded little-endian `float32`, which is faster for large batches.

| Field | Type | Description |
| - | - | - |
| `IDs` | `[]string` | Unique identifier for each vector. |
| `Vectors` | `[][]float32` | Vector data, one slice per ID. All vectors must have the same length. |
| `Metadata` | `[]map[string]interface{}` | *(Optional)* Metadata per vector, same length as `IDs`. |
| `Contents` | `[]string` | *(Optional)* Contents per vector, same length as `IDs`. An empty string means no contents. |

`UpsertVectors(ctx, ids, vectors, metadata)` is the same as `Upsert` with a `BinaryUpsertParams` that has no contents.

<Tip>Store dates in `Metadata` as epoch milliseconds (`t.UnixMilli()`) so range filters work on them. See [Dates](../types#dates).</Tip>

<Warning>Don't upsert vectors containing `NaN` or infinite values. The service stores them, and later `get` or `query` calls on that index that return vectors or distances fail with a `5xx` error. The SDK doesn't check for them.</Warning>

### Returns

`error` only; `nil` on success.

### Errors

<AccordionGroup>
  <Accordion title="*ValidationError">
    * Wraps a sentinel. A `BinaryUpsertParams` field is empty, slices differ in length (`ErrIDsVectorsLengthMismatch`, `ErrMetadataLengthMismatch`, `ErrContentsLengthMismatch`), or vectors differ in length (`ErrInconsistentDimension`). Returned before any request is sent. `VectorItems` aren't checked in the SDK.
    * The service rejects the items (HTTP `400`), for example a vector with the wrong dimension.
  </Accordion>

  <Accordion title="*AuthenticationError">
    The `apiKey` is invalid, or a read-only user key is used (HTTP `401`/`403`).
  </Accordion>

  <Accordion title="*ServiceError / *TransportError">
    The service returns `5xx` or can't be reached.
  </Accordion>
</AccordionGroup>

See [Errors](../errors).

### Example Usage

#### VectorItems

```go theme={null}
err := index.Upsert(ctx, cyborgdb.VectorItems{
    {Id: "doc1", Vector: []float32{0.1, 0.2, 0.3, 0.4}},
    {Id: "doc2", Vector: []float32{0.5, 0.6, 0.7, 0.8}, Metadata: map[string]interface{}{"category": "news"}},
})
if err != nil {
    log.Fatal(err)
}
```

#### BinaryUpsertParams with metadata and contents

```go theme={null}
err := index.Upsert(ctx, cyborgdb.BinaryUpsertParams{
    IDs: []string{"vec1", "vec2", "vec3"},
    Vectors: [][]float32{
        {0.1, 0.2, 0.3, 0.4},
        {0.5, 0.6, 0.7, 0.8},
        {0.9, 1.0, 1.1, 1.2},
    },
    Metadata: []map[string]interface{}{{"category": "news"}, {"category": "research"}, nil},
    Contents: []string{"First body", "Second body", ""},
})
if err != nil {
    log.Fatal(err)
}
```

#### Set contents on a VectorItem

```go theme={null}
item := cyborgdb.VectorItem{Id: "doc3", Vector: []float32{0.1, 0.2, 0.3, 0.4}}
item.SetContentsString("Third document")

if err := index.Upsert(ctx, cyborgdb.VectorItems{item}); err != nil {
    log.Fatal(err)
}

res, err := index.Get(ctx, []string{"doc3"}, []string{"contents"})
if err != nil {
    log.Fatal(err)
}
fmt.Println(res.Results[0].GetContents())
// Output: Third document
```

On an index with an embedding model, leave `Vector` empty and the service embeds the contents.

#### UpsertVectors

```go theme={null}
ids := []string{"vec4", "vec5"}
vectors := [][]float32{
    {0.1, 0.2, 0.3, 0.4},
    {0.5, 0.6, 0.7, 0.8},
}

if err := index.UpsertVectors(ctx, ids, vectors, nil); err != nil {
    log.Fatal(err)
}
```

#### Replace an existing item

```go theme={null}
items := cyborgdb.VectorItems{{Id: "doc1", Vector: []float32{0.1, 0.2, 0.3, 0.4}, Metadata: map[string]interface{}{"version": 1}}}
if err := index.Upsert(ctx, items); err != nil {
    log.Fatal(err)
}

// Same ID: replaces the vector and metadata
items = cyborgdb.VectorItems{{Id: "doc1", Vector: []float32{0.2, 0.3, 0.4, 0.5}, Metadata: map[string]interface{}{"version": 2}}}
if err := index.Upsert(ctx, items); err != nil {
    log.Fatal(err)
}

res, err := index.Get(ctx, []string{"doc1"}, []string{"metadata"})
if err != nil {
    log.Fatal(err)
}
fmt.Println(res.Results[0].Metadata)
// Output: map[version:2]
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.