Skip to main content

Authorizations

Authorization
string
header
required

BoxRouter API key; never an upstream provider key.

Headers

Idempotency-Key
string

Optional for this operation. Preserve the same stable identifier when retrying an uncertain response; never reuse it for new work. If omitted where allowed, Cloud generates a request-scoped key that cannot reconcile a later retry. Do not include credentials or payloads. Stable identifier for one logical mutation.

Required string length: 1 - 128

Body

application/json

Omission is equivalent to an empty object, which is a baseline sandbox.

A creation body: gates by name in requirements, a lifetime budget in lifetime_seconds, and a volume checkpoint to restore. Every field is optional; {} is a baseline sandbox in the standard image that may run for 300 seconds, or for as long as the credit balance covers it on a credit-funded route that can extend a lifetime. The words of the retired 0.2.0 request (timeout_seconds, egress, provider, a dotted requirements key) are refused with invalid_request, whose fix names the word to send instead. Creation controls are provider-independent: use resources, lifetime_seconds, at_end, image, env, labels, requirements and routing preferences. Provider-native creation options are not accepted.

lifetime_seconds
integer | null

The sandbox's lifetime in seconds, starting when BoxRouter begins creation on the selected route. Creation time counts, so less time may remain when the sandbox is ready. The minimum is 60 seconds. The requested value is matched against the route's max_lifetime_seconds, and a credit-funded sandbox reserves credits for all of it.

Leave it out for a credit-funded sandbox on a route that can extend a lifetime (extendable_lifetime) and the sandbox runs for as long as the workspace's credit balance covers it: credits are reserved one hour at a time and renewed before each hour ends. funded_until on the sandbox says when the current reservation ends; the sandbox ends then if the balance could not cover another hour. Left out on any other create (a route that cannot extend a lifetime, or a sandbox paid with the workspace's own provider account), it is 300 seconds.

Null asks for a sandbox with no lifetime: it runs until you destroy it. Only a provider that never ends a sandbox serves it, and only on the workspace's own provider account; leave at_end out with it.

Required range: x >= 60
at_end
enum<string>
default:destroy

What happens when the lifetime is used up. pause needs pause_resume in requirements. Refused with invalid_request when lifetime_seconds is null, because nothing ends that sandbox.

Available options:
destroy,
pause
requirements
object
required if secret_values is set

The gates this sandbox may use, each holding its knobs and its settings side by side. A sandbox may use only the baseline and the gates named here: a call to any other gate is refused with not_named, on every adapter. Every gate the spec names is accepted here, including the ones no adapter implements yet: whether one can be granted is matching's answer, so a gate nothing declares, or no loaded report proves, leaves the request without a route rather than making it invalid.

resources
object

Resource constraints, execution limits, and environment facts that must hold for this sandbox. The matcher compares each named value with declared resources and capabilities; fields left out impose no requirement.

preferences
object
conditionally required

The one provider-preference contract shared by sandbox creation, launch placement and Actions policy settings. Every property is optional; omitted properties inherit. Precedence, narrowest last: workspace restrictions are the ceiling, then a repository default or named Actions policy, then a workflow, then request controls. Hard restrictions (provider allowlists, route, account, supply, region, privacy, origin and spend) intersect and can only narrow; request ignore unions with workspace exclusions. A request true never lifts a workspace allow_fallbacks false. When workspace prevent_overrides is on, containing order, sort or allow_fallbacks is refused with routing_overrides_forbidden even if the value matches the workspace; only still narrows as a set and cannot reorder workspace ranking. Otherwise soft preference values replace inherited values without widening authority. order: [] and ignore: [] are valid empty soft arrays that name no preference and no exclusion; inherited hard authority is unchanged. Each list must hold distinct values; null is never valid for any property. order prioritizes named providers in listed order; eligible providers omitted from it remain candidates afterward, ranked by the existing router order. When only is supplied, it remains the hard ordered allowlist and caps eligible providers; order may rearrange its members, while omitted members retain only order. ignore excludes providers even when named by only or order. sort ranks routes within a provider. allow_fallbacks defaults to true and controls whether creation may dispatch a later eligible route after a provider definitively refuses before creating a sandbox. This includes another account for the same provider. False stops after the first route dispatch. Eligibility and preparation may skip a route before dispatch. Provider, account, supply, payer and requirements constraints remain binding.

privacy
object

Optional privacy requirements for a sandbox request. Omitted values inherit the workspace and customer-key floors; omission never resets them. Supplied values may only tighten those floors. data_collection: deny requires both no model training and zero provider data retention; a route that retains logs does not satisfy deny, even when zdr is false. zdr: true independently requires zero retention and is not a training-policy predicate. Neither setting consents to BoxRouter capture or promises that an eligible provider or end-to-end zero-retention route exists. boxrouter_content_retention separately restricts BoxRouter sandbox-content handling. Transient wins over ordinary across workspace, key, request and immutable origin floors; an ordinary request cannot relax an inherited transient floor. Unsupported transient operations and unqualified routes are refused. Omission preserves inheritance and the legacy combined meaning of request zdr: true; explicitly choosing ordinary separates BoxRouter retention from provider ZDR.

