Console Playground

TypeScript Esclarecimentos de documentação

Início Rápido

Execute código em mais de 42 linguagens com uma única chamada API. Veja como começar:

1

Obtenha sua chave API

Cadastre-se em unsandbox.com/console para obter suas credenciais API.

2

Faça sua primeira requisição

Envie código para o endpoint de execução e receba resultados instantaneamente.

3

Construa algo incrível

Use nossa execução em sandbox para agentes de machine learning, playgrounds de código, ferramentas educacionais e mais.

Instalação

Baixar

# Linux x86_64
wget https://unsandbox.com/downloads/un
chmod +x un

# Move to PATH (optional)
sudo mv un /usr/local/bin/

Compilar do código fonte

# Requirements: GCC, libcurl, libwebsockets
sudo apt-get install build-essential libcurl4-openssl-dev libwebsockets-dev

# Compile
wget https://unsandbox.com/downloads/un.c
gcc -Wall -O2 -o un un.c -lcurl -lwebsockets

Bibliotecas SDK (un-inception)

Para linguagens que precisam de acesso programático, use nossas implementações de SDK:

# Python - download un.py
wget https://unsandbox.com/cli/inception/un.py
python un.py script.py

# JavaScript - download un.js
wget https://unsandbox.com/cli/inception/un.js
node un.js script.py

# Go - download un.go
wget https://unsandbox.com/cli/inception/un.go
go run un.go script.py

Ver todos os 42 SDKs de linguagens →

Autenticação

Todas as requisições API requerem autenticação por assinatura HMAC-SHA256 para segurança.

Obrigatório

Header Description
Authorization Bearer <public_key> (your unsb-pk-xxxx key)
X-Timestamp Unix timestamp in seconds (±5 min tolerance)
X-Signature HMAC-SHA256 signature (lowercase hex)
Content-Type application/json

Formato da Assinatura

HMAC-SHA256(secret_key, timestamp:METHOD:path:body)

Exemplo de string de assinatura:

1699564800:POST:/execute:{"language":"python","code":"print('hi')"}

Sua chave secreta nunca é transmitida. O servidor verifica assinaturas usando sua chave criptografada.

Executado em (CLI)

Execute qualquer arquivo de código. A linguagem é detectada automaticamente pela extensão do arquivo ou shebang.

Uso Básico

# Python
un hello.py

# JavaScript
un app.js

# Rust (compiles and runs)
un main.rs

# C (compiles and runs)
un program.c

# Go
un main.go

Com Opções

# Extended timeout (5 minutes)
un --ttl 300 long_script.py

# With more CPU/RAM (4 vCPUs, 8GB RAM)
un -v 4 heavy_compute.py

# Maximum resources (8 vCPUs, 16GB RAM)
un --vcpu 8 ml_training.py

Resposta

A saída é transmitida diretamente para seu terminal:

$ un hello.py
Hello from unsandbox!

$ echo $?
0

Equivalente API

POST /execute

{
  "success": true,
  "stdout": "Hello from unsandbox!\n",
  "stderr": "",
  "exit_code": 0,
  "language": "python",
  "total_time_ms": 127
}
Executar Código (CLI)

Execute trechos de código diretamente da linha de comando usando a flag -s.

Uso Básico

# Python
un -s python 'print("Hello World")'

# Bash
un -s bash 'echo "Hello" && date'

# JavaScript
un -s javascript 'console.log(Math.PI)'

# Ruby
un -s ruby 'puts 2 ** 100'

# Go (full program)
un -s go 'package main; import "fmt"; func main() { fmt.Println("Hi") }'

Código Multilinha

# Using heredoc
un -s python <<'EOF'
import json
data = {"name": "unsandbox", "version": 2}
print(json.dumps(data, indent=2))
EOF

Linguagens Suportadas

Qualquer uma das 42 linguagens suportadas funciona com -s:

un -s python 'print(42)'
un -s javascript 'console.log(42)'
un -s typescript 'console.log(42 as number)'
un -s ruby 'puts 42'
un -s php '<?php echo 42;'
un -s perl 'print 42'
un -s lua 'print(42)'
un -s rust 'fn main() { println!("42"); }'
un -s c 'int main() { printf("42"); return 0; }'
un -s cpp 'int main() { std::cout << 42; }'
un -s java 'class M { public static void main(String[] a) { System.out.println(42); }}'
un -s kotlin 'fun main() = println(42)'
un -s go 'package main; import "fmt"; func main() { fmt.Println(42) }'
un -s haskell 'main = print 42'
un -s elixir 'IO.puts 42'
un -s julia 'println(42)'
un -s r 'print(42)'
Variáveis de Ambiente

Passe variáveis de ambiente para seu código usando a flag -e.

Variável Única

un -e DEBUG=1 script.py
un -e API_KEY=secret app.js

Múltiplas Variáveis

un -e DEBUG=1 -e NAME=World -e COUNT=42 script.py

Com Código Inline

un -e NAME=Claude -s python 'import os; print(f"Hello {os.environ[\"NAME\"]}")'

un -e X=10 -e Y=20 -s bash 'echo "Sum: $((X + Y))"'

Exemplo

# config_demo.py
import os

debug = os.environ.get('DEBUG', '0')
name = os.environ.get('NAME', 'World')

if debug == '1':
    print(f"Debug mode enabled")
print(f"Hello {name}!")

Executar

$ un -e DEBUG=1 -e NAME=unsandbox config_demo.py
Debug mode enabled
Hello unsandbox!
Arquivos de Entrada

Teleporte arquivos para o sandbox. O CLI usa a flag -f; a API usa o array input_files.

Uso do CLI

# Single file
un -f data.csv process.py

# Multiple files
un -f data.csv -f config.json -f image.png script.py

# Large files (skip confirmation)
un -f large_dataset.parquet -y ml_training.py

Limites

  • Número máximo de arquivos
  • Tamanho total máximo
  • Tamanho máximo de arquivo único
