curl --request GET \
--url https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details', 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.firedrill.run/v1/projects/{projectId}/run-comparisons/details",
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.firedrill.run/v1/projects/{projectId}/run-comparisons/details"
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.firedrill.run/v1/projects/{projectId}/run-comparisons/details")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details")
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{
"schemaVersion": 1,
"projectId": "<string>",
"baseline": {
"hostedRunId": "<string>",
"evidenceBundleId": "<string>",
"runId": "<string>",
"manifestDigest": "<string>",
"redaction": {
"policy": "safe_fields_v2",
"applied": true,
"replacements": 0
}
},
"candidate": {
"hostedRunId": "<string>",
"evidenceBundleId": "<string>",
"runId": "<string>",
"manifestDigest": "<string>",
"redaction": {
"policy": "safe_fields_v2",
"applied": true,
"replacements": 0
}
},
"compatibility": {
"status": "exact_inputs",
"canAttributeBehaviorChange": true,
"differences": [
"drill"
],
"explanation": "<string>"
},
"kind": "state_changes",
"alignment": "<string>",
"offset": 0,
"total": 0,
"items": [
{
"key": "<string>",
"changedFields": [
"<string>"
],
"baseline": {
"state": "available",
"value": "<unknown>",
"bytes": 8192,
"digest": "<string>"
},
"candidate": {
"state": "available",
"value": "<unknown>",
"bytes": 8192,
"digest": "<string>"
},
"kind": "state_changes",
"identity": {
"packageId": "<string>",
"namespace": "<string>",
"rowId": "<string>",
"mutation": 4503599627370495
}
}
],
"nextCursor": "<string>"
}{
"code": "<string>",
"message": "<string>",
"correlationId": "<string>",
"retryable": true,
"source": "platform",
"retryAfterMs": 123,
"operationId": "<string>",
"issues": [
{
"path": "<string>",
"code": "<string>",
"message": "<string>"
}
],
"details": {},
"evidence": {
"sessionId": "<string>",
"runId": "<string>",
"journalSeq": 4503599627370495,
"buildHash": "<string>"
}
}Read a bounded page of recorded run differences
Requires run.compare in this exact project. Both world-terminal reports are verified against their immutable manifests; current credential, membership, project grant, evidence availability and selection are rechecked after storage reads. Missing evidence returns 404 control.NOT_FOUND; deleted, deletion-requested, expired or changed evidence returns 409 control.CONFLICT; integrity failures return a sanitized 500 control.INTERNAL and unavailable storage a 503 control.INTERNAL. None is an empty comparison. Incompatible inputs remain explicitly marked incompatible: returned entries are descriptive only. Applied redaction also makes comparison descriptive_only with attribution disabled, even when retained input identities match. State changes align by record identity and mutation ordinal, including seed loading, not reconstructed final state or agent-only changes. Operations align by recorded call position, not inferred causal correspondence. Assertions include changed expectations even with unchanged status and actual value; checks are not re-evaluated. Values are the retained, potentially redacted JSON; each is at most 16 KiB, otherwise its exact canonical-JSON byte count and SHA-256 are returned with omitted state. Use each side’s evidenceBundleId with the existing authenticated artifact read to access the complete report. Absent means no aligned recorded entry, never an inferred record deletion. Pages contain only changed entries, at most 25 and 1 MiB. The cursor binds project, ordered run pair, manifest digests and kind; it is not authority. No model execution or mutation occurs.
curl --request GET \
--url https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details', 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.firedrill.run/v1/projects/{projectId}/run-comparisons/details",
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.firedrill.run/v1/projects/{projectId}/run-comparisons/details"
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.firedrill.run/v1/projects/{projectId}/run-comparisons/details")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.firedrill.run/v1/projects/{projectId}/run-comparisons/details")
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{
"schemaVersion": 1,
"projectId": "<string>",
"baseline": {
"hostedRunId": "<string>",
"evidenceBundleId": "<string>",
"runId": "<string>",
"manifestDigest": "<string>",
"redaction": {
"policy": "safe_fields_v2",
"applied": true,
"replacements": 0
}
},
"candidate": {
"hostedRunId": "<string>",
"evidenceBundleId": "<string>",
"runId": "<string>",
"manifestDigest": "<string>",
"redaction": {
"policy": "safe_fields_v2",
"applied": true,
"replacements": 0
}
},
"compatibility": {
"status": "exact_inputs",
"canAttributeBehaviorChange": true,
"differences": [
"drill"
],
"explanation": "<string>"
},
"kind": "state_changes",
"alignment": "<string>",
"offset": 0,
"total": 0,
"items": [
{
"key": "<string>",
"changedFields": [
"<string>"
],
"baseline": {
"state": "available",
"value": "<unknown>",
"bytes": 8192,
"digest": "<string>"
},
"candidate": {
"state": "available",
"value": "<unknown>",
"bytes": 8192,
"digest": "<string>"
},
"kind": "state_changes",
"identity": {
"packageId": "<string>",
"namespace": "<string>",
"rowId": "<string>",
"mutation": 4503599627370495
}
}
],
"nextCursor": "<string>"
}{
"code": "<string>",
"message": "<string>",
"correlationId": "<string>",
"retryable": true,
"source": "platform",
"retryAfterMs": 123,
"operationId": "<string>",
"issues": [
{
"path": "<string>",
"code": "<string>",
"message": "<string>"
}
],
"details": {},
"evidence": {
"sessionId": "<string>",
"runId": "<string>",
"journalSeq": 4503599627370495,
"buildHash": "<string>"
}
}Authorizations
Opaque control credential
Path Parameters
^prj_[0-9a-z]{12,32}$Query Parameters
^hrun_[0-9a-z]{12,32}$^hrun_[0-9a-z]{12,32}$state_changes, operations, assertions 1 - 40961 <= x <= 25Response
Bounded recorded differences
1 ^prj_[0-9a-z]{12,32}$Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
state_changes, operations, assertions 1 - 2000-9007199254740991 <= x <= 9007199254740991-9007199254740991 <= x <= 900719925474099125- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
1 - 4096