Skip to main content
POST
Create sandbox

Authorizations

Authorization
string
header
required

Boat bearer token in the form boat_.... Service API keys authenticate sandbox operations.

Headers

Idempotency-Key
string

Optional exactly-once key for creating a sandbox. Send your own opaque, account-unique value (a UUID) to make POST /sandboxes safe to retry when the response is lost (network timeout, 5xx): the first request creates the sandbox and binds it to the key; every later request with the same account, key, and request body returns that same sandbox instead of creating a second, billable one. Behavior: keys are retained for 24 hours; a concurrent or early retry while the first sandbox is still being minted returns 409 idempotency_in_progress (retry shortly, same key); reusing a key with a different body returns 409 idempotency_key_reused; timeouts and 5xx are safe to retry with the same key; a create that fails before the sandbox exists releases the key within ~2 minutes so a retry can create the sandbox. Omit the header to keep the default (non-idempotent) behavior.

Maximum string length: 255
X-Boat-Org
string

Same as the org query parameter. Query wins when both are set.

Query Parameters

org
string

Billing wallet for this request: an organization you belong to, by id (team_…) or by name as GET /orgs lists it (case-insensitive), or personal. Omitted, the account's active wallet applies (PATCH /orgs/active; personal until set). Two organizations sharing the name answer 409 ambiguous_org and need the id. Sandboxes and snapshots stay creator-private. On /environments routes, only this query parameter selects the organization's shared environments; the X-Boat-Org header and the active wallet do not apply there. Members read them, owners and admins change them.

Body

application/json

Options for provisioning a new cloud computer.

type
enum<string>
default:default

Machine size. small consumes machine time at half rate and large at twice the default rate (see the Billing guide). xlarge needs the $100/month plan or higher, or an account access grant from an administrator. Otherwise, create, resume and fork return 403 machine_class_plan_required. A fork inherits the source sandbox's type unless the fork request passes its own, and resume and fork can move a sandbox between sizes.

Available options:
small,
default,
large,
xlarge
ttlSeconds
integer | null
default:3600

Number of seconds before automatic archival. null disables auto-stop. The backend also accepts the string infinite for legacy compatibility; new clients should send null.

Required range: 1 <= x <= 2592000
labels
object

Key-value labels, for example your session id. Filter on them with GET /sandboxes?label=key=value. At most 20 labels. Keys match [A-Za-z0-9][A-Za-z0-9._/-]{0,62}; values are strings of at most 256 bytes.

env
object

Per-sandbox environment variables injected into the sandbox's tool environment, on top of the account environment's variables (per-sandbox values win on conflicts). Keys must match [A-Za-z_][A-Za-z0-9_]{0,127}; at most 100 variables and 64KB total. Reserved names (ASCII_TOKEN, ASCII_API_URL, AGENT_ID, PRODUCT_MODE, ENVIRONMENT_ID, BOAT_ID, SERVICE_PREVIEW_TOKEN, BOAT_CLI_TOKEN) are rejected with invalid_env. Forked sandboxes inherit the source sandbox's env unless the fork request supplies its own env.

environment
string
default:base

Name of the sandbox environment to attach to this sandbox. Environments are managed in the Boat dashboard and bundle the repositories, secrets, and credential toggles a sandbox gets. Omit to use your default environment (base unless you changed it). Unknown names are rejected with unknown_environment. An environment marked "safe for third parties" passes nothing to the sandbox, exactly like noEnv.

Examples:

"base"

"customer-demos"

noEnv
boolean
default:false

Create a sandbox with none of the secrets attached to your account (no environment variables, secret files, or credentials), confined to itself so it cannot act on your account or other sandboxes. For sandboxes you give to your own users. SSH, SCP, desktop, snapshots, and public URLs still work; pass env to give the sandbox a secret of its own. A fork of a no-env sandbox is always no-env. Equivalent to attaching an environment marked "safe for third parties".

snapshots
boolean
default:true

Pass false to never snapshot this sandbox. Nothing is captured in the background, so it pays no CPU or memory for it, and stopping it erases its disk the way zero data retention does. It cannot be resumed, forked, or saved as a saved snapshot, and if its machine fails there is no backup to rebuild it from.

monitoring
boolean
default:true

Pass false for monitoring off. Boat keeps no command or process output, process list or CPU/RAM samples for this sandbox, and its history, processes and metrics calls answer 409 monitoring_off. Live output of a running command still works. While the account default is on, true is refused with 409 monitoring_off_for_account.

failFast
boolean
default:false

Pass true to get a sandbox only if a machine of this type is ready right now. The call answers within about 1.5 s: either the usual 202 with the sandbox, or 503 no_ready_machine with nothing created, billed, or counted against your start limits, so you can retry or fall back at once. Without it, a create waits for a machine to be built when none is ready. Works with from; fork and resume take it too.

count
integer
default:1

