curl "https://api.signalmd.dev/v1/agents/6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b/comparisons/b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e" \
-H "Authorization: Bearer $SIGNAL_API_KEY"import requests
url = "https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}', 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.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"object": "comparison",
"id": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"fromVersion": 123,
"toVersion": 123,
"configCaptured": {
"from": true,
"to": true
},
"changes": [
{
"kind": "node_added",
"location": {
"kind": "node",
"id": "<string>",
"label": "<string>"
},
"detail": "<string>",
"before": "<string>",
"after": "<string>"
}
],
"result": {
"conclusion": "insufficient_evidence",
"conclusionLabel": "Not enough calls",
"callsBefore": 123,
"callsAfter": 123,
"metrics": [
{
"metric": "got_it_done",
"label": "Got it done",
"unit": "share",
"before": {
"value": 123,
"n": 123
},
"after": {
"value": 123,
"n": 123
},
"delta": 123,
"better": "higher",
"verdict": "changed",
"direction": "better",
"minimum": "The difference is real.",
"notRead": 123
}
],
"issueMoves": [
{
"issueId": "<string>",
"title": "<string>",
"place": "<string>",
"before": {
"value": 123,
"n": 123
},
"after": {
"value": 123,
"n": 123
},
"callsBefore": 123,
"callsAfter": 123,
"delta": 123,
"verdict": "changed",
"direction": "better",
"atChangedPlace": true
}
],
"narrative": "<string>",
"rule": "Not enough calls on each version yet.",
"isRandomized": true
},
"createdAt": "2026-10-02T14:03:07.120Z",
"updatedAt": "2026-10-02T14:03:07.120Z"
}{
"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"
}
}Get a version comparison
One stored comparison.
curl "https://api.signalmd.dev/v1/agents/6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b/comparisons/b8c9d0e1-f2a3-4b4c-9d5e-6f7a8b9c0d1e" \
-H "Authorization: Bearer $SIGNAL_API_KEY"import requests
url = "https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}', 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.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signalmd.dev/v1/agents/{agentId}/comparisons/{comparisonId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"object": "comparison",
"id": "3f1c2d4e-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"fromVersion": 123,
"toVersion": 123,
"configCaptured": {
"from": true,
"to": true
},
"changes": [
{
"kind": "node_added",
"location": {
"kind": "node",
"id": "<string>",
"label": "<string>"
},
"detail": "<string>",
"before": "<string>",
"after": "<string>"
}
],
"result": {
"conclusion": "insufficient_evidence",
"conclusionLabel": "Not enough calls",
"callsBefore": 123,
"callsAfter": 123,
"metrics": [
{
"metric": "got_it_done",
"label": "Got it done",
"unit": "share",
"before": {
"value": 123,
"n": 123
},
"after": {
"value": 123,
"n": 123
},
"delta": 123,
"better": "higher",
"verdict": "changed",
"direction": "better",
"minimum": "The difference is real.",
"notRead": 123
}
],
"issueMoves": [
{
"issueId": "<string>",
"title": "<string>",
"place": "<string>",
"before": {
"value": 123,
"n": 123
},
"after": {
"value": 123,
"n": 123
},
"callsBefore": 123,
"callsAfter": 123,
"delta": 123,
"verdict": "changed",
"direction": "better",
"atChangedPlace": true
}
],
"narrative": "<string>",
"rule": "Not enough calls on each version yet.",
"isRandomized": true
},
"createdAt": "2026-10-02T14:03:07.120Z",
"updatedAt": "2026-10-02T14:03:07.120Z"
}{
"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"
The comparison's id.
Response
The comparison.
A stored comparison between two versions: the configuration change and what production did around it.
comparison ^[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"
Whether each version's configuration was captured. When either was not, changes is empty because nothing could be diffed, not because nothing changed.
Show child attributes
Show child attributes
What changed in the configuration between the two versions, as recorded.
Show child attributes
Show child attributes
What production did on each version, computed on request from the calls stored now, by the health board's own metrics and verdicts.
Show child attributes
Show child attributes
"2026-10-02T14:03:07.120Z"
"2026-10-02T14:03:07.120Z"
Was this page helpful?