> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://www.comet.com/docs/opik/llms.txt.

# Create/update dataset items

PUT http://localhost:5173/api/v1/private/datasets/items
Content-Type: application/json

Create/update dataset items based on dataset item id.
Each item's 'id' field is the stable identifier and upsert key.
Provide it to update an existing item, or omit it to create a new one.

Set 'copy_from_dataset_id' and 'copy_from_version_id' together to read carry-forward rows
from the supplied (dataset, version) pair instead of the destination's prior version. When
the fields are null, carry-forward rows are read from the destination's prior version.

Reference: https://www.comet.com/docs/opik/reference/rest-api/datasets/create-or-update-dataset-items

## Servers

- `http://localhost:5173/api` (Local server, default)
- `https://www.comet.com/opik/api` (Opik Cloud)

## Request

### Body (application/json)

This endpoint expects a DatasetItemBatch_Write.

- `items` (list of DatasetItem_Write, required)
- `dataset_name` (string, optional) — If null, dataset_id must be provided
- `dataset_id` (string, optional) — If null, dataset_name must be provided
- `project_name` (string, optional) — Optional. Associates the batch with a project by name. Ignored if project_id is provided.
- `project_id` (string, optional) — Optional. Associates the batch with a project by ID. Takes precedence over project_name.
- `batch_group_id` (string, optional) — Optional batch group ID to group multiple batches into a single dataset version. If null, mutates the latest version instead of creating a new one.
- `copy_from_dataset_id` (string, optional) — Optional. Dataset to read carry-forward rows from when materializing the new version. Required together with copy_from_version_id. When null, carry-forward rows are read from the destination dataset's prior version.
- `copy_from_version_id` (string, optional) — Optional. Version within copy_from_dataset_id to read carry-forward rows from. Required together with copy_from_dataset_id.

## Response

### 204

No content

## Types

### DatasetItem_Write

- `source` (enum, required)
  - Allowed values: `manual`, `trace`, `span`, `sdk`
- `data` (JsonNode, required)
- `id` (string, optional) — Stable item identifier. On write, used as the upsert key. If omitted, a new ID is generated. Remains the same across dataset versions
- `trace_id` (string, optional)
- `span_id` (string, optional)
- `description` (string, optional)
- `tags` (list of string, optional)
- `evaluators` (list of EvaluatorItem_Write, optional)
- `execution_policy` (ExecutionPolicy_Write, optional)

### JsonNode

### EvaluatorItem_Write

- `name` (string, required)
- `type` (enum, required)
  - Allowed values: `llm_judge`, `code_metric`
- `config` (JsonNode_Write, required)

### ExecutionPolicy_Write

- `runs_per_item` (integer, optional)
- `pass_threshold` (integer, optional)

### JsonNode_Write

## Examples

**Request**

```json
{
  "items": [
    {
      "source": "manual",
      "data": {}
    }
  ]
}
```

**SDK Code**

```python
import requests

url = "http://localhost:5173/api/v1/private/datasets/items"

payload = { "items": [
        {
            "source": "manual",
            "data": {}
        }
    ] }
headers = {"Content-Type": "application/json"}

response = requests.put(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'http://localhost:5173/api/v1/private/datasets/items';
const options = {
  method: 'PUT',
  headers: {'Content-Type': 'application/json'},
  body: '{"items":[{"source":"manual","data":{}}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

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

func main() {

	url := "http://localhost:5173/api/v1/private/datasets/items"

	payload := strings.NewReader("{\n  \"items\": [\n    {\n      \"source\": \"manual\",\n      \"data\": {}\n    }\n  ]\n}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("Content-Type", "application/json")

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

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

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("http://localhost:5173/api/v1/private/datasets/items")

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

request = Net::HTTP::Put.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n  \"items\": [\n    {\n      \"source\": \"manual\",\n      \"data\": {}\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("http://localhost:5173/api/v1/private/datasets/items")
  .header("Content-Type", "application/json")
  .body("{\n  \"items\": [\n    {\n      \"source\": \"manual\",\n      \"data\": {}\n    }\n  ]\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'http://localhost:5173/api/v1/private/datasets/items', [
  'body' => '{
  "items": [
    {
      "source": "manual",
      "data": {}
    }
  ]
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("http://localhost:5173/api/v1/private/datasets/items");
var request = new RestRequest(Method.PUT);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"items\": [\n    {\n      \"source\": \"manual\",\n      \"data\": {}\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = ["items": [
    [
      "source": "manual",
      "data": []
    ]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "http://localhost:5173/api/v1/private/datasets/items")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```