curl --request POST \
--url https://api.galtea.ai/metrics/{id}/optimize \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.galtea.ai/metrics/{id}/optimize"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.galtea.ai/metrics/{id}/optimize', 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}/optimize",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.galtea.ai/metrics/{id}/optimize"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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/metrics/{id}/optimize")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/metrics/{id}/optimize")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
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,
"specificationIds": [
"spec_123"
],
"userGroupIds": [
"ug_123"
],
"createdAt": "2023-11-07T05:31:56Z",
"legacyAt": "2023-11-07T05:31:56Z",
"disabledAt": "2023-11-07T05:31:56Z"
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}{
"error": "Error type",
"message": "Error message description"
}Optimize metric
Creates an optimized copy of a metric by sending its human-annotated evaluations to the metrics-generator service, which uses the gap between AI and human scores to produce a better judge prompt. Only FULL_PROMPT and PARTIAL_PROMPT metrics owned by an organization can be optimized. Rejected with 400 unless the metric has at least minAnnotations evaluations annotated by a human AND minDisagreements of those disagree with the AI score; both thresholds are returned by GET /metrics/{id}/human-annotation-count (defaults 10 and 5, configurable via the OPTIMIZE_MIN_ANNOTATIONS_HARD / OPTIMIZE_MIN_DISAGREEMENTS_HARD env vars). 30+ annotations recommended for best optimizer signal. Returns a placeholder metric with isBeingOptimized=true. See Metrics.
curl --request POST \
--url https://api.galtea.ai/metrics/{id}/optimize \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.galtea.ai/metrics/{id}/optimize"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.galtea.ai/metrics/{id}/optimize', 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}/optimize",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.galtea.ai/metrics/{id}/optimize"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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/metrics/{id}/optimize")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/metrics/{id}/optimize")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
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,
"specificationIds": [
"spec_123"
],
"userGroupIds": [
"ug_123"
],
"createdAt": "2023-11-07T05:31:56Z",
"legacyAt": "2023-11-07T05:31:56Z",
"disabledAt": "2023-11-07T05:31:56Z"
}{
"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-....
Path Parameters
Source Metric ID
Response
Optimized metric placeholder created successfully
"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.
SELF_HOSTED, FULL_PROMPT, PARTIAL_PROMPT, HUMAN_EVALUATION, GEVAL, DEEPEVAL, DETERMINISTIC "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.
["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.