curl --request POST \
--url https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"application_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"start_time": "2023-11-07T05:31:56Z",
"end_time": "2023-11-07T05:31:56Z",
"spans": [
{
"trace_id": "<string>",
"span_id": "<string>"
}
],
"mapping": {
"inputs": {
"question": "gen_ai.request.user_message"
},
"expected_outputs": {
"answer": "gen_ai.completion.content"
},
"metadata": {
"trace_id": "trace.id",
"model": "gen_ai.request.model"
},
"extras": {
"context": "gen_ai.contents.context"
}
}
}
'import requests
url = "https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans"
payload = {
"application_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"start_time": "2023-11-07T05:31:56Z",
"end_time": "2023-11-07T05:31:56Z",
"spans": [
{
"trace_id": "<string>",
"span_id": "<string>"
}
],
"mapping": {
"inputs": { "question": "gen_ai.request.user_message" },
"expected_outputs": { "answer": "gen_ai.completion.content" },
"metadata": {
"trace_id": "trace.id",
"model": "gen_ai.request.model"
},
"extras": { "context": "gen_ai.contents.context" }
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
application_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
start_time: '2023-11-07T05:31:56Z',
end_time: '2023-11-07T05:31:56Z',
spans: [{trace_id: '<string>', span_id: '<string>'}],
mapping: {
inputs: {question: 'gen_ai.request.user_message'},
expected_outputs: {answer: 'gen_ai.completion.content'},
metadata: {trace_id: 'trace.id', model: 'gen_ai.request.model'},
extras: {context: 'gen_ai.contents.context'}
}
})
};
fetch('https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans', 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/v3/evals/datasets/{dataset_id}/items/from-spans",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'application_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'start_time' => '2023-11-07T05:31:56Z',
'end_time' => '2023-11-07T05:31:56Z',
'spans' => [
[
'trace_id' => '<string>',
'span_id' => '<string>'
]
],
'mapping' => [
'inputs' => [
'question' => 'gen_ai.request.user_message'
],
'expected_outputs' => [
'answer' => 'gen_ai.completion.content'
],
'metadata' => [
'trace_id' => 'trace.id',
'model' => 'gen_ai.request.model'
],
'extras' => [
'context' => 'gen_ai.contents.context'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans"
payload := strings.NewReader("{\n \"application_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"start_time\": \"2023-11-07T05:31:56Z\",\n \"end_time\": \"2023-11-07T05:31:56Z\",\n \"spans\": [\n {\n \"trace_id\": \"<string>\",\n \"span_id\": \"<string>\"\n }\n ],\n \"mapping\": {\n \"inputs\": {\n \"question\": \"gen_ai.request.user_message\"\n },\n \"expected_outputs\": {\n \"answer\": \"gen_ai.completion.content\"\n },\n \"metadata\": {\n \"trace_id\": \"trace.id\",\n \"model\": \"gen_ai.request.model\"\n },\n \"extras\": {\n \"context\": \"gen_ai.contents.context\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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/v3/evals/datasets/{dataset_id}/items/from-spans")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"application_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"start_time\": \"2023-11-07T05:31:56Z\",\n \"end_time\": \"2023-11-07T05:31:56Z\",\n \"spans\": [\n {\n \"trace_id\": \"<string>\",\n \"span_id\": \"<string>\"\n }\n ],\n \"mapping\": {\n \"inputs\": {\n \"question\": \"gen_ai.request.user_message\"\n },\n \"expected_outputs\": {\n \"answer\": \"gen_ai.completion.content\"\n },\n \"metadata\": {\n \"trace_id\": \"trace.id\",\n \"model\": \"gen_ai.request.model\"\n },\n \"extras\": {\n \"context\": \"gen_ai.contents.context\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"application_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"start_time\": \"2023-11-07T05:31:56Z\",\n \"end_time\": \"2023-11-07T05:31:56Z\",\n \"spans\": [\n {\n \"trace_id\": \"<string>\",\n \"span_id\": \"<string>\"\n }\n ],\n \"mapping\": {\n \"inputs\": {\n \"question\": \"gen_ai.request.user_message\"\n },\n \"expected_outputs\": {\n \"answer\": \"gen_ai.completion.content\"\n },\n \"metadata\": {\n \"trace_id\": \"trace.id\",\n \"model\": \"gen_ai.request.model\"\n },\n \"extras\": {\n \"context\": \"gen_ai.contents.context\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"api_version": "3.0",
"kind": "NORMAL",
"data": {
"items": [
{
"trace_id": "<string>",
"span_id": "<string>",
"item_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"error": {
"code": 422,
"message": "One or more spans could not be resolved. No items were written.",
"errors": [
{
"reason": "SpanNotFound",
"message": "Span span-002-b (trace 4f9fa507) not found within the specified time range"
}
]
},
"api_version": "3.0",
"kind": "ERROR"
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}Bulk add spans to dataset
Accept a list of explicit span references and a field mapping, fetch span attributes from ClickHouse, apply the mapping server-side, and write one dataset item per span. All-or-nothing — if any span cannot be resolved, no items are written and a 422 is returned with the list of unresolvable spans.
start_time and end_time are required to bound the ClickHouse lookup to the relevant monthly partitions. Without them, the query would scan every partition for the application. The FE should pass the datagrid’s current time range; MCP agents should pass the time range of the spans being exported.
Mapping values are span attribute keys as returned by POST /v3/spans/fields (e.g. "system.gen_ai.usage.input_tokens", "user.cost_usd"). Each key maps to the corresponding value from the span’s span_attributes dict.
curl --request POST \
--url https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"application_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"start_time": "2023-11-07T05:31:56Z",
"end_time": "2023-11-07T05:31:56Z",
"spans": [
{
"trace_id": "<string>",
"span_id": "<string>"
}
],
"mapping": {
"inputs": {
"question": "gen_ai.request.user_message"
},
"expected_outputs": {
"answer": "gen_ai.completion.content"
},
"metadata": {
"trace_id": "trace.id",
"model": "gen_ai.request.model"
},
"extras": {
"context": "gen_ai.contents.context"
}
}
}
'import requests
url = "https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans"
payload = {
"application_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"start_time": "2023-11-07T05:31:56Z",
"end_time": "2023-11-07T05:31:56Z",
"spans": [
{
"trace_id": "<string>",
"span_id": "<string>"
}
],
"mapping": {
"inputs": { "question": "gen_ai.request.user_message" },
"expected_outputs": { "answer": "gen_ai.completion.content" },
"metadata": {
"trace_id": "trace.id",
"model": "gen_ai.request.model"
},
"extras": { "context": "gen_ai.contents.context" }
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
application_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
start_time: '2023-11-07T05:31:56Z',
end_time: '2023-11-07T05:31:56Z',
spans: [{trace_id: '<string>', span_id: '<string>'}],
mapping: {
inputs: {question: 'gen_ai.request.user_message'},
expected_outputs: {answer: 'gen_ai.completion.content'},
metadata: {trace_id: 'trace.id', model: 'gen_ai.request.model'},
extras: {context: 'gen_ai.contents.context'}
}
})
};
fetch('https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans', 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/v3/evals/datasets/{dataset_id}/items/from-spans",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'application_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'start_time' => '2023-11-07T05:31:56Z',
'end_time' => '2023-11-07T05:31:56Z',
'spans' => [
[
'trace_id' => '<string>',
'span_id' => '<string>'
]
],
'mapping' => [
'inputs' => [
'question' => 'gen_ai.request.user_message'
],
'expected_outputs' => [
'answer' => 'gen_ai.completion.content'
],
'metadata' => [
'trace_id' => 'trace.id',
'model' => 'gen_ai.request.model'
],
'extras' => [
'context' => 'gen_ai.contents.context'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans"
payload := strings.NewReader("{\n \"application_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"start_time\": \"2023-11-07T05:31:56Z\",\n \"end_time\": \"2023-11-07T05:31:56Z\",\n \"spans\": [\n {\n \"trace_id\": \"<string>\",\n \"span_id\": \"<string>\"\n }\n ],\n \"mapping\": {\n \"inputs\": {\n \"question\": \"gen_ai.request.user_message\"\n },\n \"expected_outputs\": {\n \"answer\": \"gen_ai.completion.content\"\n },\n \"metadata\": {\n \"trace_id\": \"trace.id\",\n \"model\": \"gen_ai.request.model\"\n },\n \"extras\": {\n \"context\": \"gen_ai.contents.context\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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/v3/evals/datasets/{dataset_id}/items/from-spans")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"application_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"start_time\": \"2023-11-07T05:31:56Z\",\n \"end_time\": \"2023-11-07T05:31:56Z\",\n \"spans\": [\n {\n \"trace_id\": \"<string>\",\n \"span_id\": \"<string>\"\n }\n ],\n \"mapping\": {\n \"inputs\": {\n \"question\": \"gen_ai.request.user_message\"\n },\n \"expected_outputs\": {\n \"answer\": \"gen_ai.completion.content\"\n },\n \"metadata\": {\n \"trace_id\": \"trace.id\",\n \"model\": \"gen_ai.request.model\"\n },\n \"extras\": {\n \"context\": \"gen_ai.contents.context\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v3/evals/datasets/{dataset_id}/items/from-spans")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"application_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"start_time\": \"2023-11-07T05:31:56Z\",\n \"end_time\": \"2023-11-07T05:31:56Z\",\n \"spans\": [\n {\n \"trace_id\": \"<string>\",\n \"span_id\": \"<string>\"\n }\n ],\n \"mapping\": {\n \"inputs\": {\n \"question\": \"gen_ai.request.user_message\"\n },\n \"expected_outputs\": {\n \"answer\": \"gen_ai.completion.content\"\n },\n \"metadata\": {\n \"trace_id\": \"trace.id\",\n \"model\": \"gen_ai.request.model\"\n },\n \"extras\": {\n \"context\": \"gen_ai.contents.context\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"api_version": "3.0",
"kind": "NORMAL",
"data": {
"items": [
{
"trace_id": "<string>",
"span_id": "<string>",
"item_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}{
"error": {
"code": 422,
"message": "One or more spans could not be resolved. No items were written.",
"errors": [
{
"reason": "SpanNotFound",
"message": "Span span-002-b (trace 4f9fa507) not found within the specified time range"
}
]
},
"api_version": "3.0",
"kind": "ERROR"
}{
"api_version": "3.0",
"kind": "ERROR",
"error": {
"code": 400,
"message": "Resource Not Found",
"errors": [
{
"reason": "ResourceNotFoundException",
"message": "Resource Not Found",
"help": "<string>"
}
]
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Dataset UUID
Body
UUID of the GenAI application to query spans from
Start of the time range (inclusive, UTC). Used to bound the ClickHouse partition scan to the relevant monthly partitions. Should match the time range of the spans being exported.
End of the time range (exclusive, UTC). Used to bound the ClickHouse partition scan to the relevant monthly partitions. Should match the time range of the spans being exported.
Explicit span references to resolve and write as dataset items. Maximum 200 per request.
1 - 200 elementsShow child attributes
Show child attributes
Maps dataset field keys to source span attribute paths. Each bucket contains { field_key: source_attr_path } pairs where source_attr_path is an OTel-convention key from the span's attributes.
Show child attributes
Show child attributes