route
object

The remaining route filters. Each singular value is a hard pin: id and account_id name exactly one route or connected account and supply one funding authority. Fallback never moves a pin, a volume remains attached to its selected route, and these filters only narrow workspace restrictions.

volume
object
image

Omitted selects BoxRouter's standard image. "provider_default" opts out and runs the provider's own default. Any other string is an OCI image reference. Use a one-key dockerfile or provider_artifact object for those artifact sources; the latter requires exactly one value in preferences.only. Use {private_oci} for an image whose registry needs a login, together with registry_credentials; it runs only on routes that use your own provider keys. Every selected image must contain bash and sha256sum.

Allowed value: "provider_default"
registry_credentials
object

Request-only login for the registry named by a private_oci image; required with it and refused without it. Both strings are non-empty, at most 64 KiB UTF-8 bytes together (enforced outside JSON Schema). It is passed to the provider to set up a copy of the image and is never stored, logged, traced, returned or included in idempotency records.

env
object

Creation-time environment, limited by the server to 64 KiB total UTF-8 bytes. This byte limit is enforced outside JSON Schema validation. Never returned, logged or stored.

secret_refs
object

Explicit saved workspace secret references by destination environment name.

secret_values
object

Request-only values delivered through the hidden_secrets gate. Values are sent once during sandbox creation. The server enforces a 16 KiB per-value and 64 KiB total UTF-8 byte limit outside JSON Schema validation. Values are never stored, logged, traced, returned, or included in idempotency records. Use the matching placeholder from the response in configuration.

labels
object

BoxRouter labels, returned on the sandbox; not implicitly provider tags.

Response

Sandbox created and its common runtime is ready.

A sandbox created from a settled body, returned by create, restore, get and list. Required fields are present; fields with no value are null, never absent. Optional fields may be absent when their source is not known. Listings do no provider I/O: they show the latest durably recorded state, and native_state, route.selection and recorder are null. Detail responses observe the provider live and record the normalized state unless a concurrent lifecycle change supersedes the read.

id
string
required
Required string length: 1 - 128
Pattern: ^[^\u0000]*$
state
enum<string>
required

Clients must tolerate values they do not know. A sandbox the provider stopped, or one stopped for being idle that can be started again, reads paused; resume brings either back.

Available options:
creating,
running,
paused,
destroying,
destroyed,
error,
unknown
state_reason
enum<string> | null
required

Why it is in this state. external is a change made at the provider, behind BoxRouter's back.

Available options:
requested,
lifetime,
retention,
idle_shutdown,
external,
null
failure
object | null
required

The provider failure recorded with state=error, or null when no recorded failure explains the current state. Present on create, detail and list responses; list reads return the durable value without calling the provider.

native_state
string | null
required
observed_at
string<date-time>
required

Time the state source for this response was read: the owned-record lookup time for a list response, or the live provider-observation time for a detail response.

state_recorded_at
string<date-time> | null
required

Timestamp of the durable state source used for this response. This can be an existing lifecycle or lifetime record when the returned public state is derived from that source, and may predate observed_at. Null when no source timestamp is available or a concurrent lifecycle change supersedes the detail read.

created_at
string<date-time> | null
required

Time Cloud sent the first create request when that edge is available; otherwise the sandbox record's created time.

ready_at
string<date-time> | null
required

Time Cloud received the first create response; when that edge is unavailable, the sandbox record's ready time. Null while creating. List and detail responses use the same value.

ended_at
string<date-time> | null
required

Time Cloud received the last destroy response; when that edge is unavailable, Cloud's record of confirmation or first observation that the sandbox was gone. Null while the sandbox has not ended. List and detail responses use the same value.

labels
object
required
lifetime
object
required

