curl --request POST \
--url https://api.example.com/api/v1/burn-in/test-executions/mark-stale/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"device_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rack_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"topology_group_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"topology_group_labels": [
"<string>"
],
"site_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"test_slugs": [
"<string>"
],
"operation": "<string>",
"note": "",
"stale_before": "2023-11-07T05:31:56Z"
}
'import requests
url = "https://api.example.com/api/v1/burn-in/test-executions/mark-stale/"
payload = {
"device_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"rack_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"topology_group_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"topology_group_labels": ["<string>"],
"site_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"test_slugs": ["<string>"],
"operation": "<string>",
"note": "",
"stale_before": "2023-11-07T05:31:56Z"
}
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({
device_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
rack_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
topology_group_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
topology_group_labels: ['<string>'],
site_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
test_slugs: ['<string>'],
operation: '<string>',
note: '',
stale_before: '2023-11-07T05:31:56Z'
})
};
fetch('https://api.example.com/api/v1/burn-in/test-executions/mark-stale/', 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.example.com/api/v1/burn-in/test-executions/mark-stale/",
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([
'device_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'rack_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'topology_group_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'topology_group_labels' => [
'<string>'
],
'site_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'test_slugs' => [
'<string>'
],
'operation' => '<string>',
'note' => '',
'stale_before' => '2023-11-07T05:31:56Z'
]),
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.example.com/api/v1/burn-in/test-executions/mark-stale/"
payload := strings.NewReader("{\n \"device_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"rack_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_labels\": [\n \"<string>\"\n ],\n \"site_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"test_slugs\": [\n \"<string>\"\n ],\n \"operation\": \"<string>\",\n \"note\": \"\",\n \"stale_before\": \"2023-11-07T05:31:56Z\"\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.example.com/api/v1/burn-in/test-executions/mark-stale/")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"device_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"rack_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_labels\": [\n \"<string>\"\n ],\n \"site_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"test_slugs\": [\n \"<string>\"\n ],\n \"operation\": \"<string>\",\n \"note\": \"\",\n \"stale_before\": \"2023-11-07T05:31:56Z\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/burn-in/test-executions/mark-stale/")
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 \"device_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"rack_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_labels\": [\n \"<string>\"\n ],\n \"site_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"test_slugs\": [\n \"<string>\"\n ],\n \"operation\": \"<string>\",\n \"note\": \"\",\n \"stale_before\": \"2023-11-07T05:31:56Z\"\n}"
response = http.request(request)
puts response.read_body{
"marked_stale_count": 123,
"stale_hold_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
]
}{
"detail": "<string>",
"code": "error",
"field_errors": [
{
"field": "<string>",
"messages": [
"<string>"
]
}
]
}{
"detail": "<string>",
"code": "error",
"field_errors": [
{
"field": "<string>",
"messages": [
"<string>"
]
}
]
}{
"detail": "<string>",
"code": "error",
"field_errors": [
{
"field": "<string>",
"messages": [
"<string>"
]
}
]
}Mark test executions as stale
Mark test executions as stale for the given devices, racks, and/or topology groups (topology groups include descendants, e.g. a pod covers every rack beneath it) — either an explicit test_slugs list (requires a note) or a stale-test operation slug resolved per device’s device type. Every matching record gets an active stale hold, including records already stale from an earlier hold. Already-stale records keep their original marked_stale_at. Optionally restrict to executions completed before a given datetime (e.g. the timestamp of a firmware update or re-rack event). A manual call creates one TestExecutionStaleHold; an operation call creates one hold per touched device type so each hold retains the exact mapping snapshot used for that type. Every returned hold is independently reversible via its undo action.
curl --request POST \
--url https://api.example.com/api/v1/burn-in/test-executions/mark-stale/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"device_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rack_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"topology_group_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"topology_group_labels": [
"<string>"
],
"site_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"test_slugs": [
"<string>"
],
"operation": "<string>",
"note": "",
"stale_before": "2023-11-07T05:31:56Z"
}
'import requests
url = "https://api.example.com/api/v1/burn-in/test-executions/mark-stale/"
payload = {
"device_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"rack_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"topology_group_ids": ["3c90c3cc-0d44-4b50-8888-8dd25736052a"],
"topology_group_labels": ["<string>"],
"site_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"test_slugs": ["<string>"],
"operation": "<string>",
"note": "",
"stale_before": "2023-11-07T05:31:56Z"
}
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({
device_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
rack_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
topology_group_ids: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
topology_group_labels: ['<string>'],
site_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
test_slugs: ['<string>'],
operation: '<string>',
note: '',
stale_before: '2023-11-07T05:31:56Z'
})
};
fetch('https://api.example.com/api/v1/burn-in/test-executions/mark-stale/', 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.example.com/api/v1/burn-in/test-executions/mark-stale/",
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([
'device_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'rack_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'topology_group_ids' => [
'3c90c3cc-0d44-4b50-8888-8dd25736052a'
],
'topology_group_labels' => [
'<string>'
],
'site_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'test_slugs' => [
'<string>'
],
'operation' => '<string>',
'note' => '',
'stale_before' => '2023-11-07T05:31:56Z'
]),
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.example.com/api/v1/burn-in/test-executions/mark-stale/"
payload := strings.NewReader("{\n \"device_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"rack_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_labels\": [\n \"<string>\"\n ],\n \"site_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"test_slugs\": [\n \"<string>\"\n ],\n \"operation\": \"<string>\",\n \"note\": \"\",\n \"stale_before\": \"2023-11-07T05:31:56Z\"\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.example.com/api/v1/burn-in/test-executions/mark-stale/")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"device_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"rack_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_labels\": [\n \"<string>\"\n ],\n \"site_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"test_slugs\": [\n \"<string>\"\n ],\n \"operation\": \"<string>\",\n \"note\": \"\",\n \"stale_before\": \"2023-11-07T05:31:56Z\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/burn-in/test-executions/mark-stale/")
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 \"device_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"rack_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_ids\": [\n \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n ],\n \"topology_group_labels\": [\n \"<string>\"\n ],\n \"site_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"test_slugs\": [\n \"<string>\"\n ],\n \"operation\": \"<string>\",\n \"note\": \"\",\n \"stale_before\": \"2023-11-07T05:31:56Z\"\n}"
response = http.request(request)
puts response.read_body{
"marked_stale_count": 123,
"stale_hold_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
]
}{
"detail": "<string>",
"code": "error",
"field_errors": [
{
"field": "<string>",
"messages": [
"<string>"
]
}
]
}{
"detail": "<string>",
"code": "error",
"field_errors": [
{
"field": "<string>",
"messages": [
"<string>"
]
}
]
}{
"detail": "<string>",
"code": "error",
"field_errors": [
{
"field": "<string>",
"messages": [
"<string>"
]
}
]
}Authorizations
The access token received from the authorization server in the OAuth 2.0 flow.
Body
Input serializer for the mark-stale bulk action.
At least one of device_ids, rack_ids, topology_group_ids, or
topology_group_labels must be provided — every device they resolve to is
unioned into a single target set. topology_group_ids/topology_group_labels
resolve a group and all of its descendants (e.g. a pod covers every rack/NVLink
domain beneath it), matching the existing topology_group_id filter semantics
used elsewhere in the API. rack_ids/topology_group_ids/
topology_group_labels expansions are restricted to host-kind devices, so a
rack or pod containing a switch doesn't fail the whole call over a device type
that was never meant to be targeted.
Exactly one of test_slugs (manual) or operation (resolved from
stale_test_operations.yaml, per device's device type) must be provided. Manual
marks must include a note explaining why, since there's no operation label
to carry that context — this is the "idiot proofing": a caller can't silently
mass-invalidate records with no explanation.
Devices whose test records should be marked stale.
1Mark stale every device in these racks, in addition to device_ids.
1Mark stale every device in these topology groups and their descendants (e.g. a pod), in addition to device_ids/rack_ids. Topology group UUIDs are call-time only — a topology rebuild deletes and recreates groups with new UUIDs, so callers must resolve fresh IDs immediately before each call rather than caching them. Prefer topology_group_labels for anything that outlives a single request.
1Mark stale every device in these topology groups (resolved by label, scoped to site_id) and their descendants, in addition to the other target fields. Labels are stable across topology rebuilds, unlike topology_group_ids — prefer this field for anything a caller might store rather than resolve immediately before the call. Requires site_id.
1Required when topology_group_labels is provided, to resolve labels unambiguously.
Test slugs to invalidate directly (e.g. 'single-node.hpl-cpu'). Mutually exclusive with operation; requires note.
1A stale-test operation slug (e.g. 'node_reseat') from stale_test_operations.yaml. Resolved per device's device type into that operation's mapped test_slugs. Mutually exclusive with test_slugs. See GET /burn-in/stale-test-operations/ for the available operations.
^[-a-zA-Z0-9_]+$Reason for this mark-stale action. Required when using test_slugs directly.
1000Only mark executions completed before this datetime. Omit to target all matching records.
Response
Response serializer for the mark-stale bulk action.