Detach a sandbox from a CI runner
curl --request DELETE \
--url https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId} \
--header 'x-brimble-key: <api-key>'import requests
url = "https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}"
headers = {"x-brimble-key": "<api-key>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {'x-brimble-key': '<api-key>'}};
fetch('https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}', 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.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"x-brimble-key: <api-key>"
],
]);
$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.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("x-brimble-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}")
.header("x-brimble-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["x-brimble-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"errors": [
{
"type": "field",
"value": "<unknown>",
"msg": "Invalid value",
"path": "name",
"location": "body"
}
]
}{
"message": "Project not found",
"data": {}
}{
"message": "Project not found",
"data": {}
}{
"message": "Project not found",
"data": {}
}{
"message": "Project not found",
"data": {}
}CI Runners
Detach a sandbox from a CI runner
Stops the runner in the sandbox and removes it from GitHub. The sandbox is not deleted. It goes back to its normal expiry, unless it was created to never expire. When the last sandbox is detached, the runner is disabled.
API key scope: ci_runner.update
Team role permission: ci_runner.update
DELETE
/
v1
/
ci-runners
/
{id}
/
sandboxes
/
{sandboxId}
Detach a sandbox from a CI runner
curl --request DELETE \
--url https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId} \
--header 'x-brimble-key: <api-key>'import requests
url = "https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}"
headers = {"x-brimble-key": "<api-key>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {'x-brimble-key': '<api-key>'}};
fetch('https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}', 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.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"x-brimble-key: <api-key>"
],
]);
$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.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("x-brimble-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}")
.header("x-brimble-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.brimble.io/core/v1/ci-runners/{id}/sandboxes/{sandboxId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["x-brimble-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"errors": [
{
"type": "field",
"value": "<unknown>",
"msg": "Invalid value",
"path": "name",
"location": "body"
}
]
}{
"message": "Project not found",
"data": {}
}{
"message": "Project not found",
"data": {}
}{
"message": "Project not found",
"data": {}
}{
"message": "Project not found",
"data": {}
}Authorizations
ApiKeyAuthBearerAuth
API key created in the dashboard under Settings → API keys. Each key carries permission scopes; every endpoint lists the scope it needs.
Path Parameters
ID of the CI runner.
Pattern:
^[a-fA-F0-9]{24}$ID of the attached sandbox.
Pattern:
^[a-fA-F0-9]{24}$Response
Sandbox detached
Last modified on November 10, 2026
Was this page helpful?