Run one command in a sandbox made for it
Creates a sandbox, runs the command in it, answers with the result and deletes the sandbox. The sandbox lives exactly as long as the request: it goes when the command ends and when the caller hangs up. The command gets 300 seconds unless timeout_seconds says otherwise. The call waits for the command however long it runs: there is no 202 here. A sandbox that was given a name has left the node's table, and its name is free, before the answer says that the command has ended (the JSON answer, or the exit, error or end event of a stream): the next call can give the same name at once.
As a stream (text/event-stream): its events are start, stdout, stderr, gap, exit and error: Event streams and terminals.
Takes write and exec.
https://api.glac.ai/v1/runAutorisation
Paramètres d’en-tête
Corps de la requêteJSONobligatoire
- startoptionalboolean
true: start the image's own start command (ENTRYPOINT and CMD) when the machine boots;false: start nothing, whatever the image's labels ask for. Given (as any ofstart,start_commandandready), it is all that counts: the image's labelssbx.startandsbx.readyare not read. The sandbox is made from a template built with these settings andenv(two settings of one image are two templates; the first sandbox of a setting is returnedstartingwhile it is built), which only its owner's sandboxes are made from. Not for a sandbox made from asnapshotor atemplate(400invalid_start). - start_commandoptional
The start command, run as the image's user, its output kept by the sandbox's agent as that of the command
exe-start(the last 16 MiB of it, read like any command's withGET …/exec/exe-startand…/exec/exe-start/output; for an app's instance it is also what the app's log has of the instance): a string is run by/bin/sh -cand may hold several lines; a list is run as it is, without a shell (for an image that has none). At most 1000 arguments and 64 KiB, no NUL bytes, the first argument not empty. Withstart: false, 400invalid_start. - readyoptional
When the machine of the sandbox's template counts as up: the node saves the template, which every sandbox of these settings is cloned from, only once this check passes, so that the service is running in each of them from the start. One of three.
tcpandhttpare tried by the node from the host, at the address the preview URLs reach the sandbox by: nothing runs in the sandbox for them, so an image without a shell can be checked, and the service has to listen on all addresses, not on 127.0.0.1 alone.commandruns in the sandbox as the image's user, bysh, like the labelsbx.ready. Tried every 0.2 s for at most 120 s; a start command that ends with a failure meanwhile ends the wait at once. Either way the sandbox fails withfailure_codeboot_failed, andfailuresays what the check last got and what the start command printed last. Needsstart: trueorstart_command(400invalid_start). Not given: the template is saved without waiting. - guest_mitigationsoptionalboolean
Whether the guest kernel keeps its mitigations against speculative execution. They guard the guest's kernel against processes in the same sandbox: turn them on when a sandbox runs code of several users who do not trust each other. Sandboxes are kept apart from each other by the host either way. Default: the node's setting (off). The setting is fixed when the kernel boots: the first sandbox with a setting other than its image template's starts like a new image (returned
starting), and a sandbox made from a snapshot keeps the snapshot's (asking for the other is 400). - tmpoptionaldiskoumemory
Where the sandbox's /tmp is.
disk: on its disk, as the rest.memory: a tmpfs of at most half of its memory, mounted before its first command (in a sandbox made from a template or an image, over what the template's guest had put there; by the guest's init where it starts from its disk): what is written there is the guest's memory, billed as memory, kept when it sleeps, and gone when it starts again from its disk. A sandbox made from a snapshot whose sandbox had it in memory has it so whatever this says.default: "disk" - runtimeoptional
Runtime settings of its machine and its commands, as a Compose file's
ulimits,sysctls,tmpfs,dnsandshm_sizeask for them (Runtime). For a sandbox made from an image: they make a template of the caller's own, built with them (with nothing said of the start, the image is started as its labels ask). Refused for one made from a snapshot or a template (400invalid_start), which goes on with what its machine has. - initoptional
What the sandbox's PID 1 is. Not given, or null: the platform's init, which starts the image's start command where there is one (
start,start_command, the image's labels).systemd: a whole system. The image's own systemd is PID 1 and the node's agent is one of its services: the user installs packages, starts services withsystemctl, uses cron and the journal and logs in by SSH, as on a machine. Nothing a create names is started (start,start_commandandreadyare refused with 400invalid_start), and the template is saved once systemd says the machine has booted. Withoutimage: the node's image of a whole system (--systemd-image; Ubuntu 24.04 with systemd and OpenSSH, sandboxd/images/ubuntu), refused with 400invalid_starton a node that has none. An image without systemd (/usr/lib/systemd/systemd) fails its build, withfailure_codeinvalid_image. Its template is anybody's who asks for the same image so, unless something of the caller's is in it (runtime,image_pull_secret). Refused for one made from a snapshot or a template (400invalid_start), which goes on as its machine was. Everything else a sandbox does works as for any sandbox: commands, files, terminals, the SSH gateway, sleep and wake, snapshots and forks, moves, egress rules (sandboxd/README.md, 「整个系统:systemd 当 PID 1」). - project_networkoptionalboolean
true: the sandbox is on its project's private network from before it runs anything, at the first of the addresses the node was left to spare for the project (setProjectNetwork): the answer says which (project_address). The project is the call's owner, so this is for a call the control plane makes for a project; on a node that stands alone a sandbox is nobody's, and is put on a network by being named in it. A sandbox is on no project's network unless it asks: defaultfalse. A copy made by a fork is on none, whatever its original is on. - imageoptionalstring
An OCI image reference (
python:3.12,ghcr.io/org/app@sha256:…), in a registry on the internet: one that gives the image to anybody, or one that wants a login, withimage_pull_secret. The first sandbox of an image is returnedstartingwhile the node pulls the image and builds a template; later ones start from the template. Default: the node's base image.maxLength: 512 - image_pull_secretoptionalstring
The name of a secret (
PUT /v1/secrets/{name}) that holds the credentials of the image's registry, for an image that is not public:username:passwordin printable ASCII, the user name ending at the first colon. A registry that takes a token alone documents the user name that goes with it (AWSfor ECR,oauth2accesstokenfor Google's, any name for GHCR). The node hands the credentials to the tool that pulls the image and to nothing else: nothing of them is in the sandbox, in its template or in the node's log, and what a registry says when it refuses them comes back without them (failure_coderegistry_auth_failed). The sandbox is made from a template of its owner's alone, which a create that names credentials finds and no other: the same image named without them is asked of its registry without a login, whether or not the node has the template. The secret has to exist (404secret_not_found), to be one that may go to the image's registry (itsallowed_hostscover the registry's host as the reference writes it, without its port,docker.iowhere it names none; 403secret_host_not_allowedotherwise) and to hold such a pair (400invalid_field), and it goes withimage(400invalid_fieldfor a sandbox made from none).maxLength: 128 - limitsoptionalobject
The shape a create asks for. Each part that is not given (or is null) is the node's base template's, which is what a sandbox that asks for none gets. Up to the most this node gives a sandbox,
max_vcpusandmax_memory_bytesofGET /internal/node(by default the host's CPUs, up to 32, and its memory; never less than the base template's shape); more is 400invalid_field. Each shape of an image is a template of its own: the first sandbox of a shape the node has not built that image in is returnedstartingwhile the node builds it, from the same image, and later ones are cloned from it. Withoutimage, another shape than the base template's is built from the node's base image. A sandbox made from asnapshotor atemplatehas that one's shape: asking for it is fine, for another 400invalid_field(paramlimits). The disk's size is the node's:disk_bytesis 400invalid_field. - nameoptionalstring
A name given by the caller to a sandbox, a snapshot, a volume or an SSH key: 1 to 63 lower-case letters, digits and hyphens, not starting or ending with a hyphen, and not starting with an id prefix (
sbx-,exe-,snap-,vol-,evt-,req-; an SSH key's not withsshkey-either). A DNS label that cannot be taken for an id. Unique among sandboxes, among snapshots, among volumes and among SSH keys.pattern: ^[a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?$ - metadataoptionalmap destring
Free key-value pairs for the caller's own use; lists of sandboxes filter by them. At most 64 keys of 1 to 64 characters, values of up to 1024. Not a place for secrets: metadata are stored in clear, and every set of them a sandbox has had while it used something is kept with its usage for thirteen months, also after the sandbox is deleted (
GET /v1/usagegroups and filters by them). - public_ports_exceptoptionalarray | null
Every port but these is public as well: its short preview URL opens it for anybody, as a port in
public_ports(how E2B makes a sandbox's ports; the control plane's E2B compatibility gives[49983], envd's port, which a sandbox token opens).[]: every port. Null (the default): onlypublic_ports. Ports are taken once each, in order. - on_expiryoptionaldeleteousleepouholdounull
What
expires_atdoes when it comes:deletethe sandbox (null or absent: this);sleep, put it to sleep whatever goes on in it, and keep it (itsexpires_atis null from then on, and a request wakes it as ever);hold, the same, held asleep (held_asleepis set then: a request does not wake it). How E2B pauses a sandbox when its time is up (the control plane's E2B compatibility). Another word is 400invalid_field.default: "delete" - held_asleepoptionalboolean | null
True: while it sleeps, a request to one of its ports does not wake it: the preview listener answers 502
sandbox_pausedin its place, as E2B's proxy answers for a paused sandbox (x-preview-ingress), and only a call of the API (or its own timer) wakes it. It is not put to sleep by this:POST /v1/sandboxes/{id}/sleepdoes that. False or null: as any sandbox. (E2B'spausewithout itsautoResume, which the control plane's E2B compatibility sets, and takes away at itsconnect.)default: false - stopoptionalobject | null
How the sandbox's start command is stopped before its machine is ended for good: before a restart (
POST /v1/sandboxes/{id}/restart) and a delete. The signal goes to the start command, which is then givengrace_msto end; what has not ended then goes with the machine. A machine that sleeps or is paused is not stopped: it goes on from where it was. Not given: the start command goes with its machine, as it always has. Unknown keys: 400unknown_field; a signal that is none of these, or a grace beyond ten minutes: 400invalid_field. - regionoptionalnaoueuouapounull
The region to make it in, read by the API and not passed on. Null or left out: the region the API itself runs in. Where no machine of that region can take it, the next region does; what has to go to one machine (made from a snapshot or with volumes, or sent again with the same
Idempotency-Key) goes there, whatever the region. A volume made from a backup is made in the backup's region: another is 400invalid_field. Not a region: 400unknown_region. The answer'sregionsays where it was made.
Returns
200
The command has ended: its result as JSON, or the event stream that led there. sandbox_id names the sandbox, which no longer exists.
string400
The request is not one this call takes. invalid_json: the body is not a JSON object; unknown_field: the body has a field this call does not take; unknown_parameter: the query has a parameter this call does not take; invalid_field: a field or query parameter has the wrong type or is out of range; invalid_name: name is not a valid name; invalid_env: env has a name or a value an environment cannot hold; invalid_metadata: metadata is over its limits; expires_in_the_past: expires_at is not in the future; invalid_egress: egress is not a set of rules: param names the part that is wrong; invalid_start: start, start_command and ready do not go together as given (ready without a start command, start: false with start_command), or one of them is given with init: "systemd", whose systemd starts what its units say, or init: "systemd" names no image on a node that has no image of a whole system (--systemd-image), or the sandbox is made from a snapshot or a template: param names the field; ambiguous_source: more than one of image, snapshot and template; invalid_image: image is not a reference to an image in a registry on the internet; invalid_path: a volume's path is not absolute or is /; missing_command: no command; no_such_user: user is not a user of the sandbox; invalid_idempotency_key: Idempotency-Key is empty or over 255 characters.
- exec_idoptionalstring
With
sandbox_movedofPOST …/run: the id of the command the call started and waited for, which goes on where the sandbox went: wait for it there through the control plane withGET …/exec/{exec_id}?wait_seconds=once the move is over. The same call made again starts the command a second time, unless it comes with the same Idempotency-Key.
401
missing_api_key, invalid_api_key, expired_api_key, invalid_token.
403
The credential may not do this. needs_api_key: a sandbox token cannot do this. spend_limit_reached: a spend limit was reached. secret_host_not_allowed: a secret would be sent to a host it may not go to: by egress.inject, or as image_pull_secret to the image's registry (param says which; allowed_hosts beside error says where it may go). account_share_reached: its account holds as much of this node's data drive as one account may (drive.accounts of GET /internal/node), and has not the room for the sandbox's memory and a gigabyte to write. Nothing was made.
- exec_idoptionalstring
With
sandbox_movedofPOST …/run: the id of the command the call started and waited for, which goes on where the sandbox went: wait for it there through the control plane withGET …/exec/{exec_id}?wait_seconds=once the move is over. The same call made again starts the command a second time, unless it comes with the same Idempotency-Key.
404
Something the request names does not exist. snapshot_not_found: no such snapshot; template_not_found: no such template; volume_not_found: a volume named in volumes does not exist; secret_not_found: a secret named in egress.inject, or the one image_pull_secret names, does not exist.
- exec_idoptionalstring
With
sandbox_movedofPOST …/run: the id of the command the call started and waited for, which goes on where the sandbox went: wait for it there through the control plane withGET …/exec/{exec_id}?wait_seconds=once the move is over. The same call made again starts the command a second time, unless it comes with the same Idempotency-Key.
409
The state of something stands in the way. name_taken: the name is taken; volume_in_use: a volume in volumes that is not shared is another sandbox's; duplicate_volume: a volume is listed twice in volumes; mount_path_taken: two volumes in volumes have one path; too_many_volumes: volumes has more that are not shared than the sandbox's machine has spare drives (eight; two for one made from a template or a snapshot of before there were eight); snapshot_lost: the snapshot's status is lost; no_project_address: project_network was asked for, and the node has no network of the project, or no address of it left to spare; command_lost: the command went away while the call waited for it; sandbox_failed: the sandbox could not be started: the message says why (its image cannot be pulled, for one); idempotency_key_reused: the key was used with another body; idempotency_in_progress: the first request with the key is still running. checkpoints_unavailable (param checkpoint): checkpoint is on, and this node takes no checkpoints (it does not copy its disks to an object store, or its memory is not in layers).
- exec_idoptionalstring
With
sandbox_movedofPOST …/run: the id of the command the call started and waited for, which goes on where the sandbox went: wait for it there through the control plane withGET …/exec/{exec_id}?wait_seconds=once the move is over. The same call made again starts the command a second time, unless it comes with the same Idempotency-Key.
503
Not available. not_served_here: egress rules were given, and this node cannot put rules in force (it has no nft); or project_network was asked for, and this node puts no sandbox on a project's network; or the sandbox is to be made from an image the node has no template of, and this node fetches no images (image_pulls of GET /internal/node says why; param is image); or key_missing: this node is keyed (src/seal.rs) and does not hold the key of the project whose it is, or the platform's (the message says which): the control plane gives it, and the same call is made again (Retry-After); or unavailable: a volume in volumes could not be attached in time, and the same call is made again (Retry-After): the guest's mount of it did not finish within 60 s (a Drive whose blocks do not come: its object store away, or its fetcher out of reach), or it is still being taken off the machine after such an attach, or it is a Drive that comes block by block and nothing answers for its blocks yet.
- exec_idoptionalstring
With
sandbox_movedofPOST …/run: the id of the command the call started and waited for, which goes on where the sandbox went: wait for it there through the control plane withGET …/exec/{exec_id}?wait_seconds=once the move is over. The same call made again starts the command a second time, unless it comes with the same Idempotency-Key.
504
The caller went away. caller_gone: the caller hung up.
- exec_idoptionalstring
With
sandbox_movedofPOST …/run: the id of the command the call started and waited for, which goes on where the sandbox went: wait for it there through the control plane withGET …/exec/{exec_id}?wait_seconds=once the move is over. The same call made again starts the command a second time, unless it comes with the same Idempotency-Key.
default
Any other failure, in the same shape. internal (500): the node failed; the message says no more, and the node's log has the reason under the request's id. unavailable (503, retryable): no_capacity, every network slot of the node is in use; memory_full, a machine the call has to start (made, woken, booted from its disk, resumed, rolled back, built) does not fit in the host's memory beside what the machines that run on it are promised, and nothing paused or idle could be put to sleep to make room for it (memory of the node); drive_full, the call would have a template built and the node's data drive has no room for one (drive of the node); unavailable, the node is shutting down, the sandbox was still starting after 10 minutes, or it did not answer, or it is being moved to this node (with Retry-After: 1); fenced, the node's lease fences the sandbox (Node.lease). moved (409): the sandbox was moved to another node, which to names.
- exec_idoptionalstring
With
sandbox_movedofPOST …/run: the id of the command the call started and waited for, which goes on where the sandbox went: wait for it there through the control plane withGET …/exec/{exec_id}?wait_seconds=once the move is over. The same call made again starts the command a second time, unless it comes with the same Idempotency-Key.