curl -X POST "https://first-signal-api.fly.dev/v1/agents/6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b/tests/validate" \
-H "Authorization: Bearer $SIGNAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"spec":{"specVersion":1,"source":{"kind":"custom","basedOnTestId":null,"basedOnCallId":null},"caller":{"persona":"golden-cooperative","goal":"Ask what the cancellation policy is","lines":["What is your cancellation policy?"],"behaviours":[]},"fixtures":{"lookup_policy":[{"response":{"policy":"Free cancellation up to 24 hours before."}}]},"criteria":[{"text":"The agent states the cancellation window","decidedBy":"judge"}]}}'import requests
url = "https://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate"
payload = { "spec": {
"specVersion": 1,
"source": {
"kind": "custom",
"basedOnTestId": None,
"basedOnCallId": None
},
"caller": {
"persona": "golden-cooperative",
"goal": "Ask what the cancellation policy is",
"lines": ["What is your cancellation policy?"],
"behaviours": []
},
"fixtures": { "lookup_policy": [{ "response": { "policy": "Free cancellation up to 24 hours before." } }] },
"criteria": [
{
"text": "The agent states the cancellation window",
"decidedBy": "judge"
}
]
} }
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({
spec: {
specVersion: 1,
source: {kind: 'custom', basedOnTestId: null, basedOnCallId: null},
caller: {
persona: 'golden-cooperative',
goal: 'Ask what the cancellation policy is',
lines: ['What is your cancellation policy?'],
behaviours: []
},
fixtures: {
lookup_policy: [{response: {policy: 'Free cancellation up to 24 hours before.'}}]
},
criteria: [{text: 'The agent states the cancellation window', decidedBy: 'judge'}]
}
})
};
fetch('https://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate', 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://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate",
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([
'spec' => [
'specVersion' => 1,
'source' => [
'kind' => 'custom',
'basedOnTestId' => null,
'basedOnCallId' => null
],
'caller' => [
'persona' => 'golden-cooperative',
'goal' => 'Ask what the cancellation policy is',
'lines' => [
'What is your cancellation policy?'
],
'behaviours' => [
]
],
'fixtures' => [
'lookup_policy' => [
[
'response' => [
'policy' => 'Free cancellation up to 24 hours before.'
]
]
]
],
'criteria' => [
[
'text' => 'The agent states the cancellation window',
'decidedBy' => 'judge'
]
]
]
]),
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://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate"
payload := strings.NewReader("{\n \"spec\": {\n \"specVersion\": 1,\n \"source\": {\n \"kind\": \"custom\",\n \"basedOnTestId\": null,\n \"basedOnCallId\": null\n },\n \"caller\": {\n \"persona\": \"golden-cooperative\",\n \"goal\": \"Ask what the cancellation policy is\",\n \"lines\": [\n \"What is your cancellation policy?\"\n ],\n \"behaviours\": []\n },\n \"fixtures\": {\n \"lookup_policy\": [\n {\n \"response\": {\n \"policy\": \"Free cancellation up to 24 hours before.\"\n }\n }\n ]\n },\n \"criteria\": [\n {\n \"text\": \"The agent states the cancellation window\",\n \"decidedBy\": \"judge\"\n }\n ]\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://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"spec\": {\n \"specVersion\": 1,\n \"source\": {\n \"kind\": \"custom\",\n \"basedOnTestId\": null,\n \"basedOnCallId\": null\n },\n \"caller\": {\n \"persona\": \"golden-cooperative\",\n \"goal\": \"Ask what the cancellation policy is\",\n \"lines\": [\n \"What is your cancellation policy?\"\n ],\n \"behaviours\": []\n },\n \"fixtures\": {\n \"lookup_policy\": [\n {\n \"response\": {\n \"policy\": \"Free cancellation up to 24 hours before.\"\n }\n }\n ]\n },\n \"criteria\": [\n {\n \"text\": \"The agent states the cancellation window\",\n \"decidedBy\": \"judge\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate")
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 \"spec\": {\n \"specVersion\": 1,\n \"source\": {\n \"kind\": \"custom\",\n \"basedOnTestId\": null,\n \"basedOnCallId\": null\n },\n \"caller\": {\n \"persona\": \"golden-cooperative\",\n \"goal\": \"Ask what the cancellation policy is\",\n \"lines\": [\n \"What is your cancellation policy?\"\n ],\n \"behaviours\": []\n },\n \"fixtures\": {\n \"lookup_policy\": [\n {\n \"response\": {\n \"policy\": \"Free cancellation up to 24 hours before.\"\n }\n }\n ]\n },\n \"criteria\": [\n {\n \"text\": \"The agent states the cancellation window\",\n \"decidedBy\": \"judge\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"object": "spec_validation",
"ok": true,
"problems": [
{
"path": "<string>",
"code": "<string>",
"message": "<string>",
"severity": "error"
}
],
"spec": {
"specVersion": 1,
"source": {
"kind": "production",
"basedOnTestId": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"basedOnCallId": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"briefLine": {
"section": "out_of_scope",
"key": "<string>",
"text": "<string>"
},
"generated": {
"generationId": "<string>",
"kind": "from_call",
"cell": "<string>"
}
},
"intentSlug": "<string>",
"lane": "hearing",
"tier": "text",
"start": {
"direction": "inbound",
"agentSpeaksFirst": true,
"variables": {},
"metadata": {}
},
"caller": {
"persona": "<string>",
"goal": "<string>",
"lines": [
"<string>"
],
"behaviours": [
{
"kind": "refuses",
"atLine": 123,
"detail": "<string>"
}
]
},
"fixtures": {},
"criteria": [
{
"id": "<string>",
"decidedBy": "detector",
"ref": "<string>",
"text": "<string>",
"polarity": "must"
}
],
"expect": "pass",
"guard": true,
"sets": [
"<string>"
],
"tags": [
"<string>"
],
"testId": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"revision": 123,
"title": "<string>"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}Validate a test spec
Checks a spec as create (or, with testId, as an edit of that test) would, and stores and spends nothing. 200 whatever the result: ok says whether it would be stored. A read key may call it.
curl -X POST "https://first-signal-api.fly.dev/v1/agents/6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b/tests/validate" \
-H "Authorization: Bearer $SIGNAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"spec":{"specVersion":1,"source":{"kind":"custom","basedOnTestId":null,"basedOnCallId":null},"caller":{"persona":"golden-cooperative","goal":"Ask what the cancellation policy is","lines":["What is your cancellation policy?"],"behaviours":[]},"fixtures":{"lookup_policy":[{"response":{"policy":"Free cancellation up to 24 hours before."}}]},"criteria":[{"text":"The agent states the cancellation window","decidedBy":"judge"}]}}'import requests
url = "https://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate"
payload = { "spec": {
"specVersion": 1,
"source": {
"kind": "custom",
"basedOnTestId": None,
"basedOnCallId": None
},
"caller": {
"persona": "golden-cooperative",
"goal": "Ask what the cancellation policy is",
"lines": ["What is your cancellation policy?"],
"behaviours": []
},
"fixtures": { "lookup_policy": [{ "response": { "policy": "Free cancellation up to 24 hours before." } }] },
"criteria": [
{
"text": "The agent states the cancellation window",
"decidedBy": "judge"
}
]
} }
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({
spec: {
specVersion: 1,
source: {kind: 'custom', basedOnTestId: null, basedOnCallId: null},
caller: {
persona: 'golden-cooperative',
goal: 'Ask what the cancellation policy is',
lines: ['What is your cancellation policy?'],
behaviours: []
},
fixtures: {
lookup_policy: [{response: {policy: 'Free cancellation up to 24 hours before.'}}]
},
criteria: [{text: 'The agent states the cancellation window', decidedBy: 'judge'}]
}
})
};
fetch('https://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate', 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://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate",
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([
'spec' => [
'specVersion' => 1,
'source' => [
'kind' => 'custom',
'basedOnTestId' => null,
'basedOnCallId' => null
],
'caller' => [
'persona' => 'golden-cooperative',
'goal' => 'Ask what the cancellation policy is',
'lines' => [
'What is your cancellation policy?'
],
'behaviours' => [
]
],
'fixtures' => [
'lookup_policy' => [
[
'response' => [
'policy' => 'Free cancellation up to 24 hours before.'
]
]
]
],
'criteria' => [
[
'text' => 'The agent states the cancellation window',
'decidedBy' => 'judge'
]
]
]
]),
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://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate"
payload := strings.NewReader("{\n \"spec\": {\n \"specVersion\": 1,\n \"source\": {\n \"kind\": \"custom\",\n \"basedOnTestId\": null,\n \"basedOnCallId\": null\n },\n \"caller\": {\n \"persona\": \"golden-cooperative\",\n \"goal\": \"Ask what the cancellation policy is\",\n \"lines\": [\n \"What is your cancellation policy?\"\n ],\n \"behaviours\": []\n },\n \"fixtures\": {\n \"lookup_policy\": [\n {\n \"response\": {\n \"policy\": \"Free cancellation up to 24 hours before.\"\n }\n }\n ]\n },\n \"criteria\": [\n {\n \"text\": \"The agent states the cancellation window\",\n \"decidedBy\": \"judge\"\n }\n ]\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://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"spec\": {\n \"specVersion\": 1,\n \"source\": {\n \"kind\": \"custom\",\n \"basedOnTestId\": null,\n \"basedOnCallId\": null\n },\n \"caller\": {\n \"persona\": \"golden-cooperative\",\n \"goal\": \"Ask what the cancellation policy is\",\n \"lines\": [\n \"What is your cancellation policy?\"\n ],\n \"behaviours\": []\n },\n \"fixtures\": {\n \"lookup_policy\": [\n {\n \"response\": {\n \"policy\": \"Free cancellation up to 24 hours before.\"\n }\n }\n ]\n },\n \"criteria\": [\n {\n \"text\": \"The agent states the cancellation window\",\n \"decidedBy\": \"judge\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://first-signal-api.fly.dev/v1/agents/{agentId}/tests/validate")
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 \"spec\": {\n \"specVersion\": 1,\n \"source\": {\n \"kind\": \"custom\",\n \"basedOnTestId\": null,\n \"basedOnCallId\": null\n },\n \"caller\": {\n \"persona\": \"golden-cooperative\",\n \"goal\": \"Ask what the cancellation policy is\",\n \"lines\": [\n \"What is your cancellation policy?\"\n ],\n \"behaviours\": []\n },\n \"fixtures\": {\n \"lookup_policy\": [\n {\n \"response\": {\n \"policy\": \"Free cancellation up to 24 hours before.\"\n }\n }\n ]\n },\n \"criteria\": [\n {\n \"text\": \"The agent states the cancellation window\",\n \"decidedBy\": \"judge\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"object": "spec_validation",
"ok": true,
"problems": [
{
"path": "<string>",
"code": "<string>",
"message": "<string>",
"severity": "error"
}
],
"spec": {
"specVersion": 1,
"source": {
"kind": "production",
"basedOnTestId": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"basedOnCallId": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"briefLine": {
"section": "out_of_scope",
"key": "<string>",
"text": "<string>"
},
"generated": {
"generationId": "<string>",
"kind": "from_call",
"cell": "<string>"
}
},
"intentSlug": "<string>",
"lane": "hearing",
"tier": "text",
"start": {
"direction": "inbound",
"agentSpeaksFirst": true,
"variables": {},
"metadata": {}
},
"caller": {
"persona": "<string>",
"goal": "<string>",
"lines": [
"<string>"
],
"behaviours": [
{
"kind": "refuses",
"atLine": 123,
"detail": "<string>"
}
]
},
"fixtures": {},
"criteria": [
{
"id": "<string>",
"decidedBy": "detector",
"ref": "<string>",
"text": "<string>",
"polarity": "must"
}
],
"expect": "pass",
"guard": true,
"sets": [
"<string>"
],
"tags": [
"<string>"
],
"testId": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"revision": 123,
"title": "<string>"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}{
"error": {
"type": "not_found_error",
"code": "agent_not_found",
"message": "Agent not found.",
"param": null,
"requestId": "req_8c1f0e2b4a6d9e3f7a5c1b0d"
}
}Authorizations
An API key (sig_...), or a session token from the web app.
Path Parameters
The agent's id.
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
Body
A TestSpec (see the TestSpec component and GET .../tests/schema). Checked as a whole: a refused spec names the first problem's path in param.
Show child attributes
Show child attributes
Check the spec as an edit of this test.
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
Response
Problems, and the spec as it would be stored.
spec_validation Whether the spec would be stored.
Show child attributes
Show child attributes
The spec as it would be stored: ids filled in, personal data masked. Null when it is too broken to read.
Show child attributes
Show child attributes
Was this page helpful?