curl --request GET \
--url https://sailbox-api.sailresearch.com/v1/sailboxes \
--header 'Authorization: Bearer <token>'import requests
url = "https://sailbox-api.sailresearch.com/v1/sailboxes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sailbox-api.sailresearch.com/v1/sailboxes', 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://sailbox-api.sailresearch.com/v1/sailboxes",
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://sailbox-api.sailresearch.com/v1/sailboxes"
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://sailbox-api.sailresearch.com/v1/sailboxes")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/sailboxes")
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": [
{
"sailbox_id": "sb_9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d",
"name": "worker-1",
"app_id": "app_0f6a2c31-8b4d-4e7a-9c15-2d8e6f4a1b03",
"app_name": "batch-jobs",
"image_id": "sha256:7b1e4a0d93c25f68a1d4f7b0c3e29a5d81f6b4c07e2a9d3f5b8c1e6a04d7f293",
"status": "running",
"architecture": "amd64",
"vcpu_count": 4,
"memory_mib": 32768,
"state_disk_size_gib": 128,
"volume_mounts": [],
"cpu_used_vcpu": 1.8,
"memory_used_bytes": 4294967296,
"disk_used_bytes": 10737418240,
"error_message": null,
"deprecation": null,
"guest_schema_version": 71,
"created_by_user_id": "user_9z8y",
"visibility": "org",
"auto_sleep": {
"automatic": true
},
"egress_policy": {
"policy_id": null,
"name": null,
"document": {}
},
"started_at": "2026-07-20T18:04:19Z",
"last_checkpointed_at": null,
"checkpoint_generation": 0,
"expires_at": null,
"created_at": "2026-07-20T18:04:11Z",
"updated_at": "2026-07-20T18:31:02Z",
"can_pause": true,
"can_sleep": true,
"can_resume": false,
"can_terminate": true
}
],
"limit": 50,
"offset": 0,
"total": 1,
"has_more": false
}{
"error": {
"message": "memory_limit_gib for size m must be between 8 and 128",
"type": "invalid_request_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Invalid API key",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}{
"error": {
"message": "Your API key has been disabled due to insufficient credits. Visit https://app.sailresearch.com/billing to add credits.",
"type": "billing_error",
"param": null,
"code": "credits_exhausted",
"billing_url": "https://app.sailresearch.com/billing"
}
}{
"error": {
"message": "sailboxes require an organization-scoped API key",
"type": "permission_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Too many concurrent requests. Please retry after some of your organization's in-flight requests complete.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limited"
}
}{
"error": {
"message": "failed to fetch sailbox",
"type": "server_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Authentication service unavailable",
"type": "server_error",
"param": null,
"code": null
}
}List Sailboxes
Returns Sailboxes in your organization, most recently active first. Terminated Sailboxes stay in the list, so filter by status if you only want live ones.
curl --request GET \
--url https://sailbox-api.sailresearch.com/v1/sailboxes \
--header 'Authorization: Bearer <token>'import requests
url = "https://sailbox-api.sailresearch.com/v1/sailboxes"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://sailbox-api.sailresearch.com/v1/sailboxes', 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://sailbox-api.sailresearch.com/v1/sailboxes",
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://sailbox-api.sailresearch.com/v1/sailboxes"
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://sailbox-api.sailresearch.com/v1/sailboxes")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/sailboxes")
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": [
{
"sailbox_id": "sb_9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d",
"name": "worker-1",
"app_id": "app_0f6a2c31-8b4d-4e7a-9c15-2d8e6f4a1b03",
"app_name": "batch-jobs",
"image_id": "sha256:7b1e4a0d93c25f68a1d4f7b0c3e29a5d81f6b4c07e2a9d3f5b8c1e6a04d7f293",
"status": "running",
"architecture": "amd64",
"vcpu_count": 4,
"memory_mib": 32768,
"state_disk_size_gib": 128,
"volume_mounts": [],
"cpu_used_vcpu": 1.8,
"memory_used_bytes": 4294967296,
"disk_used_bytes": 10737418240,
"error_message": null,
"deprecation": null,
"guest_schema_version": 71,
"created_by_user_id": "user_9z8y",
"visibility": "org",
"auto_sleep": {
"automatic": true
},
"egress_policy": {
"policy_id": null,
"name": null,
"document": {}
},
"started_at": "2026-07-20T18:04:19Z",
"last_checkpointed_at": null,
"checkpoint_generation": 0,
"expires_at": null,
"created_at": "2026-07-20T18:04:11Z",
"updated_at": "2026-07-20T18:31:02Z",
"can_pause": true,
"can_sleep": true,
"can_resume": false,
"can_terminate": true
}
],
"limit": 50,
"offset": 0,
"total": 1,
"has_more": false
}{
"error": {
"message": "memory_limit_gib for size m must be between 8 and 128",
"type": "invalid_request_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Invalid API key",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}{
"error": {
"message": "Your API key has been disabled due to insufficient credits. Visit https://app.sailresearch.com/billing to add credits.",
"type": "billing_error",
"param": null,
"code": "credits_exhausted",
"billing_url": "https://app.sailresearch.com/billing"
}
}{
"error": {
"message": "sailboxes require an organization-scoped API key",
"type": "permission_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Too many concurrent requests. Please retry after some of your organization's in-flight requests complete.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limited"
}
}{
"error": {
"message": "failed to fetch sailbox",
"type": "server_error",
"param": null,
"code": null
}
}{
"error": {
"message": "Authentication service unavailable",
"type": "server_error",
"param": null,
"code": null
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
How many Sailboxes to return.
1 <= x <= 100How many Sailboxes to skip before the page starts.
0 <= x <= 100000Only return Sailboxes in this app id.
Only return Sailboxes in this status. failed also returns create_failed and interrupted_unsafe_to_retry.
Leave out Sailboxes in any of these statuses, written as a comma-separated list. Each name is matched exactly, so failed here leaves out only failed.
Only return Sailboxes matching this text. It is matched against the Sailbox name and id and against the name and id of the app it belongs to.
Only return Sailboxes that use this saved egress policy. Terminated Sailboxes keep their policy so a restore inherits it, and they are included; add exclude_status to leave them out.
Only return Sailboxes this key can operate without an owner override. A private Sailbox someone else created is left out even for an organization admin.
newest_active groups by state, most recently changed first within each group: running and creating, then paused, sleeping, and interrupted_restorable, then failed, create_failed, and interrupted_unsafe_to_retry, then everything else. newest_created sorts purely by creation time.
newest_active, newest_created, Response
A page of Sailboxes.