Skip to content
Go To Dashboard

Compute

Deploy full projects and manage persistent sandbox environments — no Blaxel account, no infrastructure setup, just API calls.

import { createFetch } from "@sapiom/fetch";
const sapiomFetch = createFetch({
apiKey: process.env.SAPIOM_API_KEY,
agentName: "my-agent",
});
const baseUrl = "https://blaxel.services.sapiom.ai/v1";
// Step 1: Create a sandbox with a port 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();
// Step 2: Wait for it to be ready
let 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 code
await 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");

Sapiom provides compute environments through Blaxel:

  1. 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.
  2. 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.

Powered by Blaxel. Blaxel provides serverless sandbox environments with support for multiple languages and runtimes.

Base URL: https://blaxel.services.sapiom.ai

MethodPathDescription
POST/v1/sandboxesCreate a sandbox
GET/v1/sandboxesList sandboxes
GET/v1/sandboxes/:nameGet a sandbox
PATCH/v1/sandboxes/:nameExtend sandbox TTL
DELETE/v1/sandboxes/:nameDelete a sandbox
POST/v1/sandboxes/:name/deployDeploy code to a sandbox

Sandboxes also expose proxied runtime APIs for process management, filesystem operations, network monitoring, and previews under /v1/sandboxes/:name/....


Endpoint: POST https://blaxel.services.sapiom.ai/v1/sandboxes

Create a persistent sandbox environment.

ParameterTypeRequiredDescription
namestringYesSandbox name (2-63 lowercase alphanumeric or hyphens, must start/end with alphanumeric)
tierstringNoxs, s, m, l, or xl (default: s)
ttlstringNoTime-to-live: 30m, 1h, 24h, 7d (default: 4h)
envsobjectNoEnvironment variables: { "KEY": "value" }
portnumberNoSingle port to expose (shorthand for ports, mutually exclusive)
portsarrayNoPorts 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
}
{
"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.

TierMemoryRate (per second)
xs2 GB$0.000023
s4 GB$0.000046
m8 GB$0.000092
l16 GB$0.000184
xl32 GB$0.000368

Endpoint: PATCH https://blaxel.services.sapiom.ai/v1/sandboxes/:name

Add more time to a running sandbox.

ParameterTypeRequiredDescription
ttlstring or numberNoAdditional time to add ("1h" or 3600)

Endpoint: DELETE https://blaxel.services.sapiom.ai/v1/sandboxes/:name

Returns 204 No Content on success.


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.

ParameterTypeRequiredDescription
filesobjectYesFile map: { "path": "content" }
runtimestringNonode, python, go, static, or custom (auto-detected if omitted)
entrypointstringNoStart 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).

{
"id": "sbox_01jz1234abcd",
"name": "my-api",
"status": "building",
"source": "sandbox",
"tier": "s",
"url": null,
"createdAt": "2026-02-25T10:30:00.000Z"
}

Once a sandbox is running, Sapiom proxies Blaxel runtime APIs for direct interaction:

Process management:

  • POST /v1/sandboxes/:name/process — Create a process
  • GET /v1/sandboxes/:name/process — List processes
  • GET /v1/sandboxes/:name/process/:pid — Get process details
  • DELETE /v1/sandboxes/:name/process/:pid — Delete process
  • DELETE /v1/sandboxes/:name/process/:pid/kill — Kill process
  • GET /v1/sandboxes/:name/process/:pid/logs — Get logs
  • GET /v1/sandboxes/:name/process/:pid/logs/stream — Stream logs (SSE)