# Files are placed in working directory
un -f data.csv -s python 'print(open("data.csv").read())'

# Process multiple input files
un -f input.json -f config.yaml script.py
{
  "language": "python",
  "code": "print(open('data.csv').read())",
  "input_files": [
    {
      "filename": "data.csv",
      "content": "bmFtZSxhZ2UKQWxpY2UsMzAKQm9iLDI1"
    }
  ]
}

O conteúdo deve estar codificado em Base64.

Os arquivos são colocados no diretório de trabalho:

  • Python: open('data.csv')
  • Node.js: fs.readFileSync('data.csv')
  • Ruby: File.read('data.csv')
  • Go: os.ReadFile("data.csv")
  • Bash: cat data.csv
Artefatos

Teleporte arquivos para fora do sandbox. Use -a para coletar artefatos de /tmp/artifacts/ ou obter binários compilados.

Coletar Arquivos Gerados

# Files in /tmp/artifacts/ are collected
un -a -o ./outputs script.py

Binário pré-compilado

# Compile C and get the binary
un -a -o ./bin main.c

# Compile Rust and get the binary
un -a -o ./bin main.rs

# Compile Go and get the binary
un -a -o ./bin main.go

Compilação WebAssembly

# Compile to WASM (supported languages)
un --wasm -o ./wasm main.c
un --wasm -o ./wasm main.rs

Exemplo: Gerar e Coletar

# generate_report.py
import json
import os

os.makedirs('/tmp/artifacts', exist_ok=True)

data = {"users": 100, "revenue": 50000}
with open('/tmp/artifacts/report.json', 'w') as f:
    json.dump(data, f, indent=2)

print("Report generated!")

Executar

$ un -a -o ./reports generate_report.py
Report generated!

$ ls ./reports
report.json
Modos de Rede

Zero Trust (padrão)

Isolamento completo de rede. Sem acesso à internet.

# Default - no network
un script.py

Semi-Confiável

Acesso à internet via proxy de saída.

# Enable network access
un -n semitrusted script.py

# Or with sessions
un session -n semitrusted

Casos de Uso

# Zero Trust - safe for untrusted code
un -s python 'print("Isolated execution")'

# Semi-Trusted - when you need network
un -n semitrusted -s python '
import requests
r = requests.get("https://api.github.com")
print(r.status_code)
'

# Semi-Trusted session for development
un session -n semitrusted --shell bash
Criar Sessão

Inicie uma sessão de shell interativo em um contêiner sandbox.

Sessão Básica

# Default bash shell
un session

# Choose your shell
un session --shell zsh
un session --shell fish

Sessões REPL

# Python REPL
un session --shell python3
un session --shell ipython
un session --shell bpython

# Node.js REPL
un session --shell node

# Ruby REPL
un session --shell irb

# Other REPLs
un session --shell julia
un session --shell ghci    # Haskell
un session --shell iex     # Elixir

Gravação de sessão

# With network access
un session -n semitrusted

# With persistence (can reconnect)
un session --tmux
un session --screen

# With timeout (1 hour)
un session --ttl 3600

# Full audit recording
un session --audit -o ./logs

Equivalente API

POST /sessions

{
  "session_id": "sess_xyz789",
  "websocket_url": "wss://api.unsandbox.com/sessions/sess_xyz789/shell",
  "status": "running"
}
Listar Sessões

Listar Trabalhos Ativos

un session --list

Saída

Active sessions: 2

SESSION ID                     CONTAINER         SHELL      TTL      STATUS
sess_abc123...                 unsb-vm-12345     python3    45m30s   active
sess_def456...                 unsb-vm-67890     bash       1h2m     active

Obter Detalhes da Sessão

un session --info sess_abc123

Equivalente API

GET /sessions and GET /sessions/{id}

{
  "sessions": [
    {
      "session_id": "sess_abc123",
      "status": "running",
      "network_mode": "zerotrust",
      "shell": "python3"
    }
  ]
}
Conectar e Desconectar

Reconecte-se a sessões persistentes (requer --tmux ou --screen).

Criar Sessão Persistente

# With tmux (recommended)
un session --tmux

# With screen
un session --screen

Desconectar

# tmux: Press Ctrl+b then d
# screen: Press Ctrl+a then d

Desconto

# By session ID
un session --attach sess_abc123

# By container name
un session --attach unsb-vm-12345

Encerrar Sessão

# Kill by ID
un session --kill sess_abc123

# Kill by container name
un session --kill unsb-vm-12345

Equivalente API

DELETE /sessions/{id}

{"status": "terminated"}
Shells e REPLs

Shells e REPLs disponíveis para sessões interativas:

Shells

bash, dash, sh, zsh, fish, ksh
tcsh, csh, elvish, xonsh, ash

REPLs

# Python
python3, bpython, ipython

# JavaScript
node

# Ruby
ruby, irb

# Other
lua, php, perl, guile, scheme
ghci, erl, iex, sbcl, clisp
r, julia, clojure

Equivalente API

GET /shells retorna a lista completa de shells disponíveis.

Congelar e Descongelar Sessões

Congele sessões para economizar recursos enquanto preserva o estado.

Congelar Sessão

un session --freeze sess_abc123

Descongelar Sessão

un session --unfreeze sess_abc123

Equivalente API

POST /sessions/{id}/freeze

{"status": "frozen"}

POST /sessions/{id}/unfreeze

{"status": "running", "unfreeze_time_ms": 1250}
Snapshots de Sessão

Crie snapshots pontuais do estado da sessão.

Criar Snapshot

# With name
un session --snapshot sess_abc123 --name "before-upgrade"

# Quick snapshot (auto-generated name)
un session --snapshot sess_abc123

Restaurar a partir do Snapshot

un session --restore snap_xyz789

Equivalente API

POST /sessions/{id}/snapshot

