curl --request POST \
--url https://api.galtea.ai/evaluations/fromSessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"sessionIds": [
"ses_123",
"ses_456"
],
"versionId": "ver_123",
"metrics": [
{
"id": "id_123",
"name": "Example Name",
"score": 0.95
}
],
"specificationIds": [
"<string>"
]
}
'import requests
url = "https://api.galtea.ai/evaluations/fromSessions"
payload = {
"sessionIds": ["ses_123", "ses_456"],
"versionId": "ver_123",
"metrics": [
{
"id": "id_123",
"name": "Example Name",
"score": 0.95
}
],
"specificationIds": ["<string>"]
}
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({
sessionIds: ['ses_123', 'ses_456'],
versionId: 'ver_123',
metrics: [{id: 'id_123', name: 'Example Name', score: 0.95}],
specificationIds: ['<string>']
})
};
fetch('https://api.galtea.ai/evaluations/fromSessions', 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.galtea.ai/evaluations/fromSessions",
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([
'sessionIds' => [
'ses_123',
'ses_456'
],
'versionId' => 'ver_123',
'metrics' => [
[
'id' => 'id_123',
'name' => 'Example Name',
'score' => 0.95
]
],
'specificationIds' => [
'<string>'
]
]),
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.galtea.ai/evaluations/fromSessions"
payload := strings.NewReader("{\n \"sessionIds\": [\n \"ses_123\",\n \"ses_456\"\n ],\n \"versionId\": \"ver_123\",\n \"metrics\": [\n {\n \"id\": \"id_123\",\n \"name\": \"Example Name\",\n \"score\": 0.95\n }\n ],\n \"specificationIds\": [\n \"<string>\"\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.galtea.ai/evaluations/fromSessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sessionIds\": [\n \"ses_123\",\n \"ses_456\"\n ],\n \"versionId\": \"ver_123\",\n \"metrics\": [\n {\n \"id\": \"id_123\",\n \"name\": \"Example Name\",\n \"score\": 0.95\n }\n ],\n \"specificationIds\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/evaluations/fromSessions")
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 \"sessionIds\": [\n \"ses_123\",\n \"ses_456\"\n ],\n \"versionId\": \"ver_123\",\n \"metrics\": [\n {\n \"id\": \"id_123\",\n \"name\": \"Example Name\",\n \"score\": 0.95\n }\n ],\n \"specificationIds\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"sessionsEvaluated": 123,
"sessionsFailed": 123,
"evaluationsCreated": 123,
"failures": [
{
"sessionId": "<string>",
"error": "<string>"
}
],
"message": "<string>",
"totalSessionsAvailable": 123,
"truncated": true,
"runIds": [
"<string>"
]
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}Evaluate multiple sessions in one call
Batch-evaluate existing sessions in a single call. Pick exactly one mode: (a) sessionIds — explicit list of session IDs; (b) versionId — every session attached to that version. Each selected session is evaluated by the same logic as POST /evaluations/fromSession, so the traces that already live on the session are scored. Unlike POST /evaluations/fromVersion, this endpoint does NOT require a conversation endpoint connection on the version — use it when the traces already exist (e.g. imported ones). Metric scope: if you send metrics, they are applied to every session. If you do not send metrics, each session is scored only by the metrics of its own originating specification (the spec that produced its test case), never the union of all the product’s metrics. A session with no spec of its own (for example an imported one) is scored with the metrics of every spec of its product. When you send specificationIds, a session whose own spec is in the list is scored with that spec’s metrics, and a session whose own spec is not in the list is skipped. A session with no spec of its own is then scored with the metrics of the listed specs of its own product, each metric once, and is skipped when there are none. Skipped sessions are reported in message. Use POST /evaluations/fromSession for a single session. See Evaluations.
curl --request POST \
--url https://api.galtea.ai/evaluations/fromSessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"sessionIds": [
"ses_123",
"ses_456"
],
"versionId": "ver_123",
"metrics": [
{
"id": "id_123",
"name": "Example Name",
"score": 0.95
}
],
"specificationIds": [
"<string>"
]
}
'import requests
url = "https://api.galtea.ai/evaluations/fromSessions"
payload = {
"sessionIds": ["ses_123", "ses_456"],
"versionId": "ver_123",
"metrics": [
{
"id": "id_123",
"name": "Example Name",
"score": 0.95
}
],
"specificationIds": ["<string>"]
}
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({
sessionIds: ['ses_123', 'ses_456'],
versionId: 'ver_123',
metrics: [{id: 'id_123', name: 'Example Name', score: 0.95}],
specificationIds: ['<string>']
})
};
fetch('https://api.galtea.ai/evaluations/fromSessions', 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.galtea.ai/evaluations/fromSessions",
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([
'sessionIds' => [
'ses_123',
'ses_456'
],
'versionId' => 'ver_123',
'metrics' => [
[
'id' => 'id_123',
'name' => 'Example Name',
'score' => 0.95
]
],
'specificationIds' => [
'<string>'
]
]),
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.galtea.ai/evaluations/fromSessions"
payload := strings.NewReader("{\n \"sessionIds\": [\n \"ses_123\",\n \"ses_456\"\n ],\n \"versionId\": \"ver_123\",\n \"metrics\": [\n {\n \"id\": \"id_123\",\n \"name\": \"Example Name\",\n \"score\": 0.95\n }\n ],\n \"specificationIds\": [\n \"<string>\"\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.galtea.ai/evaluations/fromSessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sessionIds\": [\n \"ses_123\",\n \"ses_456\"\n ],\n \"versionId\": \"ver_123\",\n \"metrics\": [\n {\n \"id\": \"id_123\",\n \"name\": \"Example Name\",\n \"score\": 0.95\n }\n ],\n \"specificationIds\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/evaluations/fromSessions")
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 \"sessionIds\": [\n \"ses_123\",\n \"ses_456\"\n ],\n \"versionId\": \"ver_123\",\n \"metrics\": [\n {\n \"id\": \"id_123\",\n \"name\": \"Example Name\",\n \"score\": 0.95\n }\n ],\n \"specificationIds\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"sessionsEvaluated": 123,
"sessionsFailed": 123,
"evaluationsCreated": 123,
"failures": [
{
"sessionId": "<string>",
"error": "<string>"
}
],
"message": "<string>",
"totalSessionsAvailable": 123,
"truncated": true,
"runIds": [
"<string>"
]
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}Authorizations
API key authorization. Pass your API key in the Authorization header as a Bearer token. Both new (gsk_*) and legacy (gsk-) API keys are accepted, e.g. Authorization: Bearer gsk_... or Authorization: Bearer gsk-....
Body
Explicit list of session IDs to evaluate. Mutually exclusive with versionId.
["ses_123", "ses_456"]
Evaluate every session attached to this version. Mutually exclusive with sessionIds.
"ver_123"
Metrics to evaluate. When provided, these exact metrics are applied to every session and per-specification scoping is bypassed. Optional: if omitted, each session is scored by the metrics of its own originating specification.
Show child attributes
Show child attributes
Specification IDs used to scope evaluation. If metrics is omitted, a session whose own specification is in the list is evaluated with that specification's linked metrics, and a session whose own specification is not in the list is skipped. A session with no specification of its own (for example an imported one) is evaluated with the linked metrics of the listed specifications of its own product, each metric once, and is skipped when there are none. If metrics is also provided, the explicit metrics apply to every session and these specs' metrics are merged in (additive), with no per-session scoping.
Response
Batch evaluation processed
Number of sessions whose evaluations were dispatched successfully. Sessions skipped during per-specification scoping are counted in neither this nor sessionsFailed.
Number of sessions whose evaluation failed.
Total number of Evaluation records created across all successful sessions.
Per-session failure details.
Show child attributes
Show child attributes
Human-readable summary. Reports how many sessions were evaluated, failed, and skipped during per-specification scoping, naming each skip cause with its own count and reason, plus any truncation note.
Total sessions matching the request (versionId mode only). When greater than the count actually evaluated the response was truncated to the first 1000 rows. null in sessionIds mode.
True when the version had more sessions than the per-request page limit (1000).
The runs this launch is attributed to, one per product the sessions belong to.