Skip to main content

Rexec SDK & API Reference

Official clients for the Rexec sandbox API (files + terminals). Shared REST + WebSocket surface across languages. SDK version line: v1.1.0+.

Upstream (source of truth):
SDK.md · SDK_GETTING_STARTED.md · SDK_PUBLISHING.md

Hosted base URLhttps://rexec.sh
AuthAuthorization: Bearer <token>
MonorepoPipeOpsHQ/Rexec (sdk/{js,python,go,rust,ruby,dotnet,java,php})
Runnable examplesPipeOpsHQ/sandbox-example

Available SDKs

LanguagePackageInstallImport notes
JS / TSpipeops-rexecnpm install pipeops-rexecimport { RexecClient } from 'pipeops-rexec'
Pythonpipeops-rexecpip install pipeops-rexecfrom rexec import RexecClient
Gorexec-gogo get github.com/PipeOpsHQ/[email protected]import rexec "github.com/PipeOpsHQ/rexec-go"
Rustpipeops-rexeccargo add pipeops-rexecuse rexec::{…}
Rubypipeops-rexecgem install pipeops-rexecrequire "rexec"
C# / .NETPipeOps.Rexecdotnet add package PipeOps.Rexecusing Rexec;
Java / Kotlinio.pipeops:rexec:1.1.0Maven/Gradleimport io.pipeops.rexec.*
PHPpipeopshq/rexeccomposer require pipeopshq/rexec:^1.1use Rexec\RexecClient

PHP fallback (VCS):

composer config repositories.rexec-php vcs https://github.com/PipeOpsHQ/rexec-php
composer require pipeopshq/rexec:^1.1

Auth

  1. API token — Rexec UI → Settings → API Tokens (production).
  2. Guest JWTPOST /api/auth/guest with { "username", "email" } (smoke tests only).

SDKs attach Authorization: Bearer <token> on REST and terminal WebSockets. Use env vars (REXEC_URL, REXEC_TOKEN) — never hardcode secrets.


Shared API surface (sandboxes)

Sandboxes (HTTP: /api/containers)

MethodHTTPNotes
ListGET /api/containersBody often { containers: [...] | null, count, limit }. SDKs return a plain array.
CreatePOST /api/containers { image, name? }May return status: "creating" (async). Prefer image aliases.
GetGET /api/containers/:idPoll until running if you need a shell.
StartPOST /api/containers/:id/start
StopPOST /api/containers/:id/stop
DeleteDELETE /api/containers/:idAlways clean up in finally / defer.

Files (per sandbox)

MethodHTTP
List dirGET /api/containers/:id/files/list?path=
ReadGET /api/containers/:id/files?path=
WritePOST /api/containers/:id/files (content often base64; language-dependent)
MkdirPOST /api/containers/:id/files/mkdir (language-dependent)
DeleteDELETE /api/containers/:id/files?path=

Terminal

Connectwss://<host>/ws/terminal/:id?cols=&rows= + Bearer
Helperswrite, onData, resize (JSON { type: "resize", cols, rows }), close
No primary HTTP exec()

Hosted Rexec does not document a first-class exec() RPC. Run commands via the terminal WebSocket.


Image aliases

PreferAvoid on hosted
ubuntu, ubuntu-24, debian, alpine, …ubuntu:24.04, arbitrary Hub tags

Catalog: GET /api/images.


Sandbox model

FieldDescription
idSandbox id
nameDisplay name
imageAlias used at create
statuscreating | running | stopped | error
created_at / started_atTimestamps
labels / environmentOptional maps

Lifecycle

create → creating → running ⇄ stopped → delete
↘ error

List payload quirk

{ "containers": [ /* or null */ ], "count": 0, "limit": 1 }

SDKs normalize so callers never special-case null.


Client construction

Prefer sandboxes (v1.1.0+). containers is a deprecated alias to the same service.

LangConstructSandboxes (preferred)
JSnew RexecClient({ baseURL, token })client.sandboxes.list() / .create({ image, name? })
Pythonasync with RexecClient(url, token)await client.sandboxes.list() / .create(image=…)
Gorexec.NewClient(url, token)client.Sandboxes.List(ctx) / .Create(ctx, &CreateSandboxRequest{…})
RustRexecClient::new(url, token)client.sandboxes().list().await / .create(…)
RubyRexec::Client.new(url, token)client.sandboxes.list / .create(…)
.NETnew RexecClient(url, token)await client.Sandboxes.ListAsync() / .CreateAsync(…)
Javanew RexecClient(url, token)client.sandboxes().list() / .create(…)
PHPnew Rexec\RexecClient($url, $token)$client->sandboxes()->list() / ->create(…)

Wait until running (pattern)

async function waitRunning(client: RexecClient, id: string, ms = 120_000) {
const deadline = Date.now() + ms;
while (Date.now() < deadline) {
const s = await client.sandboxes.get(id);
if (s.status === 'running') return s;
if (s.status === 'error') throw new Error('sandbox failed');
await new Promise((r) => setTimeout(r, 2000));
}
throw new Error('timeout waiting for running');
}

Complete, multi-language happy paths (create → poll → get → delete + cleanup):
PipeOpsHQ/sandbox-example


Errors

SDKType
JSRexecError (statusCode, message)
PythonRexecAPIError, RexecConnectionError
Go*rexec.APIError
Rustrexec::Error
RubyRexec::APIError
.NET / Java / PHPRexecException

Examples & E2E

git clone https://github.com/PipeOpsHQ/sandbox-example.git
cd sandbox-example
export REXEC_TOKEN=rexec_... # never commit
# See per-language folders: javascript, python, go, ruby, rust, java, php, dotnet

Monorepo smoke tests

cd scripts/sdk-e2e # in PipeOpsHQ/Rexec
# list → create(image: ubuntu) → get → delete
# Runners: test-js.mjs, test_py.py, go/, rust_e2e, test_rb.rb,
# dotnet_e2e, java_e2e, test_php.php

ResourceURL
Producthttps://rexec.sh
In-app SDK docshttps://rexec.sh/docs/sdk
Monorepohttps://github.com/PipeOpsHQ/Rexec
Sandbox exampleshttps://github.com/PipeOpsHQ/sandbox-example
npmhttps://www.npmjs.com/package/pipeops-rexec
PyPIhttps://pypi.org/project/pipeops-rexec/
crates.iohttps://crates.io/crates/pipeops-rexec
RubyGemshttps://rubygems.org/gems/pipeops-rexec
NuGethttps://www.nuget.org/packages/PipeOps.Rexec
Mavenhttps://repo1.maven.org/maven2/io/pipeops/rexec/
Go modulehttps://github.com/PipeOpsHQ/rexec-go
PHP source (Packagist)https://github.com/PipeOpsHQ/rexec-php