{
  "snapshot_id": "snap_abc123",
  "name": "before-upgrade",
  "size_bytes": 52428800
}

POST /sessions/{id}/restore

{"status": "restored"}
Criar Serviço

Create long-running services with automatic HTTPS at *.on.unsandbox.com. TLS certificates are provisioned automatically via Let's Encrypt. Custom domains supported via CNAME.

Serviço Básico

# Simple web server
un service --name myapp --ports 80 --bootstrap "python -m http.server 80"

# With multiple ports
un service --name api --ports 80,443 --bootstrap "./start.sh"

Com Arquivos

# Deploy app tarball
un service --name blog --ports 8000 \
  -f app.tar.gz \
  --bootstrap "tar xzf app.tar.gz && cd app && ./start.sh"

Domínios Personalizados

un service --name api --ports 80 \
  --domains api.example.com,www.api.example.com \
  --bootstrap "./start.sh"

Nível de Serviço:

# Web service (default)
un service --name web --ports 80

# Minecraft server
un service --name mc --type minecraft --bootstrap ./setup.sh

# Game server types
un service --name game --type mumble
un service --name game --type teamspeak
un service --name game --type source

Equivalente API

POST /services

{
  "service_id": "svc_abc123",
  "name": "myapp",
  "url": "https://myapp.on.unsandbox.com",
  "status": "starting",
  "ports": [80]
}
Gerenciar Serviços

Listar Serviços

un service --list

Obter Info do Serviço

un service --info svc_abc123

Congelar/Descongelar Serviço

# Freeze (auto-unfreezes on HTTP request)
un service --freeze svc_abc123

# Manual unfreeze
un service --unfreeze svc_abc123

Bloquear/Desbloquear

# Prevent accidental deletion
un service --lock svc_abc123

# Allow deletion
un service --unlock svc_abc123

Destruir Serviço

un service --destroy svc_abc123

Endpoint de API acessado

  • GET /services - Listar todos os serviços
  • GET /services/{id} - Obter detalhes do serviço
  • POST /services/{id}/freeze - Congelar serviço
  • POST /services/{id}/unfreeze - Descongelar serviço
  • POST /services/{id}/lock - Bloquear serviço
  • POST /services/{id}/unlock - Desbloquear Cofre
  • DELETE /services/{id} - Destruir serviço
Nível de Serviço:

Descongelamento Automático

Quando habilitado, serviços congelados acordam automaticamente quando recebem uma requisição HTTP.

# Enable auto-unfreeze (default for new services)
un service --auto-unfreeze svc_abc123

# Disable auto-unfreeze
un service --no-auto-unfreeze svc_abc123

Exibição da Página de Congelamento

Controle o que os visitantes veem ao acessar um serviço congelado.

# Show HTML payment page (default)
un service --show-freeze-page svc_abc123

# Return JSON error instead
un service --no-show-freeze-page svc_abc123

Equivalente API

PATCH /services/{id}

# Enable auto-unfreeze
{"unfreeze_on_demand": true}

# Disable freeze page (return JSON error)
{"show_freeze_page": false}

Comportamento da Página de Congelamento

  • show_freeze_page: true - Exibe página HTML com opções de pagamento
  • show_freeze_page: false - Retorna JSON: {"error": "service_frozen"}

Use o modo JSON para serviços API onde respostas HTML quebrariam os clientes.

Logs e Executar

Ver Logs de Bootstrap

# All logs
un service --logs svc_abc123

# Last 9000 lines
un service --tail svc_abc123

Executar Código

# Run any command
un service --execute svc_abc123 'ls -la'

# Check service status
un service --execute svc_abc123 'systemctl status myapp'

# View application logs
un service --execute svc_abc123 'journalctl -u myapp -n 50'

Exportar Script de Bootstrap

# Print to stdout
un service --dump-bootstrap svc_abc123

# Save to file
un service --dump-bootstrap svc_abc123 backup.sh

Equivalente API

GET /services/{id}/logs

{"log": "Bootstrap started...\nInstalling...\nServer listening on port 80"}

POST /services/{id}/execute

{
  "stdout": "...",
  "stderr": "",
  "exit_code": 0
}
Cofre de Variáveis de Ambiente

Armazenamento criptografado para segredos do serviço. Variáveis são injetadas quando o contêiner inicia ou descongela.

Definir Variáveis de Ambiente

# Using the API (PUT /services/{id}/env)
# Content-Type: text/plain
# Body: .env format

DATABASE_URL=postgres://user:pass@host/db
API_SECRET=abc123
DEBUG=false

Obter Status do Cofre

GET /services/{id}/env

{
  "exists": true,
  "variable_count": 3,
  "updated_at": "2026-01-14T12:00:00Z"
}

Exportar Cofre Descriptografado

POST /services/{id}/env/export

{"env": "DATABASE_URL=postgres://...\nAPI_SECRET=abc123\nDEBUG=false"}

Excluir

DELETE /services/{id}/env

{"status": "deleted"}
Reimplantar Serviço

Reexecutar Bootstrap

# Re-run existing bootstrap
un service --redeploy svc_abc123

# Redeploy with new bootstrap
un service --redeploy svc_abc123 --bootstrap ./new-setup.sh

Criar Snapshot do Serviço

# Standard snapshot (pauses briefly)
un service --snapshot svc_abc123 --name "stable-v1.0"

# Hot snapshot (no pause)
un service --snapshot svc_abc123 --hot

Equivalente API

POST /services/{id}/redeploy

{"state": "redeploying"}

POST /services/{id}/snapshot

{
  "snapshot_id": "snap_def456",
  "name": "stable-v1.0",
  "size_bytes": 104857600
}
Listar Snapshots

Listar Todos os Snapshots

un snapshot --list

Saída

Snapshots: 3

