Ejecuta código en más de 42 lenguajes con una sola llamada a la API. Así puedes empezar:
Obtén tu clave API
Regístrate en unsandbox.com/console para obtener tus credenciales de la API.
Haz tu primera solicitud
Envía código al endpoint de ejecución y obtén resultados al instante.
Construye algo increíble
Usa nuestra ejecución en sandbox para agentes de aprendizaje automático, playgrounds de código, herramientas educativas y más.
Descargar
# Linux x86_64
wget https://unsandbox.com/downloads/un
chmod +x un
# Move to PATH (optional)
sudo mv un /usr/local/bin/
Compilar desde el código fuente
# 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 lenguajes que necesitan acceso programático, usa nuestras implementaciones 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
Todas las solicitudes a la API requieren autenticación con firma HMAC-SHA256 por seguridad.
Encabezados requeridos
| 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 de firma
HMAC-SHA256(secret_key, timestamp:METHOD:path:body)
Ejemplo de cadena de firma:
1699564800:POST:/execute:{"language":"python","code":"print('hi')"}
Tu clave secreta nunca se transmite. El servidor verifica las firmas usando tu clave cifrada.
Ejecuta cualquier archivo de código. El lenguaje se auto-detecta desde la extensión del archivo o 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
Con Opciones
# 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
Respuesta
La salida fluye directamente a tu 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
}
Ejecuta fragmentos de código directamente desde la línea de comandos usando la 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 Multilínea
# Using heredoc
un -s python <<'EOF'
import json
data = {"name": "unsandbox", "version": 2}
print(json.dumps(data, indent=2))
EOF
Lenguajes Soportados
Cualquiera de los 42 lenguajes soportados funciona con -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)'
Pasa variables de entorno a tu código usando la flag -e.
Variable Única
un -e DEBUG=1 script.py
un -e API_KEY=secret app.js
Múltiples Variables
un -e DEBUG=1 -e NAME=World -e COUNT=42 script.py
Con Código en Línea
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))"'
Ejemplo
# 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}!")
Ejecútalo
$ un -e DEBUG=1 -e NAME=unsandbox config_demo.py
Debug mode enabled
Hello unsandbox!
Teletransporta archivos al sandbox. CLI usa el flag -f; la API usa el arreglo input_files.
Uso 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
Límites
- Máximo de archivos
- Tamaño total máximo
- Tamaño máximo de archivo individual
# 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"
}
]
}
El contenido debe estar codificado en Base64.
Los archivos se colocan en el directorio de trabajo:
- Python:
open('data.csv') - Node.js:
fs.readFileSync('data.csv') - Ruby:
File.read('data.csv') - Go:
os.ReadFile("data.csv") - Bash:
cat data.csv
Teletransporta archivos fuera del sandbox. Usa -a para recopilar artefactos de /tmp/artifacts/ u obtener binarios compilados.
Recopilar Archivos Generados
# Files in /tmp/artifacts/ are collected
un -a -o ./outputs script.py
Binario precompilado
# 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
Compilación WebAssembly
# Compile to WASM (supported languages)
un --wasm -o ./wasm main.c
un --wasm -o ./wasm main.rs
Ejemplo: Generar y Recopilar
# 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!")
Ejecútalo
$ un -a -o ./reports generate_report.py
Report generated!
$ ls ./reports
report.json
Confianza Cero (predeterminado)
Aislamiento de red completo. Sin acceso a internet.
# Default - no network
un script.py
Semi-Confiable
Acceso a internet vía proxy de salida.
# 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
Iniciar una sesión de shell interactiva en un contenedor sandbox.
Listar Trabajos Activos
# Default bash shell
un session
# Choose your shell
un session --shell zsh
un session --shell fish
Sesiones 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
Opciones de Sesión
# 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 Trabajos Activos
un session --list
Salida
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
Obtener Detalles de Sesión
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"
}
]
}
Reconectar a sesiones persistentes (requiere --tmux o --screen).
Crear Sesión 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
Descuento
# By session ID
un session --attach sess_abc123
# By container name
un session --attach unsb-vm-12345
Terminar Sesión
# 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 y REPLs disponibles para sesiones interactivas:
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 devuelve la lista completa de shells disponibles.
Congela sesiones para ahorrar recursos mientras preservas el estado.
Congelar Sesión
un session --freeze sess_abc123
Descongelar Sesión
un session --unfreeze sess_abc123
Equivalente API
POST /sessions/{id}/freeze
{"status": "frozen"}
POST /sessions/{id}/unfreeze
{"status": "running", "unfreeze_time_ms": 1250}
Crear instantáneas puntuales del estado de la sesión.
Crear Instantánea
# With name
un session --snapshot sess_abc123 --name "before-upgrade"
# Quick snapshot (auto-generated name)
un session --snapshot sess_abc123
Restaurar desde Instantánea
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"}
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.
Servicio 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"
Con Archivos
# Deploy app tarball
un service --name blog --ports 8000 \
-f app.tar.gz \
--bootstrap "tar xzf app.tar.gz && cd app && ./start.sh"
Dominios Personalizados
un service --name api --ports 80 \
--domains api.example.com,www.api.example.com \
--bootstrap "./start.sh"
Nivel de Servicio:
# 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]
}
Listar Servicios
un service --list
Obtener Info de Servicio
un service --info svc_abc123
Congelar/Descongelar Servicio
# 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 Servicio
un service --destroy svc_abc123
Endpoint de API accedido
GET /services- Listar todos los serviciosGET /services/{id}- Obtener detalles de servicioPOST /services/{id}/freeze- Congelar servicioPOST /services/{id}/unfreeze- Descongelar servicioPOST /services/{id}/lock- Bloquear servicioPOST /services/{id}/unlock- Desbloquear BóvedaDELETE /services/{id}- Destruir servicio
Descongelar automáticamente
Cuando está habilitado, los servicios congelados se despiertan automáticamente al recibir una solicitud HTTP.
# Enable auto-unfreeze (default for new services)
un service --auto-unfreeze svc_abc123
# Disable auto-unfreeze
un service --no-auto-unfreeze svc_abc123
Vista de la página de congelación
Controla lo que los visitantes ven al acceder a un servicio 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}
Comportamiento de la página de congelación
show_freeze_page: true- Muestra una página HTML con opciones de pagoshow_freeze_page: false- Retorna JSON: {"error": "service_frozen"}
Usa el modo JSON para servicios API donde las respuestas HTML podrían afectar a los clientes.
Ver Registros de Arranque
# All logs
un service --logs svc_abc123
# Last 9000 lines
un service --tail svc_abc123
Ejecutar 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'
Volcar Script de Arranque
# 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
}
Almacenamiento cifrado para secretos de servicio. Las variables se inyectan cuando el contenedor arranca o se descongela.
Establecer Variables de Entorno
# 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
Obtener Estado de Bóveda
GET /services/{id}/env
{
"exists": true,
"variable_count": 3,
"updated_at": "2026-01-14T12:00:00Z"
}
Exportar Bóveda Descifrada
POST /services/{id}/env/export
{"env": "DATABASE_URL=postgres://...\nAPI_SECRET=abc123\nDEBUG=false"}
Eliminar
DELETE /services/{id}/env
{"status": "deleted"}
Re-ejecutar Arranque
# Re-run existing bootstrap
un service --redeploy svc_abc123
# Redeploy with new bootstrap
un service --redeploy svc_abc123 --bootstrap ./new-setup.sh
Crear Instantánea de Servicio
# 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 Todas las Instantáneas
un snapshot --list
Salida
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
Obtener Info de Instantánea
un snapshot --info snap_a1b2-c3d4-e5f6-g7h8
Eliminar Instantánea
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 al Original
# Restore session from snapshot
un session --restore snap_abc123
# Restore service from snapshot
un service --restore snap_def456
Clonar a Nuevo Contenedor
POST /snapshots/{id}/clone
# Clone to new session
{
"type": "session",
"shell": "bash"
}
# Clone to new service
{
"type": "service",
"name": "cloned-app"
}
Respuesta
Clonar a sesión:
{"session_id": "sess_new123"}
Clonar a servicio:
{
"service_id": "svc_new456",
"url": "https://cloned-app.on.unsandbox.com"
}
Bloquear/Desbloquear Instantáneas
POST /snapshots/{id}/lock - Prevenir eliminación
POST /snapshots/{id}/unlock - Permitir eliminación
Todas las solicitudes a la API deben hacerse a:
https://api.unsandbox.com
La API soporta dos modos de red:
- zerotrust (default) — Sin acceso a red, ejecución completamente aislada
- semitrusted — Acceso a red mediante proxy de salida, puede acceder a internet
Los ejemplos de Lua a continuación requieren las siguientes bibliotecas de terceros:
socket.http (LuaSocket)json (dkjson or cjson)
Asegúrate de que estos paquetes estén instalados en tu entorno antes de ejecutar los ejemplos.
Ejecuta código de inmediato y espera los resultados. Ideal para scripts rápidos y uso interactivo.
Parámetros de solicitud
| 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 | Archivos para subir (ver Archivos de Entrada) |
-- HMAC-SHA256 authenticated request to unsandbox API
-- Uses openssl for HMAC signing
local public_key = os.getenv("UNSANDBOX_PUBLIC_KEY") or "unsb-pk-test-0000-0000-0001"
local secret_key = os.getenv("UNSANDBOX_SECRET_KEY") or "unsb-sk-test0-vault-unlck-12345"
local timestamp = os.time()
local method = "POST"
local path = "/execute"
-- Escape JSON string for shell
local function escape_json(str)
return str:gsub("\\", "\\\\"):gsub('"', '\\"'):gsub("\n", "\\n")
end
local code = escape_json('print("Hello from unsandbox!")')
local body = string.format('{"language":"lua","code":"%s"}', code)
-- Generate HMAC-SHA256 signature using openssl
local message = string.format("%d:%s:%s:%s", timestamp, method, path, body)
local hmac_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -hmac '%s' | sed 's/^.* //'",
message:gsub("'", "'\\''"), secret_key:gsub("'", "'\\''"))
local hmac_handle = io.popen(hmac_cmd)
local signature = hmac_handle:read("*a"):gsub("%s+$", "")
hmac_handle:close()
local curl_cmd = string.format(
'curl -s -X POST "https://api.unsandbox.com%s" ' ..
'-H "Content-Type: application/json" ' ..
'-H "Authorization: Bearer %s" ' ..
'-H "X-Timestamp: %d" ' ..
'-H "X-Signature: %s" ' ..
"-d '%s'",
path, public_key, timestamp, signature, body
)
local handle = io.popen(curl_cmd)
local response = handle:read("*a")
handle:close()
print(response)
{
"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
}
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 de solicitud
| 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 | Archivos para subir (ver Archivos de Entrada) |
-- HMAC-SHA256 authenticated async execution
-- Uses openssl for HMAC signing
local public_key = os.getenv("UNSANDBOX_PUBLIC_KEY") or "unsb-pk-test-0000-0000-0001"
local secret_key = os.getenv("UNSANDBOX_SECRET_KEY") or "unsb-sk-test0-vault-unlck-12345"
-- Escape JSON string for shell
local function escape_json(str)
return str:gsub("\\", "\\\\"):gsub('"', '\\"'):gsub("\n", "\\n")
end
-- Helper function for HMAC signature
local function sign_request(method, path, body)
local timestamp = os.time()
local message = string.format("%d:%s:%s:%s", timestamp, method, path, body)
local hmac_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -hmac '%s' | sed 's/^.* //'",
message:gsub("'", "'\\''"), secret_key:gsub("'", "'\\''"))
local hmac_handle = io.popen(hmac_cmd)
local signature = hmac_handle:read("*a"):gsub("%s+$", "")
hmac_handle:close()
return timestamp, signature
end
local code = escape_json([[function factorial(n)
if n <= 1 then
return 1
else
return n * factorial(n - 1)
end
end
print("Computing factorial...")
print(factorial(20))]])
local path = "/execute/async"
local body = string.format('{"language":"lua","code":"%s","ttl":300}', code)
local timestamp, signature = sign_request("POST", path, body)
local curl_cmd = string.format(
'curl -s -X POST "https://api.unsandbox.com%s" ' ..
'-H "Content-Type: application/json" ' ..
'-H "Authorization: Bearer %s" ' ..
'-H "X-Timestamp: %d" ' ..
'-H "X-Signature: %s" ' ..
"-d '%s'",
path, public_key, timestamp, signature, body
)
local handle = io.popen(curl_cmd)
local response = handle:read("*a")
handle:close()
print(response)
{
"job_id": "ba943906-4ea6-a61c-9980-445f459368d",
"status": "pending",
"message": "Job accepted for execution"
}
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 |
-- HMAC-SHA256 authenticated request to run code with auto-detect
-- Uses openssl for HMAC signing
local public_key = os.getenv("UNSANDBOX_PUBLIC_KEY") or "unsb-pk-test-0000-0000-0001"
local secret_key = os.getenv("UNSANDBOX_SECRET_KEY") or "unsb-sk-test0-vault-unlck-12345"
local timestamp = os.time()
local method = "POST"
local path = "/run"
local body = 'print("Language auto-detected!")'
-- Generate HMAC-SHA256 signature using openssl
local message = string.format("%d:%s:%s:%s", timestamp, method, path, body)
local hmac_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -hmac '%s' | sed 's/^.* //'",
message:gsub("'", "'\\''"), secret_key:gsub("'", "'\\''"))
local hmac_handle = io.popen(hmac_cmd)
local signature = hmac_handle:read("*a"):gsub("%s+$", "")
hmac_handle:close()
local curl_cmd = string.format(
'curl -s -X POST "https://api.unsandbox.com%s" ' ..
'-H "Content-Type: text/plain" ' ..
'-H "Authorization: Bearer %s" ' ..
'-H "X-Timestamp: %d" ' ..
'-H "X-Signature: %s" ' ..
"-d '%s'",
path, public_key, timestamp, signature, body:gsub("'", "'\\''")
)
local handle = io.popen(curl_cmd)
local response = handle:read("*a")
handle:close()
print(response)
{
"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"
}
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 |
-- HMAC-SHA256 authenticated async run with auto-detect
-- Uses openssl for HMAC signing
local public_key = os.getenv("UNSANDBOX_PUBLIC_KEY") or "unsb-pk-test-0000-0000-0001"
local secret_key = os.getenv("UNSANDBOX_SECRET_KEY") or "unsb-sk-test0-vault-unlck-12345"
-- Helper function for HMAC signature
local function sign_request(method, path, body)
local timestamp = os.time()
local message = string.format("%d:%s:%s:%s", timestamp, method, path, body)
local hmac_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -hmac '%s' | sed 's/^.* //'",
message:gsub("'", "'\\''"), secret_key:gsub("'", "'\\''"))
local hmac_handle = io.popen(hmac_cmd)
local signature = hmac_handle:read("*a"):gsub("%s+$", "")
hmac_handle:close()
return timestamp, signature
end
local path = "/run/async"
local body = [[print("Running async with auto-detect!")
local sum = 0
for i = 1, 1000000 do
sum = sum + i
end
print(sum)]]
local timestamp, signature = sign_request("POST", path, body)
local curl_cmd = string.format(
'curl -s -X POST "https://api.unsandbox.com%s" ' ..
'-H "Content-Type: text/plain" ' ..
'-H "Authorization: Bearer %s" ' ..
'-H "X-Timestamp: %d" ' ..
'-H "X-Signature: %s" ' ..
"-d '%s'",
path, public_key, timestamp, signature, body:gsub("'", "'\\''")
)
local handle = io.popen(curl_cmd)
local response = handle:read("*a")
handle:close()
print(response)
{
"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
}
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 executerunning- Job currently executingcompleted- Job finished successfullyfailed- Job execution failedtimeout- Job exceeded TTL limitcancelled- Job was cancelled via DELETE
-- HMAC-SHA256 authenticated request to get job status
-- Uses openssl for HMAC signing
local public_key = os.getenv("UNSANDBOX_PUBLIC_KEY") or "unsb-pk-test-0000-0000-0001"
local secret_key = os.getenv("UNSANDBOX_SECRET_KEY") or "unsb-sk-test0-vault-unlck-12345"
local job_id = "job_1234567890_abc"
local timestamp = os.time()
local method = "GET"
local path = "/jobs/" .. job_id
local body = ""
-- Generate HMAC-SHA256 signature using openssl
local message = string.format("%d:%s:%s:%s", timestamp, method, path, body)
local hmac_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -hmac '%s' | sed 's/^.* //'",
message:gsub("'", "'\\''"), secret_key:gsub("'", "'\\''"))
local hmac_handle = io.popen(hmac_cmd)
local signature = hmac_handle:read("*a"):gsub("%s+$", "")
hmac_handle:close()
local curl_cmd = string.format(
'curl -s -X GET "https://api.unsandbox.com%s" ' ..
'-H "Authorization: Bearer %s" ' ..
'-H "X-Timestamp: %d" ' ..
'-H "X-Signature: %s"',
path, public_key, timestamp, signature
)
local handle = io.popen(curl_cmd)
local response = handle:read("*a")
handle:close()
print(response)
{
"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
}
List all active (pending or running) jobs for your API key. Useful for monitoring multiple async executions.
-- HMAC-SHA256 authenticated request to list jobs
-- Uses openssl for HMAC signing
local public_key = os.getenv("UNSANDBOX_PUBLIC_KEY") or "unsb-pk-test-0000-0000-0001"
local secret_key = os.getenv("UNSANDBOX_SECRET_KEY") or "unsb-sk-test0-vault-unlck-12345"
local timestamp = os.time()
local method = "GET"
local path = "/jobs"
local body = ""
-- Generate HMAC-SHA256 signature using openssl
local message = string.format("%d:%s:%s:%s", timestamp, method, path, body)
local hmac_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -hmac '%s' | sed 's/^.* //'",
message:gsub("'", "'\\''"), secret_key:gsub("'", "'\\''"))
local hmac_handle = io.popen(hmac_cmd)
local signature = hmac_handle:read("*a"):gsub("%s+$", "")
hmac_handle:close()
local curl_cmd = string.format(
'curl -s -X GET "https://api.unsandbox.com%s" ' ..
'-H "Authorization: Bearer %s" ' ..
'-H "X-Timestamp: %d" ' ..
'-H "X-Signature: %s"',
path, public_key, timestamp, signature
)
local handle = io.popen(curl_cmd)
local response = handle:read("*a")
handle:close()
print(response)
[
{
"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"
}
]
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 |
-- HMAC-SHA256 authenticated request to delete a job
-- Uses openssl for HMAC signing
local public_key = os.getenv("UNSANDBOX_PUBLIC_KEY") or "unsb-pk-test-0000-0000-0001"
local secret_key = os.getenv("UNSANDBOX_SECRET_KEY") or "unsb-sk-test0-vault-unlck-12345"
local job_id = "job_1234567890_abc"
local timestamp = os.time()
local method = "DELETE"
local path = "/jobs/" .. job_id
local body = ""
-- Generate HMAC-SHA256 signature using openssl
local message = string.format("%d:%s:%s:%s", timestamp, method, path, body)
local hmac_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -hmac '%s' | sed 's/^.* //'",
message:gsub("'", "'\\''"), secret_key:gsub("'", "'\\''"))
local hmac_handle = io.popen(hmac_cmd)
local signature = hmac_handle:read("*a"):gsub("%s+$", "")
hmac_handle:close()
local curl_cmd = string.format(
'curl -s -X DELETE "https://api.unsandbox.com%s" ' ..
'-H "Authorization: Bearer %s" ' ..
'-H "X-Timestamp: %d" ' ..
'-H "X-Signature: %s"',
path, public_key, timestamp, signature
)
local handle = io.popen(curl_cmd)
local response = handle:read("*a")
handle:close()
print(response)
{
"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": []
}
Las imágenes son instantáneas de contenedores independientes y transferibles que sobreviven a la eliminación del contenedor. A diferencia de las instantáneas (vinculadas al ciclo de vida del contenedor), las imágenes pueden ser:
- Transferida entre claves API
- Compartida con usuarios específicos mediante confianza
- Publicada en el marketplace
- Usada para crear nuevos servicios
Niveles de visibilidad
- private — Solo el propietario puede ver/usar (predeterminado)
- unlisted — Oculta en el listado, pero se puede compartir mediante confianza
- public — Visible para todos los usuarios (marketplace)
Publicar una imagen desde un servicio o instantánea.
Cuerpo de Solicitud
| 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 |
Metadatos de Solicitud:
{
"source_type": "service",
"source_id": "unsb-service-abc123",
"name": "my-app-v1.0",
"description": "Production-ready app image"
}
Respuesta
{
"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"
}
Listar todas las imágenes que posees o que se compartieron con tu clave API.
Endpoints relacionados
GET /images/public— Listar imágenes del marketplaceGET /images/owned— Listar solo tus imágenesGET /images/shared— Listar imágenes compartidas contigo
Respuesta
{
"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"
}
]
}
Obtener información detallada sobre una imagen.
Parámetros de URL
| Parameter | Type | Description |
|---|---|---|
id |
string | Image ID (unsb-image-xxxx) |
Respuesta
{
"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"
}
Crear un nuevo servicio usando esta imagen como base.
Cuerpo de Solicitud
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Service name | |
ports |
array | Ports to expose | |
network_mode |
string | "zerotrust" or "semitrusted" | |
bootstrap |
string | Optional bootstrap script |
Metadatos de Solicitud:
{
"name": "my-app-instance",
"ports": [8080],
"network_mode": "semitrusted"
}
Respuesta
{
"service_id": "unsb-service-xyz789",
"name": "my-app-instance",
"source_image": "unsb-image-abc123",
"state": "starting"
}
Visibilidad
POST /images/{id}/visibility
{"visibility": "unlisted"}
Clonar imagen
POST /images/{id}/clone
{
"name": "my-copy-of-app",
"description": "My personal copy"
}
Bloquear/Desbloquear
POST /images/{id}/lock— Prevenir eliminaciónPOST /images/{id}/unlock— Permitir eliminación
Eliminar imagen
DELETE /images/{id}
Otorgar acceso
POST /images/{id}/grant
{
"api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx"
}
Revocar acceso
POST /images/{id}/revoke
{
"api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx"
}
Listar claves de confianza
GET /images/{id}/trusted
{
"trusted_keys": [
"unsb-pk-aaaa-bbbb-cccc-dddd",
"unsb-pk-1111-2222-3333-4444"
]
}
Transferir propiedad
POST /images/{id}/transfer
{
"to_api_key": "unsb-pk-xxxx-xxxx-xxxx-xxxx"
}
La API retorna códigos de estado HTTP estándar junto con información detallada de errores.
| Code | Status | Description |
|---|---|---|
200 |
OK | Solicitud exitosa (revisa el campo 'success' para el resultado de ejecución) |
400 |
Bad Request | Cuerpo de solicitud inválido o faltan parámetros requeridos |
401 |
Unauthorized | Clave API / firma faltante o inválida |
403 |
Forbidden | Cuenta suspendida o función no disponible |
404 |
Not Found | ID de trabajo no encontrado o expirado |
429 |
Too Many Requests | Límite de tasa excedido |
500 |
Internal Error | Error del servidor, por favor reintenta |
Formato de respuesta de error
{
"error": "Invalid API key",
"code": "INVALID_KEY",
"details": "The provided public key does not exist"
}
Los límites de tasa se aplican por clave API y varían según el plan. Consulta los precios para detalles del plan →
Encabezados de límite de tasa
Los encabezados de respuesta incluyen información de límite de tasa:
X-RateLimit-Limit— Máximo de solicitudes por minutoX-RateLimit-Remaining— Solicitudes restantesX-RateLimit-Reset— Marca de tiempo Unix cuando el límite se restablece
Cuando se exceda el límite de tasa, espera el tiempo de restablecimiento o actualiza tu plan para obtener límites más altos.
Valida tu par de claves API y obtén su configuración incluyendo límites de tasa, límites de concurrencia y estado de expiración.
Esto es útil para:
- Verificando si tu par de claves es válido
- Viendo tus límites actuales
- Construyendo interfaces de gestión de claves
- Monitoreando expiración de claves
Autenticación
Usa autenticación HMAC estándar (igual que todos los demás 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"
}
Retorna todos los lenguajes de programación soportados y sus alias.
Alias Comunes
node,js→javascriptts→typescriptlisp→commonlisp
Respuesta
{
"languages": [
"python",
"javascript",
"typescript",
"ruby",
"go",
"rust",
"c",
"cpp"
],
"aliases": {
"js": "javascript",
"node": "javascript",
"ts": "typescript",
"lisp": "commonlisp"
},
"count": 42
}
Retorna todos los shells y REPL soportados para sesiones interactivas, agrupados por categoría.
Categorías
- 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
Respuesta
{
"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
}
Endpoint simple de verificación de estado. Retorna el estado del servicio.
Respuesta
{"status": "ok"}
Obtener información sobre el pool de contenedores y el estado del sistema.
Modos de Red
- zerotrust_only — Only isolated containers
- semitrusted_only — Only network-enabled containers
- hybrid — Both types available
Respuesta
{
"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
}
}
}
Obtener el estado de todos los pools de contenedores registrados (escalado horizontal).
Respuesta
{
"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
}
]
}
Obtener estadísticas detalladas del sistema incluyendo carga y métricas de contenedores.
Respuesta
{
"containers": 285,
"load_1min": "2.15",
"load_5min": "1.89",
"load_15min": "1.45"
}
Implementaciones SDK completas con autenticación HMAC en 42 lenguajes. Úsalas cuando necesites acceso programático desde tu propio código.
Explorar las 42 implementaciones de lenguajes →
Patrón 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")'
¿Listo para comenzar?
Obtén una clave API gratuita y comienza a ejecutar código en minutos.