HeavenDocs

Endpoints

Run a command inside a Computer, move files in and out, or download its whole disk, without SSH.

All four act inside the Computer as its login user, with the same access check as SSH.

Over SSH, the same things are ssh NAME@heaven.dev CMD, scp and ssh export+NAME@heaven.dev.

Run a command

POST/v1/computer/exec

Runs one command inside a Computer as its login user, and returns its output and exit code. The command has 30 seconds and 1 MiB of output, or an hour when streamed.

The request returns conflict before anything runs if the Computer is paused or stopped, held for an unpaid pool, or its image couldn't be prepared. For a paused Computer, the error names resume.

If the request ends before the command does, the command is stopped. To keep a command running after the request ends, start it in the background: nohup ./job >job.log 2>&1 &.

Stream the output

With Accept: application/x-ndjson, the output arrives as it's written, one line per chunk: {"stdout":BASE64}, {"stderr":BASE64}, then {"exit_code":N}. A streamed command can run for an hour, with no output limit. If the connection drops after output began, the last line is {"error":MESSAGE}, and the outcome is unknown.

Send large input

Put the fields in the query and the input in the body, with a type such as application/octet-stream. Any body that isn't JSON is the command's input. The query must include computer, or the request returns invalid. The input streams, with no size limit.

A command is never run twice. If the response is lost, the outcome is unknown. Check inside the Computer before running it again.

Body

computer string required

A Computer: its name or ID.

command string required

The command line, as you'd type it after ssh NAME.

stdin string

Its standard input in base64, at most 1 MiB. Send more as the request body, with the fields in the query.

Response

output base64
Standard output and error together, at most 1 MiB.
exit_code integer
The command's exit status.
  • An API key needs exec in its commands.
Request
curl https://heaven.dev/v1/computer/exec \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  --json '{"computer": "my-site", "command": "uname -a"}'
200
{
  "version": 1,
  "data": {
    "output": "TGludXggbXktc2l0ZSA2Ljgu…",
    "exit_code": 0
  }
}
Stream
curl https://heaven.dev/v1/computer/exec \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  -H "Accept: application/x-ndjson" \
  --json '{"computer": "my-site", "command": "apt-get update"}'
200 application/x-ndjson
{"stdout":"SGl0OjEgaHR0cDovL2FyY2hpdmUu…"}
{"stdout":"UmVhZGluZyBwYWNrYWdlIGxpc3Rz…"}
{"exit_code":0}
Unpack a large archive
curl --data-binary @site.tar \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  'https://heaven.dev/v1/computer/exec?computer=my-site&command=tar%20xf%20-%20-C%20/srv'

Download a file

GET/v1/computer/exec?computer=NAME&download=PATH

Returns the file as application/octet-stream, streamed, with no size limit. A missing file, a directory, or a file the login user can't read returns an error before any data is sent. A Computer that can't run a command is refused the same way. An API key needs exec in its commands.

Query

computer string required
The Computer's name or ID.
download string required
The file's path. A relative path starts in the login user's home directory.
Request
curl -f -o app.log \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  'https://heaven.dev/v1/computer/exec?computer=my-site&download=/var/log/app.log'

Upload a file

POST/v1/computer/exec?computer=NAME&upload=PATH

Writes the request body to the path. Heaven writes it to a new file and moves it into place once it's complete, so an interrupted upload leaves the old file as it was. A Computer that can't run a command is refused the same way. An API key needs exec in its commands.

Query

computer string required
The Computer's name or ID.
upload string required
The path to write the file to.
mode string
Octal permissions, such as 0644. Defaults to the replaced file's permissions, or 0644 for a new file.
Request
curl -f --data-binary @app.tar \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  'https://heaven.dev/v1/computer/exec?computer=my-site&upload=/srv/app.tar&mode=0644'
200
{"version": 1, "data": {"path": "/srv/app.tar", "bytes": 1048576}}

Export a disk

GET/v1/computer/export

Downloads a Computer's whole disk, running or stopped, as a raw ext4 image compressed with zstd.

It works even when the Computer is held for an unpaid pool, and it doesn't start the Computer.

  • Who can export: the Computer's owner, the admins of the team that owns it, and the organization's billing owner and admins. Root access, a shared admin role and support access aren't enough. An API key needs export named in its commands. An SSH key limited to a tag or one Computer can't export.
  • Check that it finished. A download is complete only if the response ends normally. If it was cut short and curl reports an error, delete the file and export again.
  • One at a time. Only one export of a Computer runs at a time.

unzstd unpacks it to a sparse file about the size of the Computer's data, which you can mount or boot elsewhere.

Query

computer string required

A Computer: its name or ID.

  • An API key needs export in its commands.
Request
curl -f -o my-site.img.zst \
  -H "Authorization: Bearer $HEAVEN_API_KEY" \
  'https://heaven.dev/v1/computer/export?computer=my-site'
unzstd my-site.img.zst