Compute API (Modal Sandbox)
Isolated code execution in secure cloud containers via Modal. Create sandboxes, execute arbitrary commands, manage lifecycle. Supports resource limits, network isolation, and automatic cleanup. Designed as a secure runtime for AI agent code execution.
Base URL: https://api.jarvisclaw.ai/v1/marketplace/compute
Endpoints
| Method | Endpoint | Description | Price |
|---|---|---|---|
| POST | /sandbox/create | Create a new isolated sandbox | $0.01 (CPU, ≤300s) |
| POST | /sandbox/exec | Execute a command in a sandbox | $0.001/request |
| POST | /sandbox/status | Get sandbox status | $0.001/request |
| POST | /sandbox/terminate | Terminate and cleanup | $0.001/request |
Pricing
Two billing modes selected automatically by the requested timeout: short bursts pay a flat rate, long-lived sandboxes pay per hour.
Burst — timeout ≤ 300s
Flat rate per sandbox/create, covers the full short-lived session. Lifecycle ops (exec, status, terminate) at $0.001/request.
| Config | Price | Resources |
|---|---|---|
| CPU | $0.01/sandbox | Up to 1 vCPU, 1 GiB RAM, 300s lifetime |
| GPU — T4 | $0.05/sandbox | Up to 8 vCPU, 32 GiB RAM, 300s lifetime |
| GPU — L4 | $0.08/sandbox | Up to 8 vCPU, 32 GiB RAM, 300s lifetime |
| GPU — A10G | $0.10/sandbox | Up to 8 vCPU, 32 GiB RAM, 300s lifetime |
| GPU — A100 | $0.20/sandbox | Up to 8 vCPU, 32 GiB RAM, 300s lifetime |
| GPU — H100 | $0.40/sandbox | Up to 8 vCPU, 32 GiB RAM, 300s lifetime |
Long-lived — timeout > 300s, up to 24h
Per-hour rate × requested duration, billed upfront in one x402 settlement. No refund on early terminate (same as cloud-instance norms). Hours are exact — 90min on T4 = 1.5 × $1.50 = $2.25.
| Config | Per hour | Use cases |
|---|---|---|
| CPU (1 vCPU / 1 GiB) | $0.10 | Batch jobs, scrapers, schedulers |
| T4 (up to 8 vCPU / 32 GiB) | $1.50 | Light inference, small models |
| L4 (up to 8 vCPU / 32 GiB) | $2.00 | Mid-tier inference |
| A10G (up to 8 vCPU / 32 GiB) | $2.50 | Stable diffusion, 7B inference |
| A100 (up to 8 vCPU / 32 GiB) | $4.00 | Training, 13B–70B inference |
| H100 (up to 8 vCPU / 32 GiB) | $8.00 | Frontier training, low-latency 70B+ |
POST /sandbox/create
Create a new isolated sandbox container.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
image | string | No | Docker image. Default: python:3.11 |
timeout | integer | No | Max sandbox lifetime in seconds. ≤300 = flat rate, >300 = per-hour billing. Default: 300, Max: 86400 (24h) |
Request
{
"image": "python:3.11",
"timeout": 300
}Response
{
"sandbox_id": "sb_a1b2c3d4e5",
"status": "running",
"created_at": "2026-06-13T10:00:00Z",
"expires_at": "2026-06-13T10:05:00Z"
}POST /sandbox/exec
Run a command inside an existing sandbox.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
sandbox_id | string | Yes | Sandbox identifier |
command | string or array | Yes | Shell command (string) or command array (e.g. ["python", "-c", "print(1)"]) |
Request
{
"sandbox_id": "sb_a1b2c3d4e5",
"command": ["python", "-c", "import sys; print(sys.version)"]
}Response
{
"exit_code": 0,
"stdout": "3.11.9 (main, Apr 2 2024, 08:25:04) [GCC 12.2.0]\n",
"stderr": "",
"duration_ms": 45
}POST /sandbox/status
Get current status and metadata of a sandbox.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
sandbox_id | string | Yes | Sandbox identifier |
Request
{
"sandbox_id": "sb_a1b2c3d4e5"
}Response
{
"sandbox_id": "sb_a1b2c3d4e5",
"status": "running",
"created_at": "2026-06-13T10:00:00Z",
"expires_at": "2026-06-13T10:05:00Z",
"commands_executed": 3
}POST /sandbox/terminate
Immediately terminate a sandbox and release all resources.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
sandbox_id | string | Yes | Sandbox identifier |
Request
{
"sandbox_id": "sb_a1b2c3d4e5"
}Response
{
"sandbox_id": "sb_a1b2c3d4e5",
"status": "terminated"
}Errors
| HTTP Status | Code | Description |
|---|---|---|
| 404 | sandbox_not_found | The specified sandbox_id does not exist |
| 410 | sandbox_terminated | The sandbox has already been terminated |
| 408 | sandbox_timeout | The sandbox exceeded its timeout and was auto-terminated |
| 500 | exec_failed | Command execution failed due to an internal error |
Code Examples
# Create a sandbox
curl -X POST https://api.jarvisclaw.ai/v1/marketplace/compute/sandbox/create \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{"timeout": 300}'
# Execute a command
curl -X POST https://api.jarvisclaw.ai/v1/marketplace/compute/sandbox/exec \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{"sandbox_id": "sb_a1b2c3d4e5", "command": "python -c \"print(2+2)\""}'
# Check status
curl -X POST https://api.jarvisclaw.ai/v1/marketplace/compute/sandbox/status \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{"sandbox_id": "sb_a1b2c3d4e5"}'
# Terminate
curl -X POST https://api.jarvisclaw.ai/v1/marketplace/compute/sandbox/terminate \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{"sandbox_id": "sb_a1b2c3d4e5"}'import requests
BASE = "https://api.jarvisclaw.ai/v1/marketplace/compute/sandbox"
HEADERS = {
"Authorization": "Bearer sk-your-api-key",
"Content-Type": "application/json",
}
# Create a sandbox
resp = requests.post(f"{BASE}/create", headers=HEADERS, json={
"timeout": 300,
})
sandbox_id = resp.json()["sandbox_id"]
print(f"Created sandbox: {sandbox_id}")
# Execute a command
resp = requests.post(f"{BASE}/exec", headers=HEADERS, json={
"sandbox_id": sandbox_id,
"command": "python -c \"import math; print(math.pi)\"",
})
print(resp.json()["stdout"])
# Check status
resp = requests.post(f"{BASE}/status", headers=HEADERS, json={
"sandbox_id": sandbox_id,
})
print(resp.json()["status"])
# Terminate when done
requests.post(f"{BASE}/terminate", headers=HEADERS, json={
"sandbox_id": sandbox_id,
})from jarvisclaw import ComputeClient
# --- Option A: Base chain (EVM) ---
# Hex private key -> USDC on Base (Chain ID 8453)
compute = ComputeClient(private_key="0x<evm-private-key>")
# --- Option B: Solana ---
# Base58 keypair -> USDC SPL on Solana mainnet
# compute = ComputeClient(private_key="<solana-bs58-keypair>")
# SDK auto-detects chain from key format - no config needed
# Create a sandbox
sandbox = compute.create(timeout=300)
print(f"Sandbox ID: {sandbox.sandbox_id}")
# Execute commands
result = compute.exec(sandbox.sandbox_id, "pip install numpy && python -c \"import numpy; print(numpy.__version__)\"")
print(result.stdout)
result = compute.exec(sandbox.sandbox_id, "python -c \"import numpy as np; print(np.random.rand(3))\"")
print(result.stdout)
# Check status
status = compute.status(sandbox.sandbox_id)
print(f"Commands run: {status.commands_executed}")
# Terminate
compute.terminate(sandbox.sandbox_id)package main
import (
"context"
"fmt"
jc "github.com/api-jarvisclaw/go-sdk"
)
func main() {
ctx := context.Background()
cc, _ := jc.NewComputeClient(jc.WithAPIKey("sk-your-api-key"))
// Create a sandbox
sandbox, _ := cc.Create(ctx, jc.WithTimeout(300))
fmt.Printf("Sandbox ID: %s\n", sandbox.SandboxID)
// Execute a command
result, _ := cc.Exec(ctx, sandbox.SandboxID, "python -c \"print('hello')\"")
fmt.Printf("Output: %s\n", result.Stdout)
// Check status
status, _ := cc.Status(ctx, sandbox.SandboxID)
fmt.Printf("Status: %s, Commands: %d\n", status.Status, status.CommandsExecuted)
// Terminate
cc.Terminate(ctx, sandbox.SandboxID)
}package main
import (
"context"
"fmt"
jc "github.com/api-jarvisclaw/go-sdk"
)
func main() {
ctx := context.Background()
// x402 Agent wallet - pays per-call via USDC on Base (Chain ID 8453)
cc, _ := jc.NewComputeClient(jc.WithPrivateKey("0x<evm-private-key>"))
// Create a sandbox
sandbox, _ := cc.Create(ctx, jc.WithTimeout(300))
fmt.Printf("Sandbox ID: %s\n", sandbox.SandboxID)
// Execute commands
result, _ := cc.Exec(ctx, sandbox.SandboxID, "python -c \"print('agent execution')\"")
fmt.Printf("Output: %s\n", result.Stdout)
// Terminate when done
cc.Terminate(ctx, sandbox.SandboxID)
}Limitations
- 24h max timeout — sandboxes auto-terminate after the configured timeout (max 86400s)
- Flat-rate for short tasks — ≤300s gets flat CPU $0.01, longer sessions billed per hour
- No persistent storage — all data is lost when the sandbox terminates
- No inbound connections — sandboxes cannot receive network traffic from outside
- 10MB max payload — request and response bodies are capped at 10MB
- Outbound HTTP allowed — sandboxes can make outbound requests (pip install, curl, etc.)