SNAPSHOT ID                  NAME              SOURCE     SIZE     CREATED
snap_a1b2-c3d4-e5f6-g7h8     before-upgrade    session    512 MB   2h ago
snap_i9j0-k1l2-m3n4-o5p6     stable-v1.0       service    1.2 GB   1d ago
snap_q7r8-s9t0-u1v2-w3x4     dev-checkpoint    session    256 MB   3d ago

Obter Info do Snapshot

un snapshot --info snap_a1b2-c3d4-e5f6-g7h8

Excluir Snapshot

un snapshot --delete snap_a1b2-c3d4-e5f6-g7h8

Equivalente API

GET /snapshots

{
  "snapshots": [
    {
      "snapshot_id": "snap_abc123",
      "name": "before-upgrade",
      "source_type": "session",
      "size_bytes": 52428800
    }
  ]
}
Restaurar e Clonar

Restaurar para o Original

# Restore session from snapshot
un session --restore snap_abc123

# Restore service from snapshot
un service --restore snap_def456

Clonar para Novo Contêiner

POST /snapshots/{id}/clone

# Clone to new session
{
  "type": "session",
  "shell": "bash"
}

# Clone to new service
{
  "type": "service",
  "name": "cloned-app"
}

Resposta

Clonar para sessão:

{"session_id": "sess_new123"}

Clonar para serviço:

{
  "service_id": "svc_new456",
  "url": "https://cloned-app.on.unsandbox.com"
}

Bloquear/Desbloquear Snapshots

POST /snapshots/{id}/lock - Impedir exclusão

POST /snapshots/{id}/unlock - Permitir exclusão

URL Base

Todas as requisições API devem ser feitas para:

https://api.unsandbox.com

A API suporta dois modos de rede:

  • zerotrust (default) — Sem acesso à rede, execução totalmente isolada
  • semitrusted — Acesso à rede via proxy de saída, pode acessar a internet
Dependências Obrigatórias

Os exemplos em TypeScript abaixo requerem as seguintes bibliotecas de terceiros:

  • axios
  • @types/node

Certifique-se de que estes pacotes estão instalados em seu ambiente antes de executar os exemplos.

POST https://api.unsandbox.com/execute

Execute código imediatamente e aguarde os resultados. Ideal para scripts rápidos e uso interativo.

Parâmetros da Requisição

Parameter Type Required Description
language string Programming language
code string Source code to execute
env object Environment variables (key-value pairs)
network_mode string "zerotrust" or "semitrusted"
ttl integer Timeout 1-900s (default: 60)
return_artifact boolean Return compiled binary
return_wasm_artifact boolean Return WebAssembly binary
vcpu integer vCPUs 1-8 (each includes 2GB RAM)
input_files array Arquivos para upload (veja Arquivos de Entrada)
import axios from "axios";
import crypto from "crypto";

const PUBLIC_KEY = process.env.UNSANDBOX_PUBLIC_KEY || "unsb-pk-test-0000-0000-0001";
const SECRET_KEY = process.env.UNSANDBOX_SECRET_KEY || "unsb-sk-test0-vault-unlck-12345";

function signRequest(method: string, path: string, body: string): { timestamp: string; signature: string } {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const message = `${timestamp}:${method}:${path}:${body}`;
  const signature = crypto.createHmac("sha256", SECRET_KEY).update(message).digest("hex");
  return { timestamp, signature };
}

const path = "/execute";
const payload = {
  language: "python",
  code: "print('Hello from unsandbox!')",
};
const body = JSON.stringify(payload);
const { timestamp, signature } = signRequest("POST", path, body);

const headers = {
  "Content-Type": "application/json",
  Authorization: `Bearer ${PUBLIC_KEY}`,
  "X-Timestamp": timestamp,
  "X-Signature": signature,
};

axios
  .post(`https://api.unsandbox.com${path}`, payload, { headers })
  .then((response) => {
    const result = response.data;
    if (result.success) {
      console.log("Output:", result.stdout);
    } else {
      console.log("Error:", result.error);
    }
  })
  .catch((error) => console.error("Request failed:", error));
{
  "success": true,
  "stdout": "Hello from unsandbox!\n",
  "stderr": "",
  "exit_code": 0,
  "language": "python",
  "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "network_mode": "zerotrust",
  "total_time_ms": 236
}
{
  "success": false,
  "stdout": "",
  "stderr": "SyntaxError: invalid syntax\n",
  "exit_code": 1,
  "language": "python",
  "job_id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
  "network_mode": "zerotrust",
  "total_time_ms": 312
}
POST https://api.unsandbox.com/execute/async

Submit code for execution and receive a job ID to poll for results. Best for long-running scripts or when you need to decouple submission from execution.

Parâmetros da Requisição

Parameter Type Required Description
language string Programming language
code string Source code to execute
env object Environment variables (key-value pairs)
network_mode string "zerotrust" or "semitrusted"
ttl integer Timeout 1-900s (default: 60)
return_artifact boolean Return compiled binary
return_wasm_artifact boolean Return WebAssembly binary
vcpu integer vCPUs 1-8 (each includes 2GB RAM)
input_files array Arquivos para upload (veja Arquivos de Entrada)
import axios from "axios";
import crypto from "crypto";

const PUBLIC_KEY = process.env.UNSANDBOX_PUBLIC_KEY || "unsb-pk-test-0000-0000-0001";
const SECRET_KEY = process.env.UNSANDBOX_SECRET_KEY || "unsb-sk-test0-vault-unlck-12345";

function signRequest(method: string, path: string, body: string): { timestamp: string; signature: string } {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const message = `${timestamp}:${method}:${path}:${body}`;
  const signature = crypto.createHmac("sha256", SECRET_KEY).update(message).digest("hex");
  return { timestamp, signature };
}

function getHeaders(method: string, path: string, body: string, contentType = "application/json") {
  const { timestamp, signature } = signRequest(method, path, body);
  return {
    "Content-Type": contentType,
    Authorization: `Bearer ${PUBLIC_KEY}`,
    "X-Timestamp": timestamp,
    "X-Signature": signature,
  };
}

