curl --request PATCH \
--url https://api.galtea.ai/metrics/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Accuracy",
"description": "Measures the accuracy of responses",
"tags": [
"accuracy",
"quality"
],
"userGroupIds": [
"group_123"
],
"specificationIds": [
"spec_123",
"spec_456"
]
}
'import requests
url = "https://api.galtea.ai/metrics/{id}"
payload = {
"name": "Accuracy",
"description": "Measures the accuracy of responses",
"tags": ["accuracy", "quality"],
"userGroupIds": ["group_123"],
"specificationIds": ["spec_123", "spec_456"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Accuracy',
description: 'Measures the accuracy of responses',
tags: ['accuracy', 'quality'],
userGroupIds: ['group_123'],
specificationIds: ['spec_123', 'spec_456']
})
};
fetch('https://api.galtea.ai/metrics/{id}', 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/metrics/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Accuracy',
'description' => 'Measures the accuracy of responses',
'tags' => [
'accuracy',
'quality'
],
'userGroupIds' => [
'group_123'
],
'specificationIds' => [
'spec_123',
'spec_456'
]
]),
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/metrics/{id}"
payload := strings.NewReader("{\n \"name\": \"Accuracy\",\n \"description\": \"Measures the accuracy of responses\",\n \"tags\": [\n \"accuracy\",\n \"quality\"\n ],\n \"userGroupIds\": [\n \"group_123\"\n ],\n \"specificationIds\": [\n \"spec_123\",\n \"spec_456\"\n ]\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.galtea.ai/metrics/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Accuracy\",\n \"description\": \"Measures the accuracy of responses\",\n \"tags\": [\n \"accuracy\",\n \"quality\"\n ],\n \"userGroupIds\": [\n \"group_123\"\n ],\n \"specificationIds\": [\n \"spec_123\",\n \"spec_456\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/metrics/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Accuracy\",\n \"description\": \"Measures the accuracy of responses\",\n \"tags\": [\n \"accuracy\",\n \"quality\"\n ],\n \"userGroupIds\": [\n \"group_123\"\n ],\n \"specificationIds\": [\n \"spec_123\",\n \"spec_456\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "metric_123",
"metricGroupId": "metric_123",
"parentMetricId": "metric_122",
"organizationId": "org_123",
"userId": "user_123",
"name": "Accuracy",
"evaluationParams": [
"input",
"actual_output",
"expected_output"
],
"source": "PARTIAL_PROMPT",
"judgePrompt": "Evaluate the accuracy of the response",
"tags": [
"accuracy",
"quality"
],
"description": "Measures the accuracy of responses",
"documentationUrl": "https://docs.example.com/metrics/accuracy",
"evaluatorModelName": "gpt-4",
"areEvalParamsTop": true,
"isBeingOptimized": true,
"optimizationStatus": "READY_FOR_REVIEW",
"judgeGenerationSettings": {
"temperature": 0.3,
"topP": 0.9,
"maxOutputTokens": 512,
"reasoningEffort": "low"
},
"passThreshold": 0.7,
"applicabilityScope": "PRODUCTION",
"applicabilityThreshold": 0.7,
"classifierQuestion": {
"type": "yes_no",
"instructions": "<string>",
"goodAnswer": "yes",
"criteria": {
"yes": "<string>",
"no": "<string>"
},
"levels": [
{
"description": "<string>",
"score": 123
}
],
"doesNotApply": "<string>"
},
"optimizationValidation": {
"used": true,
"heldOutEvaluationIds": [
"evaluation_123"
],
"results": {
"optimization": {
"rowsScored": 25,
"rowsTotal": 25,
"source": {
"correct": 20,
"alignment": 0.71
},
"candidate": {
"correct": 20,
"alignment": 0.71
}
},
"validation": {
"rowsScored": 25,
"rowsTotal": 25,
"source": {
"correct": 20,
"alignment": 0.71
},
"candidate": {
"correct": 20,
"alignment": 0.71
}
}
},
"rows": [
{
"evaluationId": "evaluation_123",
"humanScore": 1,
"sourceScore": 0,
"candidateScore": 1
}
]
},
"optimizationRun": {
"strategies": [
"ADD_RUBRIC",
"SIMPLIFY"
],
"maxSteps": 6,
"stepsUsed": 4
},
"specificationIds": [
"spec_123"
],
"userGroupIds": [
"ug_123"
],
"createdAt": "2023-11-07T05:31:56Z",
"legacyAt": "2023-11-07T05:31:56Z",
"disabledAt": "2023-11-07T05:31:56Z",
"excludedFromAnalyticsAt": "2023-11-07T05:31:56Z",
"excludedByUserId": "<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"
}Update metric
Update an existing metric. See Metrics.
specificationIds sets the full list of specifications the metric is linked to: a link missing from the list is removed, so [] removes every link, and leaving the field out keeps the links as they are. Only POLICY and CAPABILITY specifications of the metric’s organization can be linked. Every changed specification is checked before anything is written. A Galtea default metric is updated only by a platform admin, and its list covers only the links of the admin’s organization. To link a Galtea default metric to a specification of your organization, use specifications link-metrics. A caller limited to the products its user groups grant replaces only the links to specifications of those products.
curl --request PATCH \
--url https://api.galtea.ai/metrics/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Accuracy",
"description": "Measures the accuracy of responses",
"tags": [
"accuracy",
"quality"
],
"userGroupIds": [
"group_123"
],
"specificationIds": [
"spec_123",
"spec_456"
]
}
'import requests
url = "https://api.galtea.ai/metrics/{id}"
payload = {
"name": "Accuracy",
"description": "Measures the accuracy of responses",
"tags": ["accuracy", "quality"],
"userGroupIds": ["group_123"],
"specificationIds": ["spec_123", "spec_456"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Accuracy',
description: 'Measures the accuracy of responses',
tags: ['accuracy', 'quality'],
userGroupIds: ['group_123'],
specificationIds: ['spec_123', 'spec_456']
})
};
fetch('https://api.galtea.ai/metrics/{id}', 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/metrics/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Accuracy',
'description' => 'Measures the accuracy of responses',
'tags' => [
'accuracy',
'quality'
],
'userGroupIds' => [
'group_123'
],
'specificationIds' => [
'spec_123',
'spec_456'
]
]),
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/metrics/{id}"
payload := strings.NewReader("{\n \"name\": \"Accuracy\",\n \"description\": \"Measures the accuracy of responses\",\n \"tags\": [\n \"accuracy\",\n \"quality\"\n ],\n \"userGroupIds\": [\n \"group_123\"\n ],\n \"specificationIds\": [\n \"spec_123\",\n \"spec_456\"\n ]\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.galtea.ai/metrics/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Accuracy\",\n \"description\": \"Measures the accuracy of responses\",\n \"tags\": [\n \"accuracy\",\n \"quality\"\n ],\n \"userGroupIds\": [\n \"group_123\"\n ],\n \"specificationIds\": [\n \"spec_123\",\n \"spec_456\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/metrics/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Accuracy\",\n \"description\": \"Measures the accuracy of responses\",\n \"tags\": [\n \"accuracy\",\n \"quality\"\n ],\n \"userGroupIds\": [\n \"group_123\"\n ],\n \"specificationIds\": [\n \"spec_123\",\n \"spec_456\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "metric_123",
"metricGroupId": "metric_123",
"parentMetricId": "metric_122",
"organizationId": "org_123",
"userId": "user_123",
"name": "Accuracy",
"evaluationParams": [
"input",
"actual_output",
"expected_output"
],
"source": "PARTIAL_PROMPT",
"judgePrompt": "Evaluate the accuracy of the response",
"tags": [
"accuracy",
"quality"
],
"description": "Measures the accuracy of responses",
"documentationUrl": "https://docs.example.com/metrics/accuracy",
"evaluatorModelName": "gpt-4",
"areEvalParamsTop": true,
"isBeingOptimized": true,
"optimizationStatus": "READY_FOR_REVIEW",
"judgeGenerationSettings": {
"temperature": 0.3,
"topP": 0.9,
"maxOutputTokens": 512,
"reasoningEffort": "low"
},
"passThreshold": 0.7,
"applicabilityScope": "PRODUCTION",
"applicabilityThreshold": 0.7,
"classifierQuestion": {
"type": "yes_no",
"instructions": "<string>",
"goodAnswer": "yes",
"criteria": {
"yes": "<string>",
"no": "<string>"
},
"levels": [
{
"description": "<string>",
"score": 123
}
],
"doesNotApply": "<string>"
},
"optimizationValidation": {
"used": true,
"heldOutEvaluationIds": [
"evaluation_123"
],
"results": {
"optimization": {
"rowsScored": 25,
"rowsTotal": 25,
"source": {
"correct": 20,
"alignment": 0.71
},
"candidate": {
"correct": 20,
"alignment": 0.71
}
},
"validation": {
"rowsScored": 25,
"rowsTotal": 25,
"source": {
"correct": 20,
"alignment": 0.71
},
"candidate": {
"correct": 20,
"alignment": 0.71
}
}
},
"rows": [
{
"evaluationId": "evaluation_123",
"humanScore": 1,
"sourceScore": 0,
"candidateScore": 1
}
]
},
"optimizationRun": {
"strategies": [
"ADD_RUBRIC",
"SIMPLIFY"
],
"maxSteps": 6,
"stepsUsed": 4
},
"specificationIds": [
"spec_123"
],
"userGroupIds": [
"ug_123"
],
"createdAt": "2023-11-07T05:31:56Z",
"legacyAt": "2023-11-07T05:31:56Z",
"disabledAt": "2023-11-07T05:31:56Z",
"excludedFromAnalyticsAt": "2023-11-07T05:31:56Z",
"excludedByUserId": "<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-....
Headers
Send return=minimal to get no body back from a write and skip reading the resource: a create answers 201 with only Location, and an update answers 204.
"return=minimal"
Path Parameters
Metric ID
"metric_123"
Body
"Accuracy"
"Measures the accuracy of responses"
["accuracy", "quality"]
The full list of user groups the metric is linked to. A group missing from the list is unlinked. Leave the field out to keep the groups as they are. Removing the last group of a Human Evaluation metric answers 400.
1["group_123"]
The full list of POLICY or CAPABILITY specifications the metric is linked to. A link missing from the list is removed, so [] removes every link. Leave the field out to keep the links as they are. A specification must belong to the metric's organization. A Galtea default metric is updated only by a platform admin: its list covers only the links of the admin's organization, and links that other organizations own are left as they are.
1["spec_123", "spec_456"]
Response
Metric updated successfully. The body is the resource as its GET answers it.
"metric_123"
Identifier shared by every metric in the same revision family. Server-managed — derived from parentMetricId on create (or generated for roots). Cannot be set by the caller.
"metric_123"
Id of the direct parent metric. On create, providing this value turns the new metric into a revision: it joins the parent's family and (if the parent is active) flips the parent to legacy. Omit or null to create a root metric in a fresh group. On responses, this is the recorded parent edge (null for roots).
"metric_122"
"org_123"
"user_123"
"Accuracy"
Ordered list of trace fields the evaluator needs, written in snake_case (e.g. input, actual_output, expected_output, retrieval_context). Determines which data the evaluation engine extracts from each trace. Full list of accepted values: https://docs.galtea.ai/concepts/metric/evaluation-parameters
["input", "actual_output", "expected_output"]
Evaluation method for the metric. FULL_PROMPT is deprecated for creation — POST /metrics rejects it with a 400. Use PARTIAL_PROMPT for new AI Evaluation metrics. The value remains in the enum because existing FULL_PROMPT metrics are still returned by reads and filters. CLASSIFIER is the Classifier judge, accepted only where the deployment enables it.
SELF_HOSTED, FULL_PROMPT, PARTIAL_PROMPT, HUMAN_EVALUATION, GEVAL, DEEPEVAL, DETERMINISTIC, CLASSIFIER "PARTIAL_PROMPT"
"Evaluate the accuracy of the response"
["accuracy", "quality"]
"Measures the accuracy of responses"
"https://docs.example.com/metrics/accuracy"
"gpt-4"
When true, evaluationParams are injected at the top level of the evaluator prompt instead of nested inside the conversation context.
Whether the metric is currently being optimized.
Where an optimization attempt stands. Null for a metric that did not come from an optimization. A candidate waiting for review is legacy until it is activated.
OPTIMIZING, READY_FOR_REVIEW, FAILED, NO_IMPROVEMENT, DECLINED, ACTIVATED "READY_FOR_REVIEW"
The generation settings this metric's judge runs with. Null runs the platform defaults. Immutable: changing one creates a revision.
Show child attributes
Show child attributes
Score from 0 to 1 at or above which an evaluation of this metric passes. Immutable: changing it creates a revision.
0 <= x <= 10.7
Which sessions get the applicability check before this metric is judged. NONE for a metric the platform does not score. A metric that scores traces is never checked, so it takes NONE and refuses any other value. A FULL_PROMPT metric whose judge prompt reads traces but does not list it in evaluationParams is stored as checked, yet the evaluator judges it without the check. Immutable: changing it creates a revision. The check runs only where the deployment enables it.
NONE, DEVELOPMENT, PRODUCTION, ALL "PRODUCTION"
The lowest probability that the metric applies to a session at which it is judged. Null means the platform default, 0.5. Immutable: changing it creates a revision.
0 <= x <= 10.7
The one question of a CLASSIFIER metric; null for every other source.
Show child attributes
Show child attributes
How an optimization attempt was validated: the held-out evaluations and, once the optimizer reported, both prompts scored on the search rows and on the held-out rows. Set on an optimization attempt only, and null for any other metric, for an attempt that predates it, and for an attempt copied from another organization.
Show child attributes
Show child attributes
What an optimization attempt ran: the strategies, the step budget and the steps used. Null while the attempt runs, and when it was not reported: an attempt from before the report existed, one run by an older optimizer, a failed run, an attempt copied from another organization, or a metric that is not an optimization attempt. Null never means a run of 0 steps.
Show child attributes
Show child attributes
Specifications linked to this metric. A MEMBER, READER or HUMAN_EVALUATOR caller sees only the specifications of the products it can read.
["spec_123"]
["ug_123"]
Earliest non-null of this metric's own legacy date and its evaluator model's unselectableAt, so a model no longer selectable makes every metric linked to it report as legacy even though the metric row itself is untouched. Present only once that date has passed: a scheduled future cutoff reports null, because the metric is still active until then. Unlike disabledAt, this field never carries a future date.
Earliest non-null of this metric's own disabled date and its evaluator model's disabledAt — a disabled model makes every metric linked to it report as disabled even though the metric row itself is untouched.
When set, results produced by this metric revision do not feed analytics.
User who last excluded this metric revision from analytics.