curl --request POST \
--url https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sleep": false
}'import requests
url = "https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot"
payload = { "sleep": False }
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({sleep: false})
};
fetch('https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot', 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/{sailbox_id}/reboot",
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([
'sleep' => false
]),
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://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot"
payload := strings.NewReader("{\n \"sleep\": false\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://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sleep\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot")
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 \"sleep\": false\n}"
response = http.request(request)
puts response.read_body{
"sailbox_id": "<string>",
"status": "<string>",
"applied": true
}{
"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": "sailbox \"sb_9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d\" not found",
"type": "not_found_error",
"param": null,
"code": null
}
}{
"error": {
"message": "idempotency key reused with a different request body",
"type": "conflict_error",
"param": null,
"code": null
}
}{
"error": {
"message": "request body too large",
"type": "invalid_request_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
}
}{
"error": {
"message": "idempotent request still in flight",
"type": "server_error",
"param": null,
"code": null
}
}Reboot a Sailbox
Boots the Sailbox fresh from its current disk, as a machine reboot would. Files on its disk and on mounted volumes are kept. Running processes and memory are not, so anything not yet written to disk is lost. A running Sailbox reboots now and the response has applied: true. A paused or sleeping Sailbox is not woken: the reboot is recorded, the Sailbox boots fresh on its next wake, and the response has applied: false.
Send sleep: true to power the Sailbox off instead: a running Sailbox goes to sleep now and boots fresh from its disk at its next wake.
curl --request POST \
--url https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sleep": false
}'import requests
url = "https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot"
payload = { "sleep": False }
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({sleep: false})
};
fetch('https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot', 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/{sailbox_id}/reboot",
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([
'sleep' => false
]),
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://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot"
payload := strings.NewReader("{\n \"sleep\": false\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://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sleep\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sailbox-api.sailresearch.com/v1/sailboxes/{sailbox_id}/reboot")
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 \"sleep\": false\n}"
response = http.request(request)
puts response.read_body{
"sailbox_id": "<string>",
"status": "<string>",
"applied": true
}{
"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": "sailbox \"sb_9c8f1e2a-3b4d-4f5a-8c7e-1d2f3a4b5c6d\" not found",
"type": "not_found_error",
"param": null,
"code": null
}
}{
"error": {
"message": "idempotency key reused with a different request body",
"type": "conflict_error",
"param": null,
"code": null
}
}{
"error": {
"message": "request body too large",
"type": "invalid_request_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
}
}{
"error": {
"message": "idempotent request still in flight",
"type": "server_error",
"param": null,
"code": null
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Makes the request retry-safe. Sail remembers the answer it sent under a key, including a 400 or a 409, and replays it with Idempotent-Replayed: true for a retry that repeats the key, the method, the path, and the body. Bodies are compared byte for byte. Reusing a key for a different request returns 409, so send a corrected request under a new key. A key that is blank or only spaces is ignored, and the request runs without idempotency.
Any string of up to 255 bytes works, and characters outside ASCII count for more than one. A UUID is a good default. Keys are remembered for at least 24 hours and scoped to the API key that sent them.
A server error, or a failure to record the answer, can leave a key unsettled, and creating a Sailbox is where that matters. See Retrying safely.
255Lets an organization admin operate a private Sailbox someone else created. Say why in plain text; the reason goes into your organization's audit log, and the operation is refused without it. Ignored on Sailboxes you could already operate.
Pause, resume, sleep, scheduled wake, upgrade, reboot, and terminate accept an override, and so does deleting a checkpoint taken from the Sailbox. Setting an egress policy accepts one too. Running commands and moving files accept one through an SDK or the CLI. Publishing and unpublishing ports, adding and removing custom domains, checkpointing, and creating from a checkpoint stay with the creator.
^[ -~]*$Path Parameters
Id of the Sailbox, as returned by create. It is sb_ followed by a UUID.
Body
true puts a running Sailbox to sleep instead of starting it again. It boots fresh from its disk at its next wake, and the response has applied: false.
Response
The operation was accepted.
Id of the Sailbox.
Current state of the Sailbox. Values in use today are creating, running, paused, sleeping, terminating, terminated, failed, create_failed, interrupted_restorable, and interrupted_unsafe_to_retry. New values can appear over time, so treat this as an open set.
true when the Sailbox booted fresh during this call. false when it was paused or sleeping: the reboot is recorded and the Sailbox boots fresh the next time it wakes.