curl --request GET \
--url https://api.boxrouter.ai/api/v1/sandboxes \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.boxrouter.ai/api/v1/sandboxes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.boxrouter.ai/api/v1/sandboxes', 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.boxrouter.ai/api/v1/sandboxes",
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.boxrouter.ai/api/v1/sandboxes"
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.boxrouter.ai/api/v1/sandboxes")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.boxrouter.ai/api/v1/sandboxes")
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{
"data": [
{
"id": "sbx_4f2a",
"state": "running",
"state_reason": "requested",
"failure": null,
"native_state": null,
"observed_at": "2026-09-29T18:30:00Z",
"state_recorded_at": "2026-09-29T18:29:57Z",
"created_at": "2026-09-29T17:30:00Z",
"expires_at": "2026-09-29T19:30:00Z",
"ready_at": "2026-09-29T17:30:04Z",
"ended_at": null,
"hidden_secrets": null,
"tcp_ports": null,
"labels": {
"name": "checkout-agent",
"team": "platform"
},
"name": "checkout-agent",
"resources": {
"cpu": 2,
"memory_mib": 4096,
"disk_mib": null
},
"image": {
"value": "standard",
"source": "recorded"
},
"usage": null,
"cost": {
"label": "calculated",
"total": {
"low": "0.0585",
"high": "0.0585"
}
},
"lifetime": {
"seconds": 7200,
"remaining_seconds": 3600,
"ends_at": "2026-09-29T19:30:04Z",
"kept_until": null,
"at_end": "destroy",
"max_seconds": 86400,
"extendable": false
},
"route": {
"id": "route_01J8ZK2M6D8N4Q7S9T1V3W5X6Y",
"provider": "example-provider",
"class": null,
"adapter_version": "0.3.9",
"account_id": "connection:acct_example",
"supply": "byok",
"native_id": "iukabnkodrn7v36debdoe",
"region": "us-east-1",
"selection": null
},
"contract": {
"spec_version": "sandbox-provider-spec/0.1",
"gates": {},
"resources": {
"cpu": 2,
"memory_mib": 4096,
"disk_mib": null,
"region": "us-east-1"
},
"attested": {}
},
"request": {},
"recorder": null,
"limits": {
"buffered_output_bytes": 16777216,
"file_transfer_bytes": 1048576
}
}
],
"next_cursor": null,
"counts": {
"live": 12,
"ended": 3,
"by_state": {
"running": 8,
"paused": 2
}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"outcome": "not_started",
"retry": "safe",
"retry_after_seconds": 1,
"details": {
"selection_version": 1,
"considered": 1,
"excluded": [
{
"provider": "<string>"
}
],
"closest": {},
"nearest": [
{}
],
"requirement": "<string>",
"purchase_id": "<string>",
"preview": {
"unused": 1,
"held_excluded": 1,
"fee": 1,
"principal": 1,
"tax": 1,
"total": 1,
"card": {
"brand": "<string>",
"last4": "<string>",
"type": "card",
"email": "jsmith@example.com"
}
},
"quote": {
"amount": 2,
"tax": 1,
"total": 2,
"address_required": true,
"fee_minor": 1,
"missing": [
"<string>"
]
},
"redemption": {
"code": "<string>",
"amount_nanodollars": "<string>",
"description": "<string>",
"redeemed_at": "2023-11-07T05:31:56Z"
},
"scope": "workspace",
"period": "total",
"limit_nanodollars": 2,
"requested_nanodollars": 2,
"sign_in_method": "<string>",
"masked_email": "<string>",
"failure_reason": "<string>",
"names": [
"<string>"
],
"fields": [
"preferences.order"
],
"volume_id": "<string>",
"writer_sandbox_id": "<string>",
"checkpoint": 2,
"limit_bytes": 1,
"observed_bytes": 1,
"mismatch": {
"field": "image",
"recorded": "<string>",
"requested": "<string>"
},
"volume_phase": "check",
"phase": "code",
"command": "<string>",
"exit_code": 123,
"stderr_tail": "<string>",
"stdout_tail": "<string>",
"agent": "<string>",
"port": 32768,
"revoked": true,
"preview_id": "<string>",
"url": "<string>"
},
"doc_url": "<string>",
"fix": "<string>",
"operation_id": "<string>",
"provider": "<string>",
"native_code": "<string>",
"native_status": 123,
"native_message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"outcome": "not_started",
"retry": "safe",
"retry_after_seconds": 1,
"details": {
"selection_version": 1,
"considered": 1,
"excluded": [
{
"provider": "<string>"
}
],
"closest": {},
"nearest": [
{}
],
"requirement": "<string>",
"purchase_id": "<string>",
"preview": {
"unused": 1,
"held_excluded": 1,
"fee": 1,
"principal": 1,
"tax": 1,
"total": 1,
"card": {
"brand": "<string>",
"last4": "<string>",
"type": "card",
"email": "jsmith@example.com"
}
},
"quote": {
"amount": 2,
"tax": 1,
"total": 2,
"address_required": true,
"fee_minor": 1,
"missing": [
"<string>"
]
},
"redemption": {
"code": "<string>",
"amount_nanodollars": "<string>",
"description": "<string>",
"redeemed_at": "2023-11-07T05:31:56Z"
},
"scope": "workspace",
"period": "total",
"limit_nanodollars": 2,
"requested_nanodollars": 2,
"sign_in_method": "<string>",
"masked_email": "<string>",
"failure_reason": "<string>",
"names": [
"<string>"
],
"fields": [
"preferences.order"
],
"volume_id": "<string>",
"writer_sandbox_id": "<string>",
"checkpoint": 2,
"limit_bytes": 1,
"observed_bytes": 1,
"mismatch": {
"field": "image",
"recorded": "<string>",
"requested": "<string>"
},
"volume_phase": "check",
"phase": "code",
"command": "<string>",
"exit_code": 123,
"stderr_tail": "<string>",
"stdout_tail": "<string>",
"agent": "<string>",
"port": 32768,
"revoked": true,
"preview_id": "<string>",
"url": "<string>"
},
"doc_url": "<string>",
"fix": "<string>",
"operation_id": "<string>",
"provider": "<string>",
"native_code": "<string>",
"native_status": 123,
"native_message": "<string>"
}
}List Workspace Sandboxes
You can rely on:
- Lists only the workspace’s own sandboxes, each with its latest recorded state.
- A label filter matches exactly: only sandboxes carrying every requested label are listed.
You can set: filters, sort, cursor, limit.
Not promised: a fresh observation of each sandbox from its provider.
Lists your workspace’s sandboxes from BoxRouter’s records, without asking providers. state
is the latest state BoxRouter recorded, or unknown if it recorded none; get one sandbox to
check its provider live. observed_at is when the list was read, and state_recorded_at is
when that state was recorded, which can be earlier.
lifecycle defaults to all; send lifecycle=live to list only live sandboxes, or ended for
the rest. You can repeat the state and provider parameters to match any
of several values; repeated label parameters must all match. Unknown query parameters fail the request. The page counts apply every
filter except lifecycle, and by_state also ignores state, so you can show counts while
changing those two filters. source filters by what created the sandbox, and a sandbox’s
origin stays readable after it ends or is removed.
curl --request GET \
--url https://api.boxrouter.ai/api/v1/sandboxes \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.boxrouter.ai/api/v1/sandboxes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.boxrouter.ai/api/v1/sandboxes', 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.boxrouter.ai/api/v1/sandboxes",
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.boxrouter.ai/api/v1/sandboxes"
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.boxrouter.ai/api/v1/sandboxes")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.boxrouter.ai/api/v1/sandboxes")
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{
"data": [
{
"id": "sbx_4f2a",
"state": "running",
"state_reason": "requested",
"failure": null,
"native_state": null,
"observed_at": "2026-09-29T18:30:00Z",
"state_recorded_at": "2026-09-29T18:29:57Z",
"created_at": "2026-09-29T17:30:00Z",
"expires_at": "2026-09-29T19:30:00Z",
"ready_at": "2026-09-29T17:30:04Z",
"ended_at": null,
"hidden_secrets": null,
"tcp_ports": null,
"labels": {
"name": "checkout-agent",
"team": "platform"
},
"name": "checkout-agent",
"resources": {
"cpu": 2,
"memory_mib": 4096,
"disk_mib": null
},
"image": {
"value": "standard",
"source": "recorded"
},
"usage": null,
"cost": {
"label": "calculated",
"total": {
"low": "0.0585",
"high": "0.0585"
}
},
"lifetime": {
"seconds": 7200,
"remaining_seconds": 3600,
"ends_at": "2026-09-29T19:30:04Z",
"kept_until": null,
"at_end": "destroy",
"max_seconds": 86400,
"extendable": false
},
"route": {
"id": "route_01J8ZK2M6D8N4Q7S9T1V3W5X6Y",
"provider": "example-provider",
"class": null,
"adapter_version": "0.3.9",
"account_id": "connection:acct_example",
"supply": "byok",
"native_id": "iukabnkodrn7v36debdoe",
"region": "us-east-1",
"selection": null
},
"contract": {
"spec_version": "sandbox-provider-spec/0.1",
"gates": {},
"resources": {
"cpu": 2,
"memory_mib": 4096,
"disk_mib": null,
"region": "us-east-1"
},
"attested": {}
},
"request": {},
"recorder": null,
"limits": {
"buffered_output_bytes": 16777216,
"file_transfer_bytes": 1048576
}
}
],
"next_cursor": null,
"counts": {
"live": 12,
"ended": 3,
"by_state": {
"running": 8,
"paused": 2
}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"outcome": "not_started",
"retry": "safe",
"retry_after_seconds": 1,
"details": {
"selection_version": 1,
"considered": 1,
"excluded": [
{
"provider": "<string>"
}
],
"closest": {},
"nearest": [
{}
],
"requirement": "<string>",
"purchase_id": "<string>",
"preview": {
"unused": 1,
"held_excluded": 1,
"fee": 1,
"principal": 1,
"tax": 1,
"total": 1,
"card": {
"brand": "<string>",
"last4": "<string>",
"type": "card",
"email": "jsmith@example.com"
}
},
"quote": {
"amount": 2,
"tax": 1,
"total": 2,
"address_required": true,
"fee_minor": 1,
"missing": [
"<string>"
]
},
"redemption": {
"code": "<string>",
"amount_nanodollars": "<string>",
"description": "<string>",
"redeemed_at": "2023-11-07T05:31:56Z"
},
"scope": "workspace",
"period": "total",
"limit_nanodollars": 2,
"requested_nanodollars": 2,
"sign_in_method": "<string>",
"masked_email": "<string>",
"failure_reason": "<string>",
"names": [
"<string>"
],
"fields": [
"preferences.order"
],
"volume_id": "<string>",
"writer_sandbox_id": "<string>",
"checkpoint": 2,
"limit_bytes": 1,
"observed_bytes": 1,
"mismatch": {
"field": "image",
"recorded": "<string>",
"requested": "<string>"
},
"volume_phase": "check",
"phase": "code",
"command": "<string>",
"exit_code": 123,
"stderr_tail": "<string>",
"stdout_tail": "<string>",
"agent": "<string>",
"port": 32768,
"revoked": true,
"preview_id": "<string>",
"url": "<string>"
},
"doc_url": "<string>",
"fix": "<string>",
"operation_id": "<string>",
"provider": "<string>",
"native_code": "<string>",
"native_status": 123,
"native_message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"outcome": "not_started",
"retry": "safe",
"retry_after_seconds": 1,
"details": {
"selection_version": 1,
"considered": 1,
"excluded": [
{
"provider": "<string>"
}
],
"closest": {},
"nearest": [
{}
],
"requirement": "<string>",
"purchase_id": "<string>",
"preview": {
"unused": 1,
"held_excluded": 1,
"fee": 1,
"principal": 1,
"tax": 1,
"total": 1,
"card": {
"brand": "<string>",
"last4": "<string>",
"type": "card",
"email": "jsmith@example.com"
}
},
"quote": {
"amount": 2,
"tax": 1,
"total": 2,
"address_required": true,
"fee_minor": 1,
"missing": [
"<string>"
]
},
"redemption": {
"code": "<string>",
"amount_nanodollars": "<string>",
"description": "<string>",
"redeemed_at": "2023-11-07T05:31:56Z"
},
"scope": "workspace",
"period": "total",
"limit_nanodollars": 2,
"requested_nanodollars": 2,
"sign_in_method": "<string>",
"masked_email": "<string>",
"failure_reason": "<string>",
"names": [
"<string>"
],
"fields": [
"preferences.order"
],
"volume_id": "<string>",
"writer_sandbox_id": "<string>",
"checkpoint": 2,
"limit_bytes": 1,
"observed_bytes": 1,
"mismatch": {
"field": "image",
"recorded": "<string>",
"requested": "<string>"
},
"volume_phase": "check",
"phase": "code",
"command": "<string>",
"exit_code": 123,
"stderr_tail": "<string>",
"stdout_tail": "<string>",
"agent": "<string>",
"port": 32768,
"revoked": true,
"preview_id": "<string>",
"url": "<string>"
},
"doc_url": "<string>",
"fix": "<string>",
"operation_id": "<string>",
"provider": "<string>",
"native_code": "<string>",
"native_status": 123,
"native_message": "<string>"
}
}Authorizations
Query Parameters
Sort by creation time or indexed lifetime deadline; newest is the default. For ending_soonest, records with known deadlines sort first by ascending deadline, with BoxRouter ID ascending as the tie-breaker. Records with a null deadline follow in ascending BoxRouter ID order. source groups records by what created them, github_actions first, then agents, then api, newest first within each group.
newest, oldest, ending_soonest, source Response
A page of sandboxes belonging to this workspace. A sandbox with no recorded contract, such as one a provider-native route created, carries null contract.