curl --request PATCH \
--url https://api.galtea.ai/monitors/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"productId": "prod_123",
"versionId": "version_123",
"name": "Production quality watch",
"metricGroupIds": [
"metricGroup_123"
],
"specificationIds": [
"specification_123"
],
"samplingPercentage": 10,
"monthlyCreditCap": 500,
"filterQuery": "refund, cancel, chargeback",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"status": "ACTIVE"
}
'import requests
url = "https://api.galtea.ai/monitors/{id}"
payload = {
"productId": "prod_123",
"versionId": "version_123",
"name": "Production quality watch",
"metricGroupIds": ["metricGroup_123"],
"specificationIds": ["specification_123"],
"samplingPercentage": 10,
"monthlyCreditCap": 500,
"filterQuery": "refund, cancel, chargeback",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"status": "ACTIVE"
}
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({
productId: 'prod_123',
versionId: 'version_123',
name: 'Production quality watch',
metricGroupIds: ['metricGroup_123'],
specificationIds: ['specification_123'],
samplingPercentage: 10,
monthlyCreditCap: 500,
filterQuery: 'refund, cancel, chargeback',
filterTarget: 'EITHER',
excludeQuery: 'test, internal',
excludeTarget: 'EITHER',
messageConditions: [{count: 'messages', operator: 'gt', value: 1}],
status: 'ACTIVE'
})
};
fetch('https://api.galtea.ai/monitors/{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/monitors/{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([
'productId' => 'prod_123',
'versionId' => 'version_123',
'name' => 'Production quality watch',
'metricGroupIds' => [
'metricGroup_123'
],
'specificationIds' => [
'specification_123'
],
'samplingPercentage' => 10,
'monthlyCreditCap' => 500,
'filterQuery' => 'refund, cancel, chargeback',
'filterTarget' => 'EITHER',
'excludeQuery' => 'test, internal',
'excludeTarget' => 'EITHER',
'messageConditions' => [
[
'count' => 'messages',
'operator' => 'gt',
'value' => 1
]
],
'status' => 'ACTIVE'
]),
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/monitors/{id}"
payload := strings.NewReader("{\n \"productId\": \"prod_123\",\n \"versionId\": \"version_123\",\n \"name\": \"Production quality watch\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ],\n \"samplingPercentage\": 10,\n \"monthlyCreditCap\": 500,\n \"filterQuery\": \"refund, cancel, chargeback\",\n \"filterTarget\": \"EITHER\",\n \"excludeQuery\": \"test, internal\",\n \"excludeTarget\": \"EITHER\",\n \"messageConditions\": [\n {\n \"count\": \"messages\",\n \"operator\": \"gt\",\n \"value\": 1\n }\n ],\n \"status\": \"ACTIVE\"\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/monitors/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"productId\": \"prod_123\",\n \"versionId\": \"version_123\",\n \"name\": \"Production quality watch\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ],\n \"samplingPercentage\": 10,\n \"monthlyCreditCap\": 500,\n \"filterQuery\": \"refund, cancel, chargeback\",\n \"filterTarget\": \"EITHER\",\n \"excludeQuery\": \"test, internal\",\n \"excludeTarget\": \"EITHER\",\n \"messageConditions\": [\n {\n \"count\": \"messages\",\n \"operator\": \"gt\",\n \"value\": 1\n }\n ],\n \"status\": \"ACTIVE\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/monitors/{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 \"productId\": \"prod_123\",\n \"versionId\": \"version_123\",\n \"name\": \"Production quality watch\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ],\n \"samplingPercentage\": 10,\n \"monthlyCreditCap\": 500,\n \"filterQuery\": \"refund, cancel, chargeback\",\n \"filterTarget\": \"EITHER\",\n \"excludeQuery\": \"test, internal\",\n \"excludeTarget\": \"EITHER\",\n \"messageConditions\": [\n {\n \"count\": \"messages\",\n \"operator\": \"gt\",\n \"value\": 1\n }\n ],\n \"status\": \"ACTIVE\"\n}"
response = http.request(request)
puts response.read_body{
"id": "monitor_123",
"productId": "prod_123",
"versionId": "version_123",
"userId": "user_123",
"name": "Production quality watch",
"metricGroupIds": [
"metricGroup_123"
],
"specificationIds": [
"specification_123"
],
"scoredMetricGroupIds": [
"metricGroup_123"
],
"specificationIdsByMetricGroupId": {
"metricGroup_123": [
"specification_123"
]
},
"samplingPercentage": 10,
"monthlyCreditCap": 500,
"filterQuery": "refund, cancel, chargeback",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"status": "ACTIVE",
"families": [
{
"metricGroupId": "metricGroup_123",
"name": "Answer relevancy",
"state": "ACTIVE",
"metricId": "metric_123"
}
],
"createdAt": "2023-11-07T05:31:56Z",
"deletedAt": "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"
}{
"error": "Error type",
"message": "Error message description"
}Update monitor
Update an existing monitor. Setting status to PAUSED or ACTIVE here still works; pause or resume with POST /monitors//pause and /monitors//resume instead. A list you send replaces the stored one: metricGroupIds the picked families, specificationIds the bound Specifications. See Monitors.
curl --request PATCH \
--url https://api.galtea.ai/monitors/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"productId": "prod_123",
"versionId": "version_123",
"name": "Production quality watch",
"metricGroupIds": [
"metricGroup_123"
],
"specificationIds": [
"specification_123"
],
"samplingPercentage": 10,
"monthlyCreditCap": 500,
"filterQuery": "refund, cancel, chargeback",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"status": "ACTIVE"
}
'import requests
url = "https://api.galtea.ai/monitors/{id}"
payload = {
"productId": "prod_123",
"versionId": "version_123",
"name": "Production quality watch",
"metricGroupIds": ["metricGroup_123"],
"specificationIds": ["specification_123"],
"samplingPercentage": 10,
"monthlyCreditCap": 500,
"filterQuery": "refund, cancel, chargeback",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"status": "ACTIVE"
}
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({
productId: 'prod_123',
versionId: 'version_123',
name: 'Production quality watch',
metricGroupIds: ['metricGroup_123'],
specificationIds: ['specification_123'],
samplingPercentage: 10,
monthlyCreditCap: 500,
filterQuery: 'refund, cancel, chargeback',
filterTarget: 'EITHER',
excludeQuery: 'test, internal',
excludeTarget: 'EITHER',
messageConditions: [{count: 'messages', operator: 'gt', value: 1}],
status: 'ACTIVE'
})
};
fetch('https://api.galtea.ai/monitors/{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/monitors/{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([
'productId' => 'prod_123',
'versionId' => 'version_123',
'name' => 'Production quality watch',
'metricGroupIds' => [
'metricGroup_123'
],
'specificationIds' => [
'specification_123'
],
'samplingPercentage' => 10,
'monthlyCreditCap' => 500,
'filterQuery' => 'refund, cancel, chargeback',
'filterTarget' => 'EITHER',
'excludeQuery' => 'test, internal',
'excludeTarget' => 'EITHER',
'messageConditions' => [
[
'count' => 'messages',
'operator' => 'gt',
'value' => 1
]
],
'status' => 'ACTIVE'
]),
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/monitors/{id}"
payload := strings.NewReader("{\n \"productId\": \"prod_123\",\n \"versionId\": \"version_123\",\n \"name\": \"Production quality watch\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ],\n \"samplingPercentage\": 10,\n \"monthlyCreditCap\": 500,\n \"filterQuery\": \"refund, cancel, chargeback\",\n \"filterTarget\": \"EITHER\",\n \"excludeQuery\": \"test, internal\",\n \"excludeTarget\": \"EITHER\",\n \"messageConditions\": [\n {\n \"count\": \"messages\",\n \"operator\": \"gt\",\n \"value\": 1\n }\n ],\n \"status\": \"ACTIVE\"\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/monitors/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"productId\": \"prod_123\",\n \"versionId\": \"version_123\",\n \"name\": \"Production quality watch\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ],\n \"samplingPercentage\": 10,\n \"monthlyCreditCap\": 500,\n \"filterQuery\": \"refund, cancel, chargeback\",\n \"filterTarget\": \"EITHER\",\n \"excludeQuery\": \"test, internal\",\n \"excludeTarget\": \"EITHER\",\n \"messageConditions\": [\n {\n \"count\": \"messages\",\n \"operator\": \"gt\",\n \"value\": 1\n }\n ],\n \"status\": \"ACTIVE\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/monitors/{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 \"productId\": \"prod_123\",\n \"versionId\": \"version_123\",\n \"name\": \"Production quality watch\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ],\n \"samplingPercentage\": 10,\n \"monthlyCreditCap\": 500,\n \"filterQuery\": \"refund, cancel, chargeback\",\n \"filterTarget\": \"EITHER\",\n \"excludeQuery\": \"test, internal\",\n \"excludeTarget\": \"EITHER\",\n \"messageConditions\": [\n {\n \"count\": \"messages\",\n \"operator\": \"gt\",\n \"value\": 1\n }\n ],\n \"status\": \"ACTIVE\"\n}"
response = http.request(request)
puts response.read_body{
"id": "monitor_123",
"productId": "prod_123",
"versionId": "version_123",
"userId": "user_123",
"name": "Production quality watch",
"metricGroupIds": [
"metricGroup_123"
],
"specificationIds": [
"specification_123"
],
"scoredMetricGroupIds": [
"metricGroup_123"
],
"specificationIdsByMetricGroupId": {
"metricGroup_123": [
"specification_123"
]
},
"samplingPercentage": 10,
"monthlyCreditCap": 500,
"filterQuery": "refund, cancel, chargeback",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"status": "ACTIVE",
"families": [
{
"metricGroupId": "metricGroup_123",
"name": "Answer relevancy",
"state": "ACTIVE",
"metricId": "metric_123"
}
],
"createdAt": "2023-11-07T05:31:56Z",
"deletedAt": "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"
}{
"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
Monitor ID
"monitor_123"
Body
Immutable. Answers 400 when it differs from the monitor product.
"prod_123"
Optional version to narrow the monitor to. When null the monitor watches the whole product.
"version_123"
"Production quality watch"
The metric families (Metric.metricGroupId) picked directly on the monitor. The list may be empty when specificationIds is set. The families the monitor scores are in scoredMetricGroupIds. The monitor binds the family, not a specific revision, so revising a metric is picked up automatically without editing the monitor.
["metricGroup_123"]
The Specifications (Specification.id) bound to the monitor. The monitor also scores the metrics each one links, so a metric added to or removed from a Specification takes effect on the next scan. Only Policy and Capability Specifications can be bound. The update must leave the monitor with at least one family or Specification.
["specification_123"]
Percentage of production sessions to evaluate (greater than 0, at most 100).
0 < x <= 10010
Optional monthly credit ceiling for this monitor. When set it must be a positive integer; it may exceed the organization monthly allocation (spend is clamped to the available balance). Null means uncapped.
x >= 1500
Optional content gate. Comma-separated terms; a session matches when at least one turn whose chosen target (filterTarget) contains ANY term (case-insensitive). Only matching sessions are sampled and evaluated; other sessions are skipped, spending no credits. Max 500 chars. Must be set together with filterTarget. Null means no content gate: every session that meets messageConditions is sampled.
500"refund, cancel, chargeback"
Which side of a turn filterQuery is matched against: INPUT (the user turn), OUTPUT (the agent turn), or EITHER. Must be set together with filterQuery.
INPUT, OUTPUT, EITHER, null "EITHER"
Optional exclude gate. Comma-separated terms; a session is dropped when at least one turn whose chosen target (excludeTarget) contains ANY term (case-insensitive). Applied on top of filterQuery: a session passes the content gate only when it passes filterQuery (if set) AND is not hit by excludeQuery. Max 500 chars. Must be set together with excludeTarget. Null means exclude nothing.
500"test, internal"
Which side of a turn excludeQuery is matched against: INPUT (the user turn), OUTPUT (the agent turn), or EITHER. Must be set together with excludeQuery.
INPUT, OUTPUT, EITHER, null "EITHER"
Conditions on the number of messages in a session, joined by AND: the monitor scores a session only when every condition holds. Sessions that fail are skipped and spend no credits. An empty list turns the filter off. A list no session can meet is refused, such as messages above 5 with messages at most 3, or more user messages than the messages allow: messages counts the user messages too. The list replaces the stored one. Send [] to turn the filter off; null is refused.
10Show child attributes
Show child attributes
[
{
"count": "messages",
"operator": "gt",
"value": 1
}
]
Users may set ACTIVE or PAUSED; CAPPED and NO_CREDITS are system-set by the scanner, FAILING is reserved and never set yet, and all three are rejected on user writes.
ACTIVE, PAUSED, CAPPED, NO_CREDITS, FAILING "ACTIVE"
Response
Monitor updated successfully. The body holds only the monitor id when the read after the write fails; read the monitor by that id.
- Option 1
- Option 2
"monitor_123"
"prod_123"
Optional version to narrow the monitor to. When null the monitor watches the whole product.
"version_123"
"user_123"
"Production quality watch"
The metric families (Metric.metricGroupId) picked directly on the monitor. The list may be empty when specificationIds is set. The families the monitor scores are in scoredMetricGroupIds. The monitor binds the family, not a specific revision, so revising a metric is picked up automatically without editing the monitor.
["metricGroup_123"]
The Specifications (Specification.id) bound to the monitor. The monitor also scores the metrics each one links, so a metric added to or removed from a Specification takes effect on the next scan. Only Policy and Capability Specifications can be bound.
["specification_123"]
Read-only. The metric families the monitor scores: metricGroupIds plus the families of its bound Specifications that can score production sessions.
["metricGroup_123"]
Read-only. For each family a bound Specification brings, the ids of the bound Specifications that bring it.
Show child attributes
Show child attributes
{ "metricGroup_123": ["specification_123"] }
Percentage of production sessions to evaluate (greater than 0, at most 100).
0 < x <= 10010
Optional monthly credit ceiling for this monitor. When set it must be a positive integer; it may exceed the organization monthly allocation (spend is clamped to the available balance). Null means uncapped.
x >= 1500
Optional content gate. Comma-separated terms; a session matches when at least one turn whose chosen target (filterTarget) contains ANY term (case-insensitive). Only matching sessions are sampled and evaluated; other sessions are skipped, spending no credits. Max 500 chars. Must be set together with filterTarget. Null means no content gate: every session that meets messageConditions is sampled.
500"refund, cancel, chargeback"
Which side of a turn filterQuery is matched against: INPUT (the user turn), OUTPUT (the agent turn), or EITHER. Must be set together with filterQuery.
INPUT, OUTPUT, EITHER, null "EITHER"
Optional exclude gate. Comma-separated terms; a session is dropped when at least one turn whose chosen target (excludeTarget) contains ANY term (case-insensitive). Applied on top of filterQuery: a session passes the content gate only when it passes filterQuery (if set) AND is not hit by excludeQuery. Max 500 chars. Must be set together with excludeTarget. Null means exclude nothing.
500"test, internal"
Which side of a turn excludeQuery is matched against: INPUT (the user turn), OUTPUT (the agent turn), or EITHER. Must be set together with excludeQuery.
INPUT, OUTPUT, EITHER, null "EITHER"
Conditions on the number of messages in a session, joined by AND: the monitor scores a session only when every condition holds. Sessions that fail are skipped and spend no credits. An empty list turns the filter off.
10Show child attributes
Show child attributes
[
{
"count": "messages",
"operator": "gt",
"value": 1
}
]
Users may set ACTIVE or PAUSED; CAPPED and NO_CREDITS are system-set by the scanner, FAILING is reserved and never set yet, and all three are rejected on user writes.
ACTIVE, PAUSED, CAPPED, NO_CREDITS, FAILING "ACTIVE"
Read-only. Every family in scoredMetricGroupIds with its state, so a family that no longer scores stays visible and can be removed.
Show child attributes
Show child attributes