How long the sandbox may live. It counts from the provider's create, as with the provider's own SDK (BoxRouter's clock starts when it sends the create). Whether paused time counts depends on the provider.

route
object
required

The adapter that made this sandbox. Support questions start at adapter_version. A sandbox with no recorded contract still names its provider and account; its class and adapter_version are null.

contract
object | null
required

Null for a record with no recorded contract, such as one a provider-native route created.

request
object
required

The recorded creation request after server-side expansion and defaulting, without request-only secret values, environment values or labels. A sandbox can outlive the create-request schema that was current when it was made, so this historical snapshot accepts fields from earlier contract versions. Clients should interpret only fields they recognize and preserve unknown fields when displaying or storing the snapshot.

hidden_secrets
object | null
required

Public metadata for the request-only secret values, keyed by their submitted names. Each result contains only a placeholder and its allowed hosts. Null when the create submitted no secret values.

tcp_ports
object[] | null
required

Public host and port for each requested TCP listener, in request order.

recorder
object | null
required

A tally of the gate calls made on this sandbox, allowed and refused, with the requirements line those calls relied on. It only tallies: it switches no gate on.

limits
object
required
expires_at
string<date-time> | null

Enforced deadline from the recorded lifetime budget, including extensions. This is the same deadline exposed as lifetime.ends_at; null when no deadline is known.

created_at_source
enum<string> | null

Where created_at came from. Null when created_at is null. Always BoxRouter's own record.

Available options:
provider,
published,
measured,
recorded,
calculated,
unknown
created_at_how
string | null

One sentence saying how created_at was determined. Null when created_at is null.

Minimum string length: 1
created_at_step
integer | null

Null because created_at comes from a recorded lifecycle edge or Cloud's record.

Required range: x >= 1
ready_at_source
enum<string> | null

Where ready_at came from. Null when ready_at is null. Lifecycle edges and Cloud's own record are recorded.

Available options:
provider,
published,
measured,
recorded,
calculated,
unknown
ready_at_how
string | null

One sentence saying how ready_at was determined. Null when ready_at is null.

Minimum string length: 1
ready_at_step
integer | null

Null because ready_at comes from a recorded lifecycle edge or Cloud's record.

Required range: x >= 1
ended_at_source
enum<string> | null

Where ended_at came from. Null when ended_at is null. Lifecycle edges and Cloud's own record are recorded.

Available options:
provider,
published,
measured,
recorded,
calculated,
unknown
ended_at_how
string | null

One sentence saying how ended_at was determined. Null when ended_at is null.

Minimum string length: 1
ended_at_step
integer | null

Null because ended_at comes from a recorded lifecycle edge or Cloud's record.

Required range: x >= 1
cost_source
enum<string> | null

Where cost came from. Null when cost is null. provider for a reported cost, calculated for a worked-out one, unknown when no cost could be worked out. The cost_step is 1 for a provider figure, then 2 provider times, 3 a checked billing boundary, 4 a range, 5 unknown.

Available options:
provider,
published,
measured,
recorded,
calculated,
unknown
cost_how
string | null

One sentence saying how cost was determined. Null when cost is null.

Minimum string length: 1
cost_step
integer | null

The position of the source in BoxRouter's source order for this value, 1 being the best. Null when the value is BoxRouter's own record rather than a pick between sources.

Required range: x >= 1
origin
object

Durable creation provenance. Omitted when the source is not known.

name
string | null

Sandbox name from labels.name, when set.

resources
object

Resolved CPU, memory and disk resources; null values mean unknown.

image
object | null

The image the sandbox runs and where that is known from. Null when nothing records it. Absent from responses of a Cloud that does not report it yet.

image_setup
object

Present only when this start waited for image setup on its chosen provider.

usage
Usage record · object

What the sandbox used: its size, its running time per state, how often it was created, each fact with the source it came from. Null when nothing has been recorded or the response does not carry it. Absent from responses of a Cloud that does not report it yet.

cost
Cost · object

What the sandbox cost, with one word saying how far to trust it. Create and detail responses carry the full cost with its working; list rows carry only its label and total, from the same calculation. One object serves both, so the schema accepts either shape anywhere: a client that needs the working reads the detail. Null when no cost has been worked out. Absent from responses of a Cloud that does not report it yet.

charge
object | null

What BoxRouter charged to the workspace's credits for this sandbox: the reservation while it runs, then the amount charged once the provider's records are in. Present on credit-funded sandboxes in detail and list responses. Null for a sandbox paid with the workspace's own provider account (BYOK), for a credit-funded one whose reservation was released without a charge, and for one whose ledger record cannot be verified: BoxRouter reports no charge rather than a guess. cost still reports the provider's cost. Absent from create and other responses, and from a Cloud that does not report it yet. It is the ledger's amount, never derived from cost or from BoxRouter's clock.

funded_until
string<date-time> | null

The time up to which the workspace's credits are reserved for this sandbox. A sandbox created without lifetime_seconds renews its reservation hourly while the balance covers it, so this moves later at each renewal; the sandbox ends at this time if the balance could not cover another hour. For a sandbox created with lifetime_seconds it is the end of that lifetime. Null for a sandbox paid with the workspace's own provider account (BYOK), which has no reservation. A reservation is a hold on the balance, never a cost: charge reports the credits reserved and then charged. Present on create and on detail and list reads; absent from a Cloud that does not report it yet.

connectable
boolean

Whether interactive access to this sandbox is offered: a terminal, commands, files and processes. False for a sandbox an Actions job runs in, which holds that job's token and secrets; Cloud refuses these operations on it, before and after the job ends, and the dashboard shows no Connect action. True for every other sandbox. One rule, decided by Cloud; clients do not infer it from origin, which an Actions runner that has not yet served a job does not have. Present on detail and list reads; absent from a Cloud that does not report it yet.

volume
object | null

Present when the sandbox is attached to a BoxRouter Volume.

operation_id
string | null

Present on a destroy response: the workspace-owned destroy operation while lifecycle work remains (state is destroying), null once the destroy is confirmed. Absent from every other response.

Minimum string length: 1
account
object

Present only while the account's key no longer works (section 7); that sandbox's calls then answer account_unhealthy and state is unknown.