curl --request POST \
--url https://api.galtea.ai/sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"versionId": "ver_123",
"productId": "prod_123",
"customId": "my-session-1",
"testCaseId": "tc_123",
"isProduction": true,
"context": "<string>",
"metadata": {
"key": "value"
},
"status": "PENDING"
}
'import requests
url = "https://api.galtea.ai/sessions"
payload = {
"versionId": "ver_123",
"productId": "prod_123",
"customId": "my-session-1",
"testCaseId": "tc_123",
"isProduction": True,
"context": "<string>",
"metadata": { "key": "value" },
"status": "PENDING"
}
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({
versionId: 'ver_123',
productId: 'prod_123',
customId: 'my-session-1',
testCaseId: 'tc_123',
isProduction: true,
context: '<string>',
metadata: {key: 'value'},
status: 'PENDING'
})
};
fetch('https://api.galtea.ai/sessions', 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/sessions",
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([
'versionId' => 'ver_123',
'productId' => 'prod_123',
'customId' => 'my-session-1',
'testCaseId' => 'tc_123',
'isProduction' => true,
'context' => '<string>',
'metadata' => [
'key' => 'value'
],
'status' => 'PENDING'
]),
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/sessions"
payload := strings.NewReader("{\n \"versionId\": \"ver_123\",\n \"productId\": \"prod_123\",\n \"customId\": \"my-session-1\",\n \"testCaseId\": \"tc_123\",\n \"isProduction\": true,\n \"context\": \"<string>\",\n \"metadata\": {\n \"key\": \"value\"\n },\n \"status\": \"PENDING\"\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/sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"versionId\": \"ver_123\",\n \"productId\": \"prod_123\",\n \"customId\": \"my-session-1\",\n \"testCaseId\": \"tc_123\",\n \"isProduction\": true,\n \"context\": \"<string>\",\n \"metadata\": {\n \"key\": \"value\"\n },\n \"status\": \"PENDING\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/sessions")
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 \"versionId\": \"ver_123\",\n \"productId\": \"prod_123\",\n \"customId\": \"my-session-1\",\n \"testCaseId\": \"tc_123\",\n \"isProduction\": true,\n \"context\": \"<string>\",\n \"metadata\": {\n \"key\": \"value\"\n },\n \"status\": \"PENDING\"\n}"
response = http.request(request)
puts response.read_body{
"id": "session_123",
"customId": "custom_session_123",
"versionId": "ver_123",
"userId": "user_123",
"testCaseId": "tc_123",
"context": {
"value": "Session context information"
},
"stoppingReason": "GOAL_ACHIEVED",
"recordingUri": "s3://galtea-bucket/audio/org_123/session_abc-recording.mp3",
"error": "External API responded with HTTP 422: Unprocessable Entity — {\"detail\":\"model not found\"}",
"status": "PENDING",
"isProduction": false,
"metadata": {
"key": "value"
},
"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"
}Create session
Create a new session. See Sessions.
curl --request POST \
--url https://api.galtea.ai/sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"versionId": "ver_123",
"productId": "prod_123",
"customId": "my-session-1",
"testCaseId": "tc_123",
"isProduction": true,
"context": "<string>",
"metadata": {
"key": "value"
},
"status": "PENDING"
}
'import requests
url = "https://api.galtea.ai/sessions"
payload = {
"versionId": "ver_123",
"productId": "prod_123",
"customId": "my-session-1",
"testCaseId": "tc_123",
"isProduction": True,
"context": "<string>",
"metadata": { "key": "value" },
"status": "PENDING"
}
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({
versionId: 'ver_123',
productId: 'prod_123',
customId: 'my-session-1',
testCaseId: 'tc_123',
isProduction: true,
context: '<string>',
metadata: {key: 'value'},
status: 'PENDING'
})
};
fetch('https://api.galtea.ai/sessions', 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/sessions",
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([
'versionId' => 'ver_123',
'productId' => 'prod_123',
'customId' => 'my-session-1',
'testCaseId' => 'tc_123',
'isProduction' => true,
'context' => '<string>',
'metadata' => [
'key' => 'value'
],
'status' => 'PENDING'
]),
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/sessions"
payload := strings.NewReader("{\n \"versionId\": \"ver_123\",\n \"productId\": \"prod_123\",\n \"customId\": \"my-session-1\",\n \"testCaseId\": \"tc_123\",\n \"isProduction\": true,\n \"context\": \"<string>\",\n \"metadata\": {\n \"key\": \"value\"\n },\n \"status\": \"PENDING\"\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/sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"versionId\": \"ver_123\",\n \"productId\": \"prod_123\",\n \"customId\": \"my-session-1\",\n \"testCaseId\": \"tc_123\",\n \"isProduction\": true,\n \"context\": \"<string>\",\n \"metadata\": {\n \"key\": \"value\"\n },\n \"status\": \"PENDING\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.galtea.ai/sessions")
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 \"versionId\": \"ver_123\",\n \"productId\": \"prod_123\",\n \"customId\": \"my-session-1\",\n \"testCaseId\": \"tc_123\",\n \"isProduction\": true,\n \"context\": \"<string>\",\n \"metadata\": {\n \"key\": \"value\"\n },\n \"status\": \"PENDING\"\n}"
response = http.request(request)
puts response.read_body{
"id": "session_123",
"customId": "custom_session_123",
"versionId": "ver_123",
"userId": "user_123",
"testCaseId": "tc_123",
"context": {
"value": "Session context information"
},
"stoppingReason": "GOAL_ACHIEVED",
"recordingUri": "s3://galtea-bucket/audio/org_123/session_abc-recording.mp3",
"error": "External API responded with HTTP 422: Unprocessable Entity — {\"detail\":\"model not found\"}",
"status": "PENDING",
"isProduction": false,
"metadata": {
"key": "value"
},
"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"
}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
Session creation input. versionId is optional: when omitted, provide productId and the API reuses the product's latest version (creating a default first version if the product has none). One of versionId or productId is required. testCaseId and isProduction are independent: a session can be production (no testCaseId), test-driven non-production (testCaseId set, isProduction defaults to false), or externally-ingested non-production (no testCaseId, isProduction explicitly false — typical for imported traces). The only forbidden combination is testCaseId set together with isProduction=true. When testCaseId is set, context is rejected because it would be derived from the test case.
Version ID to create the session for. Optional when productId is provided; one of versionId or productId is required.
"ver_123"
Product to anchor the session when versionId is omitted. The API reuses the product's latest version or creates a default one. Ignored when versionId is provided.
"prod_123"
Optional caller-defined identifier for the session
"my-session-1"
Test case to link this session to. Forbidden when isProduction=true. Defaults to omitted, in which case isProduction defaults to true.
"tc_123"
Whether the session represents real production traffic. Defaults to true when testCaseId is omitted and false when testCaseId is set. May be set explicitly to false without a testCaseId for externally-ingested sessions (e.g. trace imports).
Additional context for the session. Accepts a plain string or a structured JSON object. Forbidden when testCaseId is set (the context is derived from the test case).
Arbitrary key-value metadata
{ "key": "value" }
Initial session status. Defaults to PENDING (open, accepts new turns); the session closes on an explicit finish or the product auto-close sweep (#3384).
PENDING, COMPLETED, FAILED Response
Session created successfully
"session_123"
"custom_session_123"
"ver_123"
"user_123"
"tc_123"
Structured context data. For plain text context, format is { value: "..." }
{ "value": "Session context information" }
"GOAL_ACHIEVED"
Canonical storage URI of the full-call recording for a telephony-evaluation session. Null for non-telephony sessions or before the recording is processed. Resolve to a playable URL via GET /storage?uri=.
"s3://galtea-bucket/audio/org_123/session_abc-recording.mp3"
"External API responded with HTTP 422: Unprocessable Entity — {\"detail\":\"model not found\"}"
PENDING, COMPLETED, FAILED "PENDING"
True when the session represents real production traffic (no associated test case).
false
{ "key": "value" }