curl --request POST \
--url https://api.galtea.ai/monitors/preview \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"productId": "prod_123",
"samplingPercentage": 10,
"versionId": "version_123",
"filterQuery": "refund",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"days": 90,
"monitorId": "monitor_123",
"metricGroupIds": [
"metricGroup_123"
],
"specificationIds": [
"specification_123"
]
}
'import requests
url = "https://api.galtea.ai/monitors/preview"
payload = {
"productId": "prod_123",
"samplingPercentage": 10,
"versionId": "version_123",
"filterQuery": "refund",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"days": 90,
"monitorId": "monitor_123",
"metricGroupIds": ["metricGroup_123"],
"specificationIds": ["specification_123"]
}
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({
productId: 'prod_123',
samplingPercentage: 10,
versionId: 'version_123',
filterQuery: 'refund',
filterTarget: 'EITHER',
excludeQuery: 'test, internal',
excludeTarget: 'EITHER',
messageConditions: [{count: 'messages', operator: 'gt', value: 1}],
days: 90,
monitorId: 'monitor_123',
metricGroupIds: ['metricGroup_123'],
specificationIds: ['specification_123']
})
};
fetch('https://api.galtea.ai/monitors/preview', 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/preview",
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([
'productId' => 'prod_123',
'samplingPercentage' => 10,
'versionId' => 'version_123',
'filterQuery' => 'refund',
'filterTarget' => 'EITHER',
'excludeQuery' => 'test, internal',
'excludeTarget' => 'EITHER',
'messageConditions' => [
[
'count' => 'messages',
'operator' => 'gt',
'value' => 1
]
],
'days' => 90,
'monitorId' => 'monitor_123',
'metricGroupIds' => [
'metricGroup_123'
],
'specificationIds' => [
'specification_123'
]
]),
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/preview"
payload := strings.NewReader("{\n \"productId\": \"prod_123\",\n \"samplingPercentage\": 10,\n \"versionId\": \"version_123\",\n \"filterQuery\": \"refund\",\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 \"days\": 90,\n \"monitorId\": \"monitor_123\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\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/monitors/preview")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"productId\": \"prod_123\",\n \"samplingPercentage\": 10,\n \"versionId\": \"version_123\",\n \"filterQuery\": \"refund\",\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 \"days\": 90,\n \"monitorId\": \"monitor_123\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/monitors/preview")
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 \"productId\": \"prod_123\",\n \"samplingPercentage\": 10,\n \"versionId\": \"version_123\",\n \"filterQuery\": \"refund\",\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 \"days\": 90,\n \"monitorId\": \"monitor_123\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"range": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"candidateCount": 500,
"readRange": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"candidateLimit": 500,
"candidateLimitReached": false,
"withTurnsCount": 480,
"contentFilterMatchCount": 150,
"matchCount": 120,
"sampledCount": 12,
"approximateSampling": true,
"creditsPerSession": 4,
"sampledSessions": [
{
"sessionId": "session_123",
"versionId": "version_123",
"createdAt": "2023-11-07T05:31:56Z",
"turnCount": 4,
"matchedText": "I would like a refund for my last order because it arrived damaged…"
}
]
}{
"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"
}Preview monitor content-filter matches
Read-only preview for a CANDIDATE monitor config: how many and which recent past sessions the given content filter, message conditions and sampling percentage would select, among the most recent closed production sessions inside a look-back window. Runs no evaluations, spends no credits, and writes nothing (no processed marks). Use it while creating or editing a monitor. The match count is exact; for a create preview (no monitorId) the sampled subset is representative, not the exact set the created monitor will draw. With metricGroupIds or specificationIds, it also answers the credits one evaluated session costs.
curl --request POST \
--url https://api.galtea.ai/monitors/preview \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"productId": "prod_123",
"samplingPercentage": 10,
"versionId": "version_123",
"filterQuery": "refund",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"days": 90,
"monitorId": "monitor_123",
"metricGroupIds": [
"metricGroup_123"
],
"specificationIds": [
"specification_123"
]
}
'import requests
url = "https://api.galtea.ai/monitors/preview"
payload = {
"productId": "prod_123",
"samplingPercentage": 10,
"versionId": "version_123",
"filterQuery": "refund",
"filterTarget": "EITHER",
"excludeQuery": "test, internal",
"excludeTarget": "EITHER",
"messageConditions": [
{
"count": "messages",
"operator": "gt",
"value": 1
}
],
"days": 90,
"monitorId": "monitor_123",
"metricGroupIds": ["metricGroup_123"],
"specificationIds": ["specification_123"]
}
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({
productId: 'prod_123',
samplingPercentage: 10,
versionId: 'version_123',
filterQuery: 'refund',
filterTarget: 'EITHER',
excludeQuery: 'test, internal',
excludeTarget: 'EITHER',
messageConditions: [{count: 'messages', operator: 'gt', value: 1}],
days: 90,
monitorId: 'monitor_123',
metricGroupIds: ['metricGroup_123'],
specificationIds: ['specification_123']
})
};
fetch('https://api.galtea.ai/monitors/preview', 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/preview",
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([
'productId' => 'prod_123',
'samplingPercentage' => 10,
'versionId' => 'version_123',
'filterQuery' => 'refund',
'filterTarget' => 'EITHER',
'excludeQuery' => 'test, internal',
'excludeTarget' => 'EITHER',
'messageConditions' => [
[
'count' => 'messages',
'operator' => 'gt',
'value' => 1
]
],
'days' => 90,
'monitorId' => 'monitor_123',
'metricGroupIds' => [
'metricGroup_123'
],
'specificationIds' => [
'specification_123'
]
]),
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/preview"
payload := strings.NewReader("{\n \"productId\": \"prod_123\",\n \"samplingPercentage\": 10,\n \"versionId\": \"version_123\",\n \"filterQuery\": \"refund\",\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 \"days\": 90,\n \"monitorId\": \"monitor_123\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\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/monitors/preview")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"productId\": \"prod_123\",\n \"samplingPercentage\": 10,\n \"versionId\": \"version_123\",\n \"filterQuery\": \"refund\",\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 \"days\": 90,\n \"monitorId\": \"monitor_123\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/monitors/preview")
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 \"productId\": \"prod_123\",\n \"samplingPercentage\": 10,\n \"versionId\": \"version_123\",\n \"filterQuery\": \"refund\",\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 \"days\": 90,\n \"monitorId\": \"monitor_123\",\n \"metricGroupIds\": [\n \"metricGroup_123\"\n ],\n \"specificationIds\": [\n \"specification_123\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"range": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"candidateCount": 500,
"readRange": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"candidateLimit": 500,
"candidateLimitReached": false,
"withTurnsCount": 480,
"contentFilterMatchCount": 150,
"matchCount": 120,
"sampledCount": 12,
"approximateSampling": true,
"creditsPerSession": 4,
"sampledSessions": [
{
"sessionId": "session_123",
"versionId": "version_123",
"createdAt": "2023-11-07T05:31:56Z",
"turnCount": 4,
"matchedText": "I would like a refund for my last order because it arrived damaged…"
}
]
}{
"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
Product whose recent production sessions the preview scans.
1"prod_123"
Candidate sampling percentage (greater than 0, at most 100).
0 < x <= 10010
Optional version to narrow the preview to. Null previews the whole product.
"version_123"
Candidate content filter. Null keeps every session that meets the message conditions.
500"refund"
Which side of a turn filterQuery matches against. Set together with filterQuery.
INPUT, OUTPUT, EITHER, null "EITHER"
Candidate exclude filter. Comma-separated terms; a session is dropped when a turn whose chosen target (excludeTarget) contains ANY term. Null excludes nothing. Set together with excludeTarget. Independent of filterQuery.
500"test, internal"
Which side of a turn excludeQuery matches against. Set together with excludeQuery.
INPUT, OUTPUT, EITHER, null "EITHER"
Candidate message conditions, joined by AND. Omitted previews the default (messages above 1); [] previews no message filter. 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.
10Show child attributes
Show child attributes
[
{
"count": "messages",
"operator": "gt",
"value": 1
}
]
Look-back window in days that bounds which sessions are read (default 90, max 90).
1 <= x <= 9090
Existing monitor id when previewing an EDIT, so sampling uses its real seed (exact). Omit for a create preview (representative sampling).
"monitor_123"
The metric families picked on the candidate monitor, as on create. Set it or specificationIds to receive creditsPerSession; omit both when you do not need the cost. A family that has no current metric, or whose metrics belong to another organization, counts 0.
["metricGroup_123"]
The Specifications bound to the candidate monitor, as on create. The cost counts each family they bring that can score production sessions, and a family that is also in metricGroupIds once.
["specification_123"]
Response
Preview computed successfully
The requested look-back window.
Show child attributes
Show child attributes
Recent closed production sessions considered (bounded by the window and an internal cap).
500
Oldest and newest creation time of the sessions actually read. Null when no session was read.
Show child attributes
Show child attributes
The most sessions the preview reads.
500
True when the preview read candidateLimit sessions, so older sessions inside the window were not read.
false
Sessions read that hold at least one turn. The scanner never evaluates a session with no turn.
480
Sessions with at least one turn whose content filter passes. Equals withTurnsCount when no content filter is set.
150
Sessions that met the message conditions and matched the candidate filter (exact; a null filter keeps every session that meets the message conditions).
120
Matched sessions that also fell in the sampling fraction.
12
True for a create preview (no monitorId): the sampled subset is representative, computed from a placeholder seed. The match count is always exact.
true
Credits that scoring one evaluated session costs, at the current price, for the families metricGroupIds and specificationIds give, as the scanner charges them. A metric that costs nothing (Self-Hosted, Human Evaluation, or disabled) counts 0, so empty lists cost 0. Null when the request omits both metricGroupIds and specificationIds.
4
The would-be-selected sessions, most-recent first (capped at 100).
Show child attributes
Show child attributes