Compute
Deploy full projects and manage persistent sandbox environments — no Blaxel account, no infrastructure setup, just API calls.
Quick Example
Section titled “Quick Example”import { withSapiom } from "@sapiom/axios";import axios from "axios";
const client = withSapiom(axios.create(), { apiKey: process.env.SAPIOM_API_KEY, serviceName: "Compute Sandbox", agentName: "my-agent",});
const baseUrl = "https://blaxel.services.sapiom.ai/v1";
// Step 1: Create a sandbox with a port exposedconst { data: sandbox } = await client.post(`${baseUrl}/sandboxes`, { name: "my-api", tier: "s", ttl: "2h", port: 3000,});
// Step 2: Wait for it to be readylet status = sandbox.status;while (status !== "running") { const { data: check } = await client.get(`${baseUrl}/sandboxes/${sandbox.name}`); status = check.status;}
// Step 3: Deploy codeawait client.post(`${baseUrl}/sandboxes/${sandbox.name}/deploy`, { files: { "index.js": "require('http').createServer((req, res) => res.end('Hello!')).listen(3000);", "package.json": '{"scripts":{"start":"node index.js"}}', }, runtime: "node",});
console.log("Deploying — poll sandbox status until running with a URL");import { createFetch } from "@sapiom/fetch";
const sapiomFetch = createFetch({ apiKey: process.env.SAPIOM_API_KEY, serviceName: "Compute Sandbox", agentName: "my-agent",});
const baseUrl = "https://blaxel.services.sapiom.ai/v1";
// Step 1: Create a sandbox with a port exposedconst createRes = await sapiomFetch(`${baseUrl}/sandboxes`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "my-api", tier: "s", ttl: "2h", port: 3000, }),});
const sandbox = await createRes.json();
// Step 2: Wait for it to be readylet status = sandbox.status;while (status !== "running") { const checkRes = await sapiomFetch(`${baseUrl}/sandboxes/${sandbox.name}`); const check = await checkRes.json(); status = check.status;}
// Step 3: Deploy codeawait sapiomFetch(`${baseUrl}/sandboxes/${sandbox.name}/deploy`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ files: { "index.js": "require('http').createServer((req, res) => res.end('Hello!')).listen(3000);", "package.json": '{"scripts":{"start":"node index.js"}}', }, runtime: "node", }),});
console.log("Deploying — poll sandbox status until running with a URL");How It Works
Section titled “How It Works”Sapiom provides compute environments through Blaxel:
- Sandboxes — Create persistent environments that stay running. You can interact with them via process, filesystem, and network APIs. Choose a tier based on your memory needs.
- Deploy — Push code to a sandbox. Upload files (JSON or tarball), and Blaxel handles dependency installation and process startup. Once deployed, create preview URLs to expose your service publicly.
All compute uses tier-based per-second pricing. Choose a tier based on your memory and performance needs.
Provider
Section titled “Provider”Powered by Blaxel. Blaxel provides serverless sandbox environments with support for multiple languages and runtimes.
API Reference
Section titled “API Reference”Endpoints
Section titled “Endpoints”Base URL: https://blaxel.services.sapiom.ai
| Method | Path | Description |
|---|---|---|
| POST | /v1/sandboxes | Create a sandbox |
| GET | /v1/sandboxes | List sandboxes |
| GET | /v1/sandboxes/:name | Get a sandbox |
| PATCH | /v1/sandboxes/:name | Extend sandbox TTL |
| DELETE | /v1/sandboxes/:name | Delete a sandbox |
| POST | /v1/sandboxes/:name/deploy | Deploy code to a sandbox |
Sandboxes also expose proxied runtime APIs for process management, filesystem operations, network monitoring, and previews under /v1/sandboxes/:name/....
Create Sandbox
Section titled “Create Sandbox”Endpoint: POST https://blaxel.services.sapiom.ai/v1/sandboxes
Create a persistent sandbox environment.
Request
Section titled “Request”| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Sandbox name (2-63 lowercase alphanumeric or hyphens, must start/end with alphanumeric) |
tier | string | No | xs, s, m, l, or xl (default: s) |
ttl | string | No | Time-to-live: 30m, 1h, 24h, 7d (default: 4h) |
envs | object | No | Environment variables: { "KEY": "value" } |
port | number | No | Single port to expose (shorthand for ports, mutually exclusive) |
ports | array | No | Ports to expose — numbers (e.g., [3000, 8080]) or objects (e.g., [{ target: 3000, protocol: "HTTP" }]). Required for previews. |
{ "name": "my-api", "tier": "s", "ttl": "2h", "envs": { "NODE_ENV": "production" }, "port": 3000}Response
Section titled “Response”{ "id": "sbox_01jz1234abcd", "name": "my-api", "source": "sandbox", "status": "provisioning", "tier": "s", "url": null, "expiresAt": "2026-02-25T14:30:00.000Z", "createdAt": "2026-02-25T10:30:00.000Z", "updatedAt": "2026-02-25T10:30:00.000Z"}The sandbox starts in provisioning status and transitions to running within seconds. The url field is populated once the sandbox is ready.
| Tier | Memory | Rate (per second) |
|---|---|---|
xs | 2 GB | $0.000023 |
s | 4 GB | $0.000046 |
m | 8 GB | $0.000092 |
l | 16 GB | $0.000184 |
xl | 32 GB | $0.000368 |
Extend Sandbox
Section titled “Extend Sandbox”Endpoint: PATCH https://blaxel.services.sapiom.ai/v1/sandboxes/:name
Add more time to a running sandbox.
| Parameter | Type | Required | Description |
|---|---|---|---|
ttl | string or number | No | Additional time to add ("1h" or 3600) |
Delete Sandbox
Section titled “Delete Sandbox”Endpoint: DELETE https://blaxel.services.sapiom.ai/v1/sandboxes/:name
Returns 204 No Content on success.
Deploy to Sandbox
Section titled “Deploy to Sandbox”Endpoint: POST https://blaxel.services.sapiom.ai/v1/sandboxes/:name/deploy
Deploy code to an existing sandbox. Returns 202 Accepted — the build runs asynchronously. Poll GET /v1/sandboxes/:name until status transitions to running.
Request (JSON)
Section titled “Request (JSON)”| Parameter | Type | Required | Description |
|---|---|---|---|
files | object | Yes | File map: { "path": "content" } |
runtime | string | No | node, python, go, static, or custom (auto-detected if omitted) |
entrypoint | string | No | Start command (auto-detected if omitted) |
{ "files": { "index.js": "const http = require('http');\nhttp.createServer((req, res) => res.end('Hello')).listen(3000);", "package.json": "{\"name\": \"my-api\", \"scripts\": {\"start\": \"node index.js\"}}" }, "runtime": "node"}Deploy also accepts tarball uploads (Content-Type: application/gzip) with metadata via query params (runtime, entrypoint).
Response (202 Accepted)
Section titled “Response (202 Accepted)”{ "id": "sbox_01jz1234abcd", "name": "my-api", "status": "building", "source": "sandbox", "tier": "s", "url": null, "createdAt": "2026-02-25T10:30:00.000Z"}Runtime Proxy Endpoints
Section titled “Runtime Proxy Endpoints”Once a sandbox is running, Sapiom proxies Blaxel runtime APIs for direct interaction:
Process management:
POST /v1/sandboxes/:name/process— Create a processGET /v1/sandboxes/:name/process— List processesGET /v1/sandboxes/:name/process/:pid— Get process detailsDELETE /v1/sandboxes/:name/process/:pid— Delete processDELETE /v1/sandboxes/:name/process/:pid/kill— Kill processGET /v1/sandboxes/:name/process/:pid/logs— Get logsGET /v1/sandboxes/:name/process/:pid/logs/stream— Stream logs (SSE)
Filesystem:
GET /v1/sandboxes/:name/filesystem/*path— Read filePUT /v1/sandboxes/:name/filesystem/*path— Write fileDELETE /v1/sandboxes/:name/filesystem/*path— Delete fileGET /v1/sandboxes/:name/filesystem/tree/*path— Get directory treeGET /v1/sandboxes/:name/filesystem/find— Find filesGET /v1/sandboxes/:name/filesystem/search— Search file contents
Network:
GET /v1/sandboxes/:name/network/process/:pid/ports— Get open ports for a processPOST /v1/sandboxes/:name/network/process/:pid/ports/monitor— Start port monitoringDELETE /v1/sandboxes/:name/network/process/:pid/ports/monitor— Stop port monitoring
Previews:
POST /v1/sandboxes/:name/previews— Create a public preview URLGET /v1/sandboxes/:name/previews— List previews
Sandbox Status Lifecycle
Section titled “Sandbox Status Lifecycle”| Status | Description |
|---|---|
provisioning | Sandbox is being created |
building | Code is being deployed (after deploy call) |
running | Ready for use |
stopped | Sandbox has stopped |
failed | Creation or deployment failed (check error field) |
deleting | Deletion in progress |
deleted | Fully removed |
Error Codes
Section titled “Error Codes”| Code | Description |
|---|---|
| 400 | Invalid request — check parameter values and file paths |
| 402 | Payment required — ensure you’re using the Sapiom SDK |
| 404 | Sandbox not found, or not owned by your account |
| 409 | Name conflict (sandbox name already in use) or sandbox not in a deployable state |
| 410 | Sandbox has been deleted |
| 422 | Sandbox limit exceeded for your account |
| 429 | Rate limit exceeded |
| 502 | Upstream error from Blaxel |
| 503 | Sandbox not yet ready (still provisioning) |
| 504 | Upstream timeout |
Complete Example
Section titled “Complete Example”import { withSapiom } from "@sapiom/axios";import axios from "axios";
const client = withSapiom(axios.create(), { apiKey: process.env.SAPIOM_API_KEY, serviceName: "Compute Sandbox", agentName: "my-agent",});
const baseUrl = "https://blaxel.services.sapiom.ai/v1";
async function deployService() { // Create a sandbox with port 3000 exposed const { data: sandbox } = await client.post(`${baseUrl}/sandboxes`, { name: "my-api", tier: "s", ttl: "2h", port: 3000, });
console.log(`Sandbox created: ${sandbox.name}`);
// Wait for sandbox to be ready let current = sandbox; while (current.status !== "running") { const { data: check } = await client.get( `${baseUrl}/sandboxes/${sandbox.name}` ); current = check; }
// Deploy a Node.js server await client.post(`${baseUrl}/sandboxes/${sandbox.name}/deploy`, { files: { "index.js": ` const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ status: 'ok', time: new Date().toISOString() })); }); server.listen(3000, () => console.log('Listening on :3000')); `, "package.json": '{"name":"my-api","scripts":{"start":"node index.js"}}', }, runtime: "node", });
// Wait for deploy to complete let deployed = current; while (deployed.status !== "running" || !deployed.url) { const { data: check } = await client.get( `${baseUrl}/sandboxes/${sandbox.name}` ); deployed = check; }
console.log(`Service live at ${deployed.url}`);
// Create a public preview URL const { data: preview } = await client.post( `${baseUrl}/sandboxes/${sandbox.name}/previews`, { port: 3000 } );
console.log(`Preview URL: ${preview.url}`);
// Clean up when done // await client.delete(`${baseUrl}/sandboxes/${sandbox.name}`);}
await deployService();import { createFetch } from "@sapiom/fetch";
const sapiomFetch = createFetch({ apiKey: process.env.SAPIOM_API_KEY, serviceName: "Compute Sandbox", agentName: "my-agent",});
const baseUrl = "https://blaxel.services.sapiom.ai/v1";
async function deployService() { // Create a sandbox with port 3000 exposed const createRes = await sapiomFetch(`${baseUrl}/sandboxes`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "my-api", tier: "s", ttl: "2h", port: 3000, }), });
const sandbox = await createRes.json(); console.log(`Sandbox created: ${sandbox.name}`);
// Wait for sandbox to be ready let current = sandbox; while (current.status !== "running") { const checkRes = await sapiomFetch( `${baseUrl}/sandboxes/${sandbox.name}` ); current = await checkRes.json(); }
// Deploy a Node.js server await sapiomFetch(`${baseUrl}/sandboxes/${sandbox.name}/deploy`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ files: { "index.js": ` const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ status: 'ok', time: new Date().toISOString() })); }); server.listen(3000, () => console.log('Listening on :3000')); `, "package.json": '{"name":"my-api","scripts":{"start":"node index.js"}}', }, runtime: "node", }), });
// Wait for deploy to complete let deployed = current; while (deployed.status !== "running" || !deployed.url) { const checkRes = await sapiomFetch( `${baseUrl}/sandboxes/${sandbox.name}` ); deployed = await checkRes.json(); }
console.log(`Service live at ${deployed.url}`);
// Create a public preview URL const previewRes = await sapiomFetch( `${baseUrl}/sandboxes/${sandbox.name}/previews`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ port: 3000 }), } );
const preview = await previewRes.json(); console.log(`Preview URL: ${preview.url}`);
// Clean up when done // await sapiomFetch(`${baseUrl}/sandboxes/${sandbox.name}`, { method: "DELETE" });}
await deployService();Pricing
Section titled “Pricing”| Operation | Cost |
|---|---|
| Sandbox — XS (2 GB) | $0.000023/second |
| Sandbox — S (4 GB) | $0.000046/second |
| Sandbox — M (8 GB) | $0.000092/second |
| Sandbox — L (16 GB) | $0.000184/second |
| Sandbox — XL (32 GB) | $0.000368/second |
| Deploy, list, get, delete | Nominal ($0.00001) |
Sandbox pricing is calculated upfront based on tier and TTL. Extending a sandbox’s TTL costs the tier rate multiplied by the additional time.