const payload = {
  language: "rust",
  code: 'fn main() { println!("Computing..."); }',
  ttl: 300,
};
const submitPath = "/execute/async";
const submitBody = JSON.stringify(payload);

// Submit job
axios
  .post(`https://api.unsandbox.com${submitPath}`, payload, {
    headers: getHeaders("POST", submitPath, submitBody),
  })
  .then(async (response) => {
    const jobId = response.data.job_id;
    console.log(`Job submitted: ${jobId}`);

    // Poll for results
    const statusPath = `/jobs/${jobId}`;
    while (true) {
      const statusResp = await axios.get(`https://api.unsandbox.com${statusPath}`, {
        headers: getHeaders("GET", statusPath, ""),
      });
      const status = statusResp.data;

      if (status.status === "completed") {
        const result = status.result;
        if (result.success) {
          console.log("Output:", result.stdout);
        } else {
          console.log("Error:", result.stderr);
        }
        break;
      } else if (["timeout", "cancelled"].includes(status.status)) {
        console.log(`Job ${status.status}`);
        break;
      }

      await new Promise((resolve) => setTimeout(resolve, 1000));
    }
  })
  .catch((error) => console.error("Request failed:", error));
{
  "job_id": "ba943906-4ea6-a61c-9980-445f459368d",
  "status": "pending",
  "message": "Job accepted for execution"
}
POST https://api.unsandbox.com/run

Execute code with automatic language detection via shebang. Send raw code as the request body with Content-Type: text/plain.