With from: create this many sandboxes from the saved snapshot in one request. Boat creates them together, which is faster than separate creates when you need many sandboxes at once. Start limits and the active-sandbox limit count every sandbox of the batch; if the batch does not fit, nothing is created. The answer lists all of them in sandboxes (and the first one in sandbox). Refused with 400 count_requires_from without from, and with 400 count_with_fail_fast together with failFast.

Required range: 1 <= x <= 1000
setupScript
string

Shell script that runs on the sandbox after it is ready. Ready means "ready to accept the user", not "setup done": the script starts in the background once provisioning completes and never blocks the sandbox becoming usable. It runs as the sandbox user (user, not root; sudo needs no password) via bash, with the sandbox's environment applied, and its output goes to a log file on the sandbox. Observe the outcome as setupStatus (pending/running/done/failed) and setupError on the sandbox. Rejected with a 400 invalid_setup_script error when it is not a string or exceeds 64KB. When the request also has files, the script starts after every file is written.

Maximum string length: 65536
name
string

Display name of the sandbox, the same value PATCH /sandboxes/{id} sets. A sandbox created from a saved snapshot is named after the snapshot when this is omitted.

Maximum string length: 120
visibility
enum<string>

Who can use a sandbox billed to an organization, with the same rules as the sandbox's visibility field. private: only you can use it. shared: every member can, as long as it holds none of your personal logins (noEnv, or an environment that passes nothing). Omitted, the organization's default for new sandboxes applies (PATCH /orgs/{org} newSandboxesPrivate). It is set before the sandbox gets a machine, so a private sandbox is never shared, not even for a moment, and needs no unshare call. A personal sandbox is always private: shared is refused with 400 not_org_sandbox. Change it later with POST /sandboxes/{id}/share and POST /sandboxes/{id}/unshare.

Available options:
private,
shared
hostedPorts
object[]

Ports to host on public HTTPS URLs, each exactly as POST /sandboxes/{id}/host does. The create waits for the sandbox's machine (up to 60 s, usually under a second), hosts every port at once and answers the URLs in hostedPorts. The ports are routed before the sandbox is ready, so a service that starts later is reachable as soon as it listens. Refused with 400 invalid_hosted_ports for a bad entry or a duplicate port, with 400 count_with_hosted_ports together with count, and with 400 fail_fast_with_hosted_ports together with failFast.

Maximum array length: 50
files
object[]

Files to write on the sandbox, each like PUT /sandboxes/{id}/files (a path under /home/user or /tmp, relative paths resolve against /home/user; missing folders are created). Boat writes them once the sandbox's disk is in place and before it reports ready, so a client that sees ready, and the setupScript, always find them. They are written once, at the first start: a resume does not write them again. At most 256KB in total; upload bigger files with POST /sandboxes/{id}/files/upload-url. setupStatus covers them: it stays pending until they are written, and a write that fails sets it failed with the path and the reason in setupError (the setup script then does not run). Refused with 400 invalid_files for a bad path, a duplicate path or a body over the limits.

Maximum array length: 32
org
string

Bill this sandbox to an organization you belong to (its shared wallet), by id or by name as GET /orgs lists it; personal or your own account id means personal billing. Omitted, the X-Boat-Org / ?org= request scope applies, then the account's active wallet (PATCH /orgs/active), then personal. Listing, snapshots, and environments stay yours: the org is a wallet, not a shared workspace. Takes precedence over teamId.

teamId
string

Legacy alias for org. Ignored when org is also set.

from
string

Create the sandbox from a saved snapshot (saved with POST /saved-snapshots, or boat snapshot <id> <name> in the CLI). The sandbox starts from that exact frozen state. Omitting type inherits the type the snapshot was saved from; env and no-env inherit from the snapshot's source sandbox unless the request passes its own, with the same rules as forking. Also accepts a share code (bsh_...) that another account made with POST /saved-snapshots/{name}/shares. The new sandbox lives in and is billed to your account. It does not get the owner's per-sandbox env; your own environment applies normally. A wrong or revoked code returns 404 snapshot_not_found.

Response

Boat accepted for provisioning.

ok
boolean
required
Example:

true

type
string
required

Stable success envelope discriminator added by v1.

Allowed value: "sandbox.created"
status
enum<string>
required

ready only when an idempotent retry finds a sandbox that is already past provisioning.

Available options:
provisioning,
ready
ttlSeconds
integer | null
required
sandbox
object
required
sandboxes
object[]

Present when the request set count above 1. Every sandbox of the batch, in creation order.

hostedPorts
object[]

Present when the request set hostedPorts, in request order. Each entry is what POST /sandboxes/{id}/host answers for that port: url, access, isProtected and localhost, or error and message when that one port could not be hosted (the sandbox is created anyway; host the port again with POST /sandboxes/{id}/host).

giftLimitNotice
string

Present when a fair-use cap on a gifted account shortened the requested auto-stop time.