Filesystem:

  • GET /v1/sandboxes/:name/filesystem/*path — Read file
  • PUT /v1/sandboxes/:name/filesystem/*path — Write file
  • DELETE /v1/sandboxes/:name/filesystem/*path — Delete file
  • GET /v1/sandboxes/:name/filesystem/tree/*path — Get directory tree
  • GET /v1/sandboxes/:name/filesystem/find — Find files
  • GET /v1/sandboxes/:name/filesystem/search — Search file contents

Network:

  • GET /v1/sandboxes/:name/network/process/:pid/ports — Get open ports for a process
  • POST /v1/sandboxes/:name/network/process/:pid/ports/monitor — Start port monitoring
  • DELETE /v1/sandboxes/:name/network/process/:pid/ports/monitor — Stop port monitoring

Previews:

  • POST /v1/sandboxes/:name/previews — Create a public preview URL
  • GET /v1/sandboxes/:name/previews — List previews


Endpoint: POST https://blaxel.services.sapiom.ai/v1/run

Execute code in an ephemeral sandbox. The response includes stdout, stderr, and exit code. The sandbox is automatically cleaned up after execution.

ParameterTypeRequiredDescription
languagestringYespython, node, typescript, bash, ruby, go
codestringConditionalInline source code (mutually exclusive with files)
filesobjectConditionalFile map: { "path": "content" } (mutually exclusive with code)
entrypointstringNoMain file when using files
packagesstring[]NoPackages to install (pip/npm) before execution
timeoutnumberNoMax execution time in seconds (default: 30, max: 600)
{
"language": "python",
"code": "import math\nprint(f'Pi is {math.pi:.4f}')",
"timeout": 10
}
{
"id": "run_abc123",
"status": "completed",
"language": "python",
"stdout": "Pi is 3.1416\n",
"stderr": "",
"exitCode": 0,
"durationMs": 842,
"createdAt": "2026-03-01T10:30:00.000Z",
"completedAt": "2026-03-01T10:30:01.000Z"
}
MethodPathDescription
GET/v1/runsList recent runs
GET/v1/runs/:idGet run result

Runs use XS tier ($0.000023/second) for the configured timeout:

TimeoutPrice
30s (default)$0.00069
60s$0.00138
600s (max)$0.0138

Jobs are stateless serverless functions deployed to Blaxel. They can run on-demand or on a cron schedule.

Endpoint: POST https://blaxel.services.sapiom.ai/v1/jobs

ParameterTypeRequiredDescription
namestringYesUnique job name
filesobjectYesFile map: { "path": "content" }
runtimestringNonode, python, etc. (auto-detected if omitted)
runtimeConfigobjectNoRuntime configuration
runtimeConfig.memorynumberNoMemory in MB, 128-4096 (default: 256)
runtimeConfig.timeoutnumberNoTimeout in seconds, 1-3600 (default: 300)
schedulestringNoCron expression for scheduled execution
envsobjectNoEnvironment variables

Also accepts binary uploads (application/zip or application/x-tar+gzip) with metadata via query params.

MethodPathDescription
POST/v1/jobsDeploy a job
GET/v1/jobsList jobs
GET/v1/jobs/:nameGet job details
PUT/v1/jobs/:nameRedeploy (update) a job
DELETE/v1/jobs/:nameDelete a job

Endpoint: POST https://blaxel.services.sapiom.ai/v1/jobs/:name/executions

ParameterTypeRequiredDescription
tasksarrayYesArray of task payloads (each element runs as one task)
envobjectNoEnvironment variable overrides
memorynumberNoMemory override in MB
MethodPathDescription
POST/v1/jobs/:name/executionsTrigger execution
GET/v1/jobs/:name/executionsList executions
GET/v1/jobs/:name/executions/:idGet execution details

All job operations are nominally priced at $0.00001 per API call.


StatusDescription
provisioningSandbox is being created
buildingCode is being deployed (after deploy call)
runningReady for use
stoppedSandbox has stopped
failedCreation or deployment failed (check error field)
deletingDeletion in progress
deletedFully removed
CodeDescription
400Invalid request — check parameter values and file paths
402Payment required — ensure you’re using the Sapiom SDK
404Sandbox not found, or not owned by your account
409Name conflict (sandbox name already in use) or sandbox not in a deployable state
410Sandbox has been deleted
422Sandbox limit exceeded for your account
429Rate limit exceeded
502Upstream error from Blaxel
503Sandbox not yet ready (still provisioning)
504Upstream timeout
import { createFetch } from "@sapiom/fetch";
const sapiomFetch = createFetch({
apiKey: process.env.SAPIOM_API_KEY,
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();
OperationCost
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, deleteNominal ($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.