Create a new goal
curl --request POST \
--url https://api.waterr.ai/v1/goals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": "<string>",
"instructions": "<string>",
"metrics": {},
"scenario_id": "<string>",
"active": true,
"scenarios": [
"<string>"
]
}
'import requests
url = "https://api.waterr.ai/v1/goals"
payload = {
"name": "<string>",
"description": "<string>",
"instructions": "<string>",
"metrics": {},
"scenario_id": "<string>",
"active": True,
"scenarios": ["<string>"]
}
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({
name: '<string>',
description: '<string>',
instructions: '<string>',
metrics: {},
scenario_id: '<string>',
active: true,
scenarios: ['<string>']
})
};
fetch('https://api.waterr.ai/v1/goals', 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.waterr.ai/v1/goals",
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([
'name' => '<string>',
'description' => '<string>',
'instructions' => '<string>',
'metrics' => [
],
'scenario_id' => '<string>',
'active' => true,
'scenarios' => [
'<string>'
]
]),
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.waterr.ai/v1/goals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"instructions\": \"<string>\",\n \"metrics\": {},\n \"scenario_id\": \"<string>\",\n \"active\": true,\n \"scenarios\": [\n \"<string>\"\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.waterr.ai/v1/goals")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"instructions\": \"<string>\",\n \"metrics\": {},\n \"scenario_id\": \"<string>\",\n \"active\": true,\n \"scenarios\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.waterr.ai/v1/goals")
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 \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"instructions\": \"<string>\",\n \"metrics\": {},\n \"scenario_id\": \"<string>\",\n \"active\": true,\n \"scenarios\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyGoals
Create and manage evaluation goals for scoring participants.
POST
/
goals
Create a new goal
curl --request POST \
--url https://api.waterr.ai/v1/goals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": "<string>",
"instructions": "<string>",
"metrics": {},
"scenario_id": "<string>",
"active": true,
"scenarios": [
"<string>"
]
}
'import requests
url = "https://api.waterr.ai/v1/goals"
payload = {
"name": "<string>",
"description": "<string>",
"instructions": "<string>",
"metrics": {},
"scenario_id": "<string>",
"active": True,
"scenarios": ["<string>"]
}
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({
name: '<string>',
description: '<string>',
instructions: '<string>',
metrics: {},
scenario_id: '<string>',
active: true,
scenarios: ['<string>']
})
};
fetch('https://api.waterr.ai/v1/goals', 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.waterr.ai/v1/goals",
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([
'name' => '<string>',
'description' => '<string>',
'instructions' => '<string>',
'metrics' => [
],
'scenario_id' => '<string>',
'active' => true,
'scenarios' => [
'<string>'
]
]),
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.waterr.ai/v1/goals"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"instructions\": \"<string>\",\n \"metrics\": {},\n \"scenario_id\": \"<string>\",\n \"active\": true,\n \"scenarios\": [\n \"<string>\"\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.waterr.ai/v1/goals")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"instructions\": \"<string>\",\n \"metrics\": {},\n \"scenario_id\": \"<string>\",\n \"active\": true,\n \"scenarios\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.waterr.ai/v1/goals")
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 \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"instructions\": \"<string>\",\n \"metrics\": {},\n \"scenario_id\": \"<string>\",\n \"active\": true,\n \"scenarios\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyOverview
Goals define the criteria the AI uses to evaluate participants after each session. Each goal has a name, description, and scoring instructions. Goals are invisible to participants during the session.Get All Goals
Retrieve all goals for the authenticated user.curl -X GET https://api.waterr.ai/v1/goals \
-H "Authorization: Bearer wai_<your_key>"
[
{
"id": "a1b2c3d4-...",
"name": "Communication Clarity",
"description": "How clearly the participant articulates their ideas",
"instructions": "Score 1-10 based on structure, conciseness, and use of examples",
"metrics": null,
"scenario_id": "scenario-uuid",
"active": true,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
]
Get Goal by ID
string
required
The goal UUID
curl -X GET https://api.waterr.ai/v1/goals/{id} \
-H "Authorization: Bearer wai_<your_key>"
Create Goal
string
required
Name of the goal (e.g., “Problem Solving”, “Empathy”)
string
What this goal measures — visible to you in the dashboard
string
Scoring instructions for the AI — how to evaluate and what score range to use
object
Custom evaluation metrics as JSON (optional)
string
Link this goal directly to a scenario (optional — you can also link via the scenario’s
goals array)boolean
Whether this goal is active. Default:
truemembership_id is automatically set from your auth token — you don’t need to pass it.curl -X POST https://api.waterr.ai/v1/goals \
-H "Authorization: Bearer wai_<your_key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Technical Depth",
"description": "Evaluates depth and accuracy of technical explanations",
"instructions": "Score 1-10. Look for: specific technologies mentioned, trade-off analysis, real-world experience signals. Deduct points for vague or surface-level answers."
}'
{
"id": "a1b2c3d4-...",
"name": "Technical Depth",
"description": "Evaluates depth and accuracy of technical explanations",
"instructions": "Score 1-10...",
"metrics": null,
"active": true,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
Bulk Create Goals
Create multiple goals at once:curl -X POST https://api.waterr.ai/v1/goals/bulk \
-H "Authorization: Bearer wai_<your_key>" \
-H "Content-Type: application/json" \
-d '{
"goals": [
{
"name": "Communication",
"description": "Clarity and structure of responses",
"instructions": "Score 1-10 based on articulation..."
},
{
"name": "Problem Solving",
"description": "Approach to breaking down problems",
"instructions": "Score 1-10 based on methodology..."
}
]
}'
Update Goal
string
required
The goal UUID
curl -X PUT https://api.waterr.ai/v1/goals/{id} \
-H "Authorization: Bearer wai_<your_key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Goal Name",
"instructions": "Updated scoring criteria..."
}'
Delete Goal
string
required
The goal UUID
curl -X DELETE https://api.waterr.ai/v1/goals/{id} \
-H "Authorization: Bearer wai_<your_key>"
Linking Goals to Scenarios
Goals are linked to scenarios during scenario creation or update. Pass an array of goal IDs:curl -X POST https://api.waterr.ai/v1/scenarios \
-H "Authorization: Bearer wai_<your_key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Sales Discovery Call",
"type": "roleplay",
"persona_id": "...",
"prompt": "...",
"goals": ["goal-uuid-1", "goal-uuid-2", "goal-uuid-3"]
}'
Write scoring instructions that are specific and behavioral. “Good communication” is vague. “Responds in structured format: states the approach, walks through reasoning, then summarizes” gives the AI clear criteria.
Goal Scoring Tips
Use a consistent scale
Pick a scale (1-10 recommended) and define what each end means. The AI needs anchors.
Be behavioral, not subjective
“Did they ask clarifying questions before answering?” is scorable. “Were they smart?” is not.
3-5 goals per scenario
Too many goals dilute focus. Pick the 3-5 things that actually matter for this conversation.
Include negative signals
Tell the AI what to deduct for: “Deduct 2 points if they skip the discovery phase entirely.”
Authorizations
API key from waterr.ai/settings?tab=api-keys. Send as Authorization: Bearer wai_<your_key>.
Body
application/json
Name of the goal
Maximum string length:
100Detailed description of the goal
Instructions for achieving the goal
JSON object containing goal metrics
ID of the scenario this goal is directly linked to (optional)
Whether this goal is active for the scenario (default true)
Array of scenario IDs to associate with this goal (legacy support)
Response
Goal created successfully