Request

  • Content-Type: text/plain
  • Body: Raw code with shebang (e.g., #!/usr/bin/env python3)

Query Parameters

Parameter Type Required Description
env string URL-encoded JSON object with environment variables
network_mode string "zerotrust" or "semitrusted"
ttl integer Timeout 1-900s (default: 60)
return_artifact boolean Return compiled binary
return_wasm_artifact boolean Return WebAssembly binary
import axios from "axios";
import crypto from "crypto";

const PUBLIC_KEY = process.env.UNSANDBOX_PUBLIC_KEY || "unsb-pk-test-0000-0000-0001";
const SECRET_KEY = process.env.UNSANDBOX_SECRET_KEY || "unsb-sk-test0-vault-unlck-12345";

function signRequest(method: string, path: string, body: string): { timestamp: string; signature: string } {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const message = `${timestamp}:${method}:${path}:${body}`;
  const signature = crypto.createHmac("sha256", SECRET_KEY).update(message).digest("hex");
  return { timestamp, signature };
}

const path = "/run";
const code = `#!/usr/bin/env python3
print("Language auto-detected!")`;
const { timestamp, signature } = signRequest("POST", path, code);

const headers = {
  "Content-Type": "text/plain",
  Authorization: `Bearer ${PUBLIC_KEY}`,
  "X-Timestamp": timestamp,
  "X-Signature": signature,
};

axios
  .post(`https://api.unsandbox.com${path}`, code, { headers })
  .then((response) => {
    const result = response.data;
    console.log(`Detected: ${result.detected_language}`);
    console.log(`Output: ${result.stdout}`);
  })
  .catch((error) => console.error("Request failed:", error));
{
  "success": true,
  "stdout": "Language auto-detected!\n",
  "stderr": "",
  "exit_code": 0,
  "language": "python",
  "detected_language": "python",
  "job_id": "f6a7b8c9-d0e1-2345-fghi-678901234567",
  "network_mode": "zerotrust"
}
POST https://api.unsandbox.com/run/async

Submit code with automatic language detection and receive a job ID. Combines the convenience of /run with the flexibility of async execution.

Request

  • Content-Type: text/plain
  • Body: Raw code with shebang (e.g., #!/usr/bin/env ruby)

Query Parameters

Parameter Type Required Description
env string URL-encoded JSON object with environment variables
network_mode string "zerotrust" or "semitrusted"
ttl integer Timeout 1-900s (default: 60)
return_artifact boolean Return compiled binary
return_wasm_artifact boolean Return WebAssembly binary
import axios from "axios";
import crypto from "crypto";

const PUBLIC_KEY = process.env.UNSANDBOX_PUBLIC_KEY || "unsb-pk-test-0000-0000-0001";
const SECRET_KEY = process.env.UNSANDBOX_SECRET_KEY || "unsb-sk-test0-vault-unlck-12345";

function signRequest(method: string, path: string, body: string): { timestamp: string; signature: string } {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const message = `${timestamp}:${method}:${path}:${body}`;
  const signature = crypto.createHmac("sha256", SECRET_KEY).update(message).digest("hex");
  return { timestamp, signature };
}

function getHeaders(method: string, path: string, body: string, contentType = "application/json") {
  const { timestamp, signature } = signRequest(method, path, body);
  return {
    "Content-Type": contentType,
    Authorization: `Bearer ${PUBLIC_KEY}`,
    "X-Timestamp": timestamp,
    "X-Signature": signature,
  };
}

const code = `#!/usr/bin/env ruby
puts "Running async with auto-detect!"`;
const submitPath = "/run/async";

// Submit job
axios
  .post(`https://api.unsandbox.com${submitPath}`, code, {
    headers: getHeaders("POST", submitPath, code, "text/plain"),
  })
  .then(async (response) => {
    const jobId = response.data.job_id;
    console.log(`Job submitted: ${jobId}`);

    // Poll for results
    const statusPath = `/jobs/${jobId}`;
    while (true) {
      const statusResp = await axios.get(`https://api.unsandbox.com${statusPath}`, {
        headers: getHeaders("GET", statusPath, ""),
      });
      const status = statusResp.data;

      if (status.status === "completed") {
        const result = status.result;
        console.log(`Detected: ${result.detected_language}`);
        if (result.success) {
          console.log(`Output: ${result.stdout}`);
        }
        break;
      } else if (["timeout", "cancelled"].includes(status.status)) {
        console.log(`Job ${status.status}`);
        break;
      }

      await new Promise((resolve) => setTimeout(resolve, 1000));
    }
  })
  .catch((error) => console.error("Request failed:", error));
{
  "job_id": "ba943906-4ea6-a61c-9980-445f459368d",
  "status": "pending",
  "detected_language": "python",
  "message": "Job accepted for execution"
}

Via GET /jobs/{id}

{
  "job_id": "a7b8c9d0-e1f2-3456-ghij-789012345678",
  "status": "completed",
  "created_at": "2025-01-11T12:00:00Z",
  "started_at": "2025-01-11T12:00:01Z",
  "completed_at": "2025-01-11T12:00:02Z",
  "success": true,
  "stdout": "Running async with auto-detect!\n",
  "stderr": "",
  "exit_code": 0,
  "language": "ruby",
  "network_mode": "zerotrust",
  "total_time_ms": 1234
}
GET https://api.unsandbox.com/jobs/{id}

Check the status and results of an asynchronous job. Poll this endpoint after submitting a job via /execute/async or /run/async.

URL Parameters

Parameter Type Description
id string Job ID returned from async endpoint

Possible Status Values

  • pending - Job queued, waiting to execute
  • running - Job currently executing
  • completed - Job finished successfully
  • failed - Job execution failed
  • timeout - Job exceeded TTL limit
  • cancelled - Job was cancelled via DELETE
import axios from "axios";
import crypto from "crypto";

const PUBLIC_KEY = process.env.UNSANDBOX_PUBLIC_KEY || "unsb-pk-test-0000-0000-0001";
const SECRET_KEY = process.env.UNSANDBOX_SECRET_KEY || "unsb-sk-test0-vault-unlck-12345";

function signRequest(method: string, path: string, body: string): { timestamp: string; signature: string } {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const message = `${timestamp}:${method}:${path}:${body}`;
  const signature = crypto.createHmac("sha256", SECRET_KEY).update(message).digest("hex");
  return { timestamp, signature };
}

const jobId = "job_1234567890_abc";
const path = `/jobs/${jobId}`;
const { timestamp, signature } = signRequest("GET", path, "");

const headers = {
  Authorization: `Bearer ${PUBLIC_KEY}`,
  "X-Timestamp": timestamp,
  "X-Signature": signature,
};

axios
  .get(`https://api.unsandbox.com${path}`, { headers })
  .then((response) => {
    const job = response.data;
    console.log(`Status: ${job.status}`);
    if (job.status === "completed") {
      console.log(`Success: ${job.success}`);
      console.log(`Output: ${job.stdout}`);
    }
  })
  .catch((error) => console.error("Request failed:", error));
{
  "job_id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
  "status": "completed",
  "created_at": "2025-01-11T12:00:00Z",
  "started_at": "2025-01-11T12:00:01Z",
  "completed_at": "2025-01-11T12:00:05Z",
  "success": true,
  "stdout": "Hello from unsandbox!\n",
  "stderr": "",
  "exit_code": 0,
  "language": "python",
  "network_mode": "zerotrust",
  "total_time_ms": 4021
}
GET https://api.unsandbox.com/jobs

List all active (pending or running) jobs for your API key. Useful for monitoring multiple async executions.

import axios from "axios";
import crypto from "crypto";

const PUBLIC_KEY = process.env.UNSANDBOX_PUBLIC_KEY || "unsb-pk-test-0000-0000-0001";
const SECRET_KEY = process.env.UNSANDBOX_SECRET_KEY || "unsb-sk-test0-vault-unlck-12345";

function signRequest(method: string, path: string, body: string): { timestamp: string; signature: string } {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const message = `${timestamp}:${method}:${path}:${body}`;
  const signature = crypto.createHmac("sha256", SECRET_KEY).update(message).digest("hex");
  return { timestamp, signature };
}

const path = "/jobs";
const { timestamp, signature } = signRequest("GET", path, "");

const headers = {
  Authorization: `Bearer ${PUBLIC_KEY}`,
  "X-Timestamp": timestamp,
  "X-Signature": signature,
};

axios
  .get(`https://api.unsandbox.com${path}`, { headers })
  .then((response) => {
    const jobs = response.data;
    jobs.forEach((job: { job_id: string; status: string; language: string }) => {
      console.log(`${job.job_id}: ${job.status} (${job.language})`);
    });
  })
  .catch((error) => console.error("Request failed:", error));
[
  {
    "job_id": "ba943906-4ea6-a61c-9980-445f459368d",
    "status": "completed",
    "language": "python",
    "network_mode": "zerotrust",
    "created_at": "2025-01-11T12:00:00Z"
  },
  {
    "job_id": "c1d2e3f4-5678-90ab-cdef-1234567890ab",
    "status": "running",
    "language": "rust",
    "network_mode": "zerotrust",
    "created_at": "2025-01-11T12:01:00Z"
  }
]
DELETE https://api.unsandbox.com/jobs/{id}

Cancel a pending or running job. If the job is already executing, it will be terminated and partial output returned.

URL Parameters

Parameter Type Description
id string Job ID to cancel
import axios from "axios";
import crypto from "crypto";

const PUBLIC_KEY = process.env.UNSANDBOX_PUBLIC_KEY || "unsb-pk-test-0000-0000-0001";
const SECRET_KEY = process.env.UNSANDBOX_SECRET_KEY || "unsb-sk-test0-vault-unlck-12345";

function signRequest(method: string, path: string, body: string): { timestamp: string; signature: string } {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const message = `${timestamp}:${method}:${path}:${body}`;
  const signature = crypto.createHmac("sha256", SECRET_KEY).update(message).digest("hex");
  return { timestamp, signature };
}

const jobId = "job_1234567890_abc";
const path = `/jobs/${jobId}`;
const { timestamp, signature } = signRequest("DELETE", path, "");

const headers = {
  Authorization: `Bearer ${PUBLIC_KEY}`,
  "X-Timestamp": timestamp,
  "X-Signature": signature,
};

axios
  .delete(`https://api.unsandbox.com${path}`, { headers })
  .then((response) => {
    const result = response.data;
    console.log(`Cancelled: ${result.message}`);
    if (result.result) {
      console.log(`Partial output: ${result.stdout}`);
    }
  })
  .catch((error) => console.error("Request failed:", error));
{
  "job_id": "ba943906-4ea6-a61c-9980-445f459368d",
  "status": "cancelled",
  "message": "Job cancelled",
  "completed_at": "2025-01-11T12:00:30Z",
  "success": true,
  "stdout": "   Compiling hello v0.1.0 (/tmp)\n",
  "artifacts": []
}
Visão Geral de Imagens

Imagens são snapshots de contêiner independentes e transferíveis que sobrevivem à exclusão do contêiner. Diferente dos snapshots (vinculados ao ciclo de vida do contêiner), imagens podem ser:

  • Transferido entre chaves API
  • Compartilhado com usuários específicos via confiança
  • Tornado público para o marketplace
  • Usado para criar novos serviços

Níveis de Visibilidade

  • private — Somente o proprietário pode ver/usar (padrão)
  • unlisted — Oculto da listagem, mas pode ser compartilhado via confiança
  • public — Visível para todos os usuários (marketplace)
POST https://api.unsandbox.com/images

Publique uma imagem a partir de um serviço ou snapshot.

Corpo da Requisição

Parameter Type Required Description
source_type string "service" or "snapshot"
source_id string ID of service or snapshot
name string User-friendly name
description string Optional description

Metadados de Requisição:

{
  "source_type": "service",
  "source_id": "unsb-service-abc123",
  "name": "my-app-v1.0",
  "description": "Production-ready app image"
}

Resposta

{
  "id": "unsb-image-xyz789",
  "name": "my-app-v1.0",
  "description": "Production-ready app image",
  "source_type": "service",
  "source_id": "unsb-service-abc123",
  "fingerprint": "abc123def456...",
  "size_bytes": 524288000,
  "visibility": "private",
  "locked": false,
  "owner_api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx",
  "created_at": "2025-01-11T12:00:00Z"
}
GET https://api.unsandbox.com/images

Liste todas as imagens que pertencem à ou foram compartilhadas com sua chave API.

Endpoints Relacionados

  • GET /images/public — Listar imagens do marketplace
  • GET /images/owned — Listar apenas suas imagens
  • GET /images/shared — Listar imagens compartilhadas com você

Resposta

{
  "images": [
    {
      "id": "unsb-image-xyz789",
      "name": "my-app-v1.0",
      "fingerprint": "abc123...",
      "size_bytes": 524288000,
      "visibility": "private",
      "locked": false,
      "created_at": "2025-01-11T12:00:00Z"
    }
  ]
}
GET https://api.unsandbox.com/images/{id}

Obtenha informações detalhadas sobre uma imagem.

Parâmetros de URL

Parameter Type Description
id string Image ID (unsb-image-xxxx)

Resposta

{
  "id": "unsb-image-xyz789",
  "name": "my-app-v1.0",
  "description": "Production-ready app image",
  "source_type": "service",
  "source_id": "unsb-service-abc123",
  "fingerprint": "abc123def456...",
  "node": "cammy",
  "size_bytes": 524288000,
  "visibility": "private",
  "locked": false,
  "owner_api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx",
  "trusted_keys": [],
  "created_at": "2025-01-11T12:00:00Z"
}
POST https://api.unsandbox.com/images/{id}/spawn

Crie um novo serviço usando esta imagem como base.

Corpo da Requisição

Parameter Type Required Description
name string Service name
ports array Ports to expose
network_mode string "zerotrust" or "semitrusted"
bootstrap string Optional bootstrap script

Metadados de Requisição:

{
  "name": "my-app-instance",
  "ports": [8080],
  "network_mode": "semitrusted"
}

Resposta

{
  "service_id": "unsb-service-xyz789",
  "name": "my-app-instance",
  "source_image": "unsb-image-abc123",
  "state": "starting"
}
Gerenciamento de Imagens

Visibilidade e Compartilhamento

POST /images/{id}/visibility

{"visibility": "unlisted"}

Clonar Imagem

POST /images/{id}/clone

{
  "name": "my-copy-of-app",
  "description": "My personal copy"
}

Bloquear/Desbloquear

  • POST /images/{id}/lock — Impedir exclusão
  • POST /images/{id}/unlock — Permitir exclusão

Excluir

DELETE /images/{id}

Conceder Acesso

POST /images/{id}/grant

{
  "api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx"
}

Revogar Acesso

POST /images/{id}/revoke

{
  "api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx"
}

Listar Chaves de Confiança

GET /images/{id}/trusted

{
  "trusted_keys": [
    "unsb-pk-aaaa-bbbb-cccc-dddd",
    "unsb-pk-1111-2222-3333-4444"
  ]
}

Transferir Propriedade

POST /images/{id}/transfer

{
  "to_api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx"
}
Códigos de Erro

A API retorna códigos de status HTTP padrão junto com informações detalhadas de erro.

Code Status Description
200 OK Requisição bem-sucedida (verifique o campo 'success' para o resultado da execução)
400 Bad Request Corpo da requisição inválido ou parâmetros obrigatórios ausentes
401 Unauthorized Chave API / assinatura ausente ou inválida
403 Forbidden Conta suspensa ou recurso não disponível
404 Not Found ID do job não encontrado ou expirado
429 Too Many Requests Limite de taxa excedido
500 Internal Error Erro no servidor, por favor tente novamente

Formato de Resposta de Erro

{
  "error": "Invalid API key",
  "code": "INVALID_KEY",
  "details": "The provided public key does not exist"
}
Limites de Taxa:

Os limites de taxa são aplicados por chave API e variam por plano. Veja os preços para detalhes do plano →

Limite de Requisições:

Os cabeçalhos de resposta incluem informações de limite de taxa:

  • X-RateLimit-Limit — requisições/minuto
  • X-RateLimit-Remaining — Requisições restantes
  • X-RateLimit-Reset — Timestamp Unix quando o limite é redefinido

Quando limitado pela taxa, aguarde o tempo de redefinição ou faça upgrade do seu plano para limites maiores.

POST https://api.unsandbox.com/keys/validate

Valide seu par de chaves API e recupere sua configuração incluindo limites de taxa, limites de concorrência e status de expiração.

Isso é útil para:

  • Verificando se seu par de chaves é válido
  • Visualizando seus limites atuais
  • Construindo interfaces de gerenciamento de chaves
  • Monitorando expiração da chave

Autenticação

Usa autenticação HMAC padrão (igual a todos os outros endpoints).

# Sign the request
TIMESTAMP=$(date +%s)
PUBLIC_KEY="unsb-pk-xxxx-xxxx-xxxx-xxxx"
SECRET_KEY="unsb-sk-xxxxx-xxxxx-xxxxx-xxxxx"
BODY="{}"
MESSAGE="${TIMESTAMP}:POST:/keys/validate:${BODY}"
SIGNATURE=$(echo -n "$MESSAGE" | openssl dgst -sha256 -hmac "$SECRET_KEY" | cut -d' ' -f2)

# Make the request
curl -X POST https://api.unsandbox.com/keys/validate \
  -H "Authorization: Bearer $PUBLIC_KEY" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE" \
  -H "Content-Type: application/json" \
  -d "$BODY"
{
  "valid": true,
  "public_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx",
  "rate_per_minute": 60,
  "burst": 10,
  "concurrency_limit": 5,
  "expires_at": "2026-12-31T23:59:59Z",
  "tier": "Tier 3"
}
GET https://api.unsandbox.com/languages

Retorna todas as linguagens de programação suportadas e seus aliases.

Aliases Comuns

  • node, jsjavascript
  • tstypescript
  • lispcommonlisp

Resposta

{
  "languages": [
    "python",
    "javascript",
    "typescript",
    "ruby",
    "go",
    "rust",
    "c",
    "cpp"
  ],
  "aliases": {
    "js": "javascript",
    "node": "javascript",
    "ts": "typescript",
    "lisp": "commonlisp"
  },
  "count": 42
}
GET https://api.unsandbox.com/shells

Retorna todos os shells e REPLs suportados para sessões interativas, agrupados por categoria.

Categorias

  • unix — bash, dash, sh, zsh, fish, ksh
  • python — python, python3, ipython, bpython
  • javascript — node
  • ruby — ruby, irb
  • lisp — scheme, guile, sbcl, clisp, clojure
  • erlang — erl, iex
  • data — r, julia, sqlite3

Resposta

{
  "shells": [
    "bash", "bpython", "clisp",
    "clojure", "dash", "fish",
    "ghci", "guile", "iex",
    "ipython", "irb", "julia"
  ],
  "categories": {
    "unix": ["bash", "dash", "sh", "zsh", "fish"],
    "python": ["python", "python3", "ipython", "bpython"],
    "javascript": ["node"],
    "ruby": ["ruby", "irb"],
    "lisp": ["scheme", "guile", "sbcl", "clisp", "clojure"]
  },
  "count": 35
}
GET https://api.unsandbox.com/health

Endpoint simples de verificação de integridade. Retorna o status do serviço.

Resposta

{"status": "ok"}
GET https://api.unsandbox.com/cluster

Obtenha informações sobre o pool de contêineres e status do sistema.

Modos de Rede

  • zerotrust_only — Only isolated containers
  • semitrusted_only — Only network-enabled containers
  • hybrid — Both types available

Resposta

{
  "mode": "pooled",
  "pool_size": 288,
  "allocated": 5,
  "available": 280,
  "spawning": 0,
  "total_containers": 285,
  "network_mode": "hybrid",
  "network_breakdown": {
    "zerotrust": {
      "allocated": 2,
      "available": 140,
      "total": 142
    },
    "semitrusted": {
      "allocated": 3,
      "available": 140,
      "services": 1,
      "total": 143
    }
  }
}
GET https://api.unsandbox.com/pools

Obtenha o status de todos os pools de contêineres registrados (escalabilidade horizontal).

Resposta

{
  "pool_count": 2,
  "total_capacity": 288,
  "total_allocated": 8,
  "total_available": 280,
  "pools": [
    {
      "id": "pool_manager@cammy",
      "allocated": 4,
      "available": 140,
      "total": 144
    },
    {
      "id": "pool_manager@ai",
      "allocated": 4,
      "available": 140,
      "total": 144
    }
  ]
}
GET https://api.unsandbox.com/stats

Obtenha estatísticas detalhadas do sistema incluindo carga e métricas de contêineres.

Resposta

{
  "containers": 285,
  "load_1min": "2.15",
  "load_5min": "1.89",
  "load_15min": "1.45"
}
Bibliotecas SDK (un-inception)

Implementações completas de SDK com autenticação HMAC em 42 linguagens. Use quando precisar de acesso programático a partir do seu próprio código.

Navegue por todas as 42 implementações de linguagens →

Padrão de Uso

# Download the SDK for your language
wget https://unsandbox.com/cli/inception/un.py

# Use it in your code
# un.py provides: execute_code(), create_session(), create_service()

# Or run it as a CLI
python un.py script.py
python un.py -s python 'print("Hello")'

Pronto para começar?

Obtenha uma chave API gratuita e comece a executar código em minutos.

Export Vault

Enter a password to encrypt your exported vault. You'll need this password to import the vault on another device.

Import Vault

Select an exported vault file and enter the export password to decrypt it.