temperDocs
Menu

API reference

Exec

Execution and files: run commands synchronously, read and write files, background processes (follow output by long polling or WebSocket, with reconnection after a disconnect).

Run a command synchronously

POST/v1/environments/{id}/exec

command is run with bash -lc (the same environment as the Agent's login shell); argv is executed as is. Provide exactly one of the two. The default working directory is the agent user's home directory. The call returns when the process exits; a process exceeding timeout_secs is killed inside the VM (timed_out: true, HTTP is still 200). The control plane waits a further 30 seconds as a fallback, after which it returns 503 exec_timeout. stdout and stderr each return at most 1 MiB (the rest is cut off and *_truncated is set), decoded as UTF-8 (invalid bytes replaced with U+FFFD). The process environment is first loaded from /etc/temper/agent.env and the Agent package's /opt/agent/env; env cannot override variables already set in those two files. If the environment is not running it is woken first; see "Execution and files" in the introduction.

Request body application/json · ExecRequest

FieldTypeDescription
argvarray of string

Executed as is, for example ["python3", "-c", "print(1)"].

commandstring

Run with bash -lc, for example ls -la | head.

envmap of string

Extra environment variables. Names consist of letters, digits and underscores and do not start with a digit; variables already set in agent.env or the Agent package's env cannot be overridden.

cwdstring

Working directory (a path inside the runtime unit); defaults to the agent user's home directory.

timeout_secsinteger
stdinstring

Standard input for the process (closed afterwards); if omitted, stdin is /dev/null.

Responses

  • 200The process exited (a non-zero exit code is still 200) ExecResult
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 415Missing `Content-Type: application/json` (`unsupported_media_type`)
  • 422The JSON does not match the schema: a missing field, a wrong type or enum value, or an unknown field (`invalid_body`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Read a file

GET/v1/environments/{id}/files

Returns the raw bytes (application/octet-stream), streamed as they are read. 404 if it does not exist, 400 if it is a directory, 403 if the agent user cannot read it. An error after streaming has begun (the VM disconnects) can only be signalled by dropping the connection: the client sees an incomplete transfer.

Parameters

ParameterInTypeDescription
pathrequiredquerystring

A path inside the runtime unit. Relative paths are resolved against the agent user's home directory (also the default working directory). Permissions and symbolic links are evaluated as the agent user inside the runtime unit sees them, and paths cannot escape the runtime unit. Must not be empty or contain NUL.

Responses

  • 200File contents string
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 403The agent user inside the runtime unit lacks permission (cannot read, write, or create the parent directories)
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Write a file

PUT/v1/environments/{id}/files

The request body is the content (at most 1 GiB; Content-Type is not checked, application/octet-stream is recommended). Overwrites any existing file. 404 if the parent directory does not exist; with mkdir=true the parent directories are created first (403 if they cannot be); 400 if the target is a directory; 403 if it cannot be written.

Parameters

ParameterInTypeDescription
pathrequiredquerystring

A path inside the runtime unit. Relative paths are resolved against the agent user's home directory (also the default working directory). Permissions and symbolic links are evaluated as the agent user inside the runtime unit sees them, and paths cannot escape the runtime unit. Must not be empty or contain NUL.

mkdirqueryboolean

Create the parent directories first (mkdir -p).

Request body application/octet-stream

Responses

  • 201Written WriteFileResult
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 403The agent user inside the runtime unit lacks permission (cannot read, write, or create the parent directories)
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 413The request body exceeds the size limit (`payload_too_large`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Delete a file or directory

DELETE/v1/environments/{id}/files

404 if it does not exist; 400 if it is a directory and recursive=true was not given. For a symbolic link only the link itself is deleted.

Parameters

ParameterInTypeDescription
pathrequiredquerystring

A path inside the runtime unit. Relative paths are resolved against the agent user's home directory (also the default working directory). Permissions and symbolic links are evaluated as the agent user inside the runtime unit sees them, and paths cannot escape the runtime unit. Must not be empty or contain NUL.

recursivequeryboolean

Delete a directory together with its contents (rm -rf).

Responses

  • 204Deleted
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 403The agent user inside the runtime unit lacks permission (cannot read, write, or create the parent directories)
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

List a directory

GET/v1/environments/{id}/files/list

One level, not recursive, sorted by name, at most 10000 entries (the rest are cut off and truncated is set). 404 if it does not exist, 400 if it is not a directory.

Parameters

ParameterInTypeDescription
pathrequiredquerystring

A path inside the runtime unit. Relative paths are resolved against the agent user's home directory (also the default working directory). Permissions and symbolic links are evaluated as the agent user inside the runtime unit sees them, and paths cannot escape the runtime unit. Must not be empty or contain NUL.

Responses

  • 200Directory contents DirectoryListing
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 403The agent user inside the runtime unit lacks permission (cannot read, write, or create the parent directories)
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

List background processes

GET/v1/environments/{id}/processes

Includes exited processes that have not been deleted. Not paginated (at most 64).

Responses

  • 200Processes ProcessList
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Start a background process

POST/v1/environments/{id}/processes

Same parameters as exec, except that timeout_secs defaults to 0 (no limit), and stdin: true means you will write stdin later through attach (otherwise stdin is /dev/null). The process is independent of the request; its output is kept in the VM's memory (the most recent 8 MiB per process) and can be read with /output or /attach. Process records live in the VM's memory: they survive a suspend and resume, but are lost when the VM is replaced (upgrade, failure); after that, queries return 404. Each environment keeps at most 64 background processes (including exited ones that have not been deleted); beyond that, 429 too_many_processes.

Request body application/json · SpawnRequest

FieldTypeDescription
argvarray of string
commandstring
envmap of string
cwdstring
timeout_secsinteger

Maximum run time, after which the process is killed; 0 = no limit

stdinboolean

You will write stdin later through attach; otherwise stdin is /dev/null

Responses

  • 201Started Process
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 415Missing `Content-Type: application/json` (`unsupported_media_type`)
  • 422The JSON does not match the schema: a missing field, a wrong type or enum value, or an unknown field (`invalid_body`)
  • 429A count limit was reached (this is not rate limiting; retrying will not help until something is released)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Get a background process

GET/v1/environments/{id}/processes/{pid}

Whether it is running, its exit status, and the output offset reached so far.

Responses

  • 200Process Process
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Kill and forget a process

DELETE/v1/environments/{id}/processes/{pid}

Kills the process if it is still running, then deletes its record and retained output.

Responses

  • 204Deleted
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Get output (long polling)

GET/v1/environments/{id}/processes/{pid}/output

Reads from offset since. Output already available is returned immediately; otherwise the call waits up to wait_secs seconds for the first chunk, then waits another 0.1 seconds to collect anything that follows right after it. At most about 4 MiB is returned per call. Pass next back as since on the next call. If since is earlier than the oldest output the VM still retains (process.output_start), output starts from the oldest retained byte (the first chunk's offset will be greater than since). Once the process has exited, exited: true and exit holds the exit status. Offsets are in bytes (stdout and stderr combined); data is decoded as UTF-8.

Parameters

ParameterInTypeDescription
sincequeryinteger (int64)

Byte offset to start from.

wait_secsqueryinteger

Maximum seconds to wait when there is no new output; values above 30 are treated as 30.

Responses

  • 200A chunk of output ProcessOutput
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Follow output, write stdin and send signals in real time (WebSocket)

GET/v1/environments/{id}/processes/{pid}/attach

A WebSocket upgrade (Connection: Upgrade, Upgrade: websocket), authenticated like every other endpoint (Authorization header). The server connects to the VM and confirms the process exists before upgrading, so errors such as 404, 409 and 503 are returned as ordinary HTTP responses; a request without the upgrade headers gets 400. Disconnecting does not affect the process: reconnect with the same process id and the last next as since to continue where you left off. To "run a command over WebSocket", first POST /processes (with stdin: true if you want to write stdin), then attach.

The server sends only JSON text messages, distinguished by type:

  • {"type": "attached", "process": Process}: always the first message;
  • {"type": "output", "stream": "stdout" | "stderr", "offset": <byte offset>, "data": "<UTF-8 text>"};
  • {"type": "exit", "exit": ProcessExit, "next": <offset>}: the process exited; the server then closes the connection;
  • {"type": "error", "message": "...", "next"?: <offset>}: the VM disconnected (with next; the server then closes the connection and you can reconnect), or a message from the client could not be understood (without next; the connection stays open).

The client sends JSON text messages (fields can be combined): {"stdin": "<text>"} writes to stdin (requires stdin: true at spawn), {"stdin_eof": true} closes stdin, and {"signal": "INT"} sends a signal (TERM / KILL / INT / HUP). See AttachServerMessage and AttachClientMessage for the message schemas.

Parameters

ParameterInTypeDescription
sincequeryinteger (int64)

Byte offset to start replaying from.

Responses

  • 101Upgraded to WebSocket; messages are then exchanged in the format described above. The `application/json` here describes each text message the server sends (`AttachServerMessage`), not a response body; for messages the client sends, see `AttachClientMessage`.
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).

Send a signal to a background process

POST/v1/environments/{id}/processes/{pid}/signal

Request body application/json · SignalRequest

FieldTypeDescription
signalrequiredSignal

Responses

  • 204Sent
  • 400Invalid parameters: validation failed, the body is not valid JSON, or the query string could not be parsed (all returned in the same JSON shape).
  • 401Missing, invalid or revoked key
  • 404Does not exist, or does not belong to this developer (`no such resource`); for a nonexistent route `message` is `no such route`
  • 409The environment's actual state is failed (`environment_failed`; check its events), or it was suspended for exceeding a monthly usage limit (`limit_exceeded`; see `setLimit`)
  • 415Missing `Content-Type: application/json` (`unsupported_media_type`)
  • 422The JSON does not match the schema: a missing field, a wrong type or enum value, or an unknown field (`invalid_body`)
  • 500Internal error (details are recorded only in server logs)
  • 503Temporarily unable to complete the request; `error` tells the cases apart: `environment_not_placed` (not placed on a host within 15 seconds), `environment_not_running` (not up within 90 seconds), `host_unavailable` (host offline), `guest_unavailable` (the VM cannot be reached or disconnected midway), `exec_failed` (the process could not be started inside the VM), `exec_timeout` (a synchronous exec still had not finished after its timeout), `file_operation_failed` (a file operation hit an unexpected error).