NodeOps
UK

Execution & Files

Run commands inside a sandbox and transfer files in and out.


At a glance

  • Base URL: https://api.sb.createos.sh
  • Auth: X-Api-Key: <token> header. Get a token
  • Response envelope: JSend, {"status": "...", "data": ...}

POST /v1/sandboxes/{id}/exec

Run a command inside a running sandbox, either buffered (default) or as a live NDJSON stream.

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id

Query parameters

ParameterTypeDefaultDescription
streambooleanfalseWhen true, response is application/x-ndjson (one ExecStreamEvent per line). Equivalent to setting stream: true in the request body.

Request body

FieldTypeRequiredDescription
cmdstringYesProgram to execute (absolute path or PATH-resolved).
argsstring[]NoArgument list.
stdinstringNoOptional stdin passed to the process.
envobjectNoPer-exec environment variable overrides. Every key must have been declared in the sandbox's envs at create time; you can override a value but cannot introduce new keys. Undeclared keys return 400.
streambooleanNoEquivalent to ?stream=true query parameter.

Note: Background processes must detach (redirect stdio + &) or the exec blocks until they exit.


Buffered mode (default)

Returns after the command exits. Response is a standard JSend success envelope with data.result.

Example request

Bash
1curl -X POST https://api.sb.createos.sh/v1/sandboxes/sb-01K.../exec \
2 -H "X-Api-Key: $CREATEOS_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{"cmd": "/usr/bin/python3", "args": ["-c", "print(1+1)"]}'

Example response

JSON
1{
2 "status": "success",
3 "data": {
4 "result": {
5 "stdout": "2\n",
6 "stderr": "",
7 "exit_code": 0
8 },
9 "exec_ms": 124.7
10 }
11}

Streaming mode (?stream=true)

The server emits one JSON object per line over Content-Type: application/x-ndjson (HTTP/1.1 chunked). The terminal frame carries exit_code. Heartbeat lines ({"hb":true}) are emitted every 5 seconds so a dead client is detected and the in-VM command killed within ~5 s of disconnect.

Each line is an ExecStreamEvent:

FieldDescription
stdoutstdout chunk (string)
stderrstderr chunk (string)
hbHeartbeat marker; clients should ignore
exit_codeTerminal frame, last event sent
errorAgent-level failure (couldn't start command)

In any one event, exactly one field is meaningful; the rest are zero/absent.

Example request

Bash
1curl -X POST "https://api.sb.createos.sh/v1/sandboxes/sb-01K.../exec?stream=true" \
2 -H "X-Api-Key: $CREATEOS_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{"cmd": "/bin/bash", "args": ["-c", "for i in 1 2 3; do echo $i; sleep 1; done"]}'

Example stream output

{"stdout":"1\n"}
{"hb":true}
{"stdout":"2\n"}
{"stdout":"3\n"}
{"exit_code":0}

Notable errors: 404 sandbox not found or not running, 400 undeclared env key.


PUT /v1/sandboxes/{id}/files

Upload a file into the sandbox.

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id

Query parameters

ParameterTypeRequiredDescription
pathstringYesAbsolute path inside the VM. .. is rejected. Parent directories are auto-created.

Request body

Raw file bytes. Content-Type: application/octet-stream. Maximum size: 500 MiB.

Example request

Bash
1curl -X PUT "https://api.sb.createos.sh/v1/sandboxes/sb-01K.../files?path=/workspace/main.py" \
2 -H "X-Api-Key: $CREATEOS_API_KEY" \
3 -H "Content-Type: application/octet-stream" \
4 --data-binary @main.py

Example response

JSON
1{
2 "status": "success",
3 "data": {}
4}

Path rules: Path must be absolute (start with /). Relative paths like script.py are rejected with 400.

Notable errors: 400 invalid path or file too large, 404 sandbox not found.


GET /v1/sandboxes/{id}/files

Download a file from the sandbox.

Auth required: Yes

Path parameters

ParameterDescription
idSandbox id

Query parameters

ParameterTypeRequiredDescription
pathstringYesAbsolute path inside the VM. .. is rejected.

Example request

Bash
1curl -o result.csv \
2 "https://api.sb.createos.sh/v1/sandboxes/sb-01K.../files?path=/workspace/result.csv" \
3 -H "X-Api-Key: $CREATEOS_API_KEY"

The response body is the raw file bytes (Content-Type: application/octet-stream).

Notable errors: 404 sandbox or file not found.


Tip: tarball directory transfer

To move a whole directory, tar it on the client, upload the bundle, then unpack inside the sandbox:

Bash
1# Upload directory
2tar -c mydir | curl -X PUT \
3 "https://api.sb.createos.sh/v1/sandboxes/sb-01K.../files?path=/tmp/bundle.tar" \
4 -H "X-Api-Key: $CREATEOS_API_KEY" \
5 -H "Content-Type: application/octet-stream" \
6 --data-binary @-
7
8# Unpack inside sandbox
9curl -X POST https://api.sb.createos.sh/v1/sandboxes/sb-01K.../exec \
10 -H "X-Api-Key: $CREATEOS_API_KEY" \
11 -H "Content-Type: application/json" \
12 -d '{"cmd": "tar", "args": ["-C", "/workspace", "-xf", "/tmp/bundle.tar"]}'

100,000+ Builders. One Platform.

Get product updates, builder stories, and early access to features that help you ship faster.

NodeOps is the agentic operating system for production AI. CreateOS is its flagship product.