API Reference

Workloads

Workloads are managed background processes running inside your workspace. Each workload has its own lifecycle (start/stop), logging, and status tracking.

Stable IDs and project labels

Set id when a project needs a stable workload identity inside a shared workspace. IDs are unique within that workspace, and the same ID may be used in another workspace. Create, get and list preserve the ID and labels, including after a cold workspace restart. Omit id to generate the next available numeric ID.

An ID must contain 1–128 letters, numbers, dots, underscores or hyphens, starting with a letter or number. labels accepts up to 64 string values; keys must be 1–128 bytes and values at most 1024 bytes. Invalid input returns HTTP 400 with invalid_workload_id or invalid_workload_labels.

Creating the same ID again returns HTTP 409 / workload_id_conflict. It does not replace the command, labels or running process. On an ambiguous network failure, get the requested ID and verify its configuration before deciding to update it. Labels describe a workload; they do not grant access or change the workspace's account or namespace ownership. Workspace permissions apply to all workloads in that workspace; use separate workspaces for customers that must not control each other's processes.

const workload = await ws.workloads.create('ws_a1b2c3d4', {
  id: 'project-42-web',
  cmd: ['node', 'server.js'],
  labels: { project: '42', role: 'web' },
});
const sameWorkload = await ws.workloads.get('ws_a1b2c3d4', workload.id);

REST create/get responses wrap the object in workload; list responses use workloads. The SDK returns the workload object or array directly.

Log retention and cleanup

Managed workload logs have bounded retention. By default, each workload keeps up to 20 MiB across two files, for up to 7 days. Size rotation may remove records sooner. Very high output rates can drop excess lines; these logs are a recent operational history, not an archival logging service.

Set these fields when creating a workload, or send them to PATCH /workspace/:workspaceId/workloads/:workloadId:

FieldDefaultAllowed values
max_log_size_mb101–64 MiB per file; two files retained
log_retention_hours1681–720 hours

Zero resets a field to its bounded default; it does not disable retention. Reducing a limit can delete older output immediately. Updating retention requires a running workspace and does not restart the workload.

PATCH /workspace/:workspaceId/workloads/:workloadId
Content-Type: application/json

{"max_log_size_mb": 5, "log_retention_hours": 24}

Use the normal workspace API credentials for these endpoints:

OperationEndpoint
Applied limits, stored bytes and dropped-output countGET /workspace/:workspaceId/workloads/:workloadId/logs/config
Delete retained workload logsDELETE /workspace/:workspaceId/workloads/:workloadId/logs
Recent history, at most the requested number of linesGET /workspace/:workspaceId/workloads/:workloadId/logs?tail=2000

Clearing logs removes both retained files' contents and keeps the process running. New output appears immediately. The dropped-output count covers this agent run. A live stream sends cleared: true when history is cleared; viewers should discard older entries when they receive it. Slow viewers may disconnect and can reconnect to fetch the retained tail.

In the dashboard, open a workload's logs and use Log retention or Clear stored logs. The viewer retains at most 2,000 entries and 1 MiB. Pausing the viewer disconnects its stream; resuming loads the retained tail.

The SDK helpers are workloads.logConfig(), workloads.clearLogs(), and workloads.update() with the fields above. If your installed SDK does not yet include these helpers, use the REST endpoints. Older workspace agents return an explicit update-required error for these controls.

Create

Create and start a new workload.

const workload = await ws.workloads.create('ws_a1b2c3d4', {
  cmd: ['node', 'server.js'],
  name: 'web-server',
  labels: { role: 'api', env: 'production' },
});
POST /workspace/:workspaceId/workloads
{
  "cmd": ["node", "server.js"],
  "name": "web-server",
  "labels": { "role": "api", "env": "production" }
}
curl -X POST "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "cmd": ["node", "server.js"],
    "name": "web-server",
    "labels": { "role": "api" }
  }'

Parameters

ParameterTypeRequiredDescription
cmdstring[]YesCommand array (non-empty)
commandstring[]-Alias for cmd
idstringNoStable workspace-scoped ID; generated if omitted; duplicate IDs return 409
namestringNoHuman-readable workload name
labelsRecord<string, string>NoUp to 64 metadata labels, persisted with the workload

Response 201

{
  "success": true,
  "workload": {
    "id": "wl_xyz789",
    "name": "web-server",
    "command": ["node", "server.js"],
    "labels": { "role": "api", "env": "production" },
    "state": "running",
    "created_at": "2026-02-24T10:30:00Z"
  }
}

List

List all workloads. Supports filtering by state, name, and labels.

const workloads = await ws.workloads.list('ws_a1b2c3d4', {
  states: 'running',
  name: 'web',
});
GET /workspace/:workspaceId/workloads?states=running&name=web
curl "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads?states=running" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Query parameters

ParameterTypeDescription
statesstringFilter by state (e.g., "running", "stopped")
namestringFilter by name (partial match)
label_*stringFilter by label. e.g., label_role=api

Get

Get a specific workload.

const workload = await ws.workloads.get('ws_a1b2c3d4', 'wl_xyz789');
GET /workspace/:workspaceId/workloads/:workloadId
curl "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Update

Update a workload's configuration.

await ws.workloads.update('ws_a1b2c3d4', 'wl_xyz789', {
  name: 'web-server-v2',
  labels: { version: '2.0' },
});
PUT /workspace/:workspaceId/workloads/:workloadId
{
  "name": "web-server-v2",
  "labels": { "version": "2.0" }
}
curl -X PUT "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "name": "web-server-v2" }'

Delete

Delete a specific workload.

await ws.workloads.delete('ws_a1b2c3d4', 'wl_xyz789');
DELETE /workspace/:workspaceId/workloads/:workloadId
curl -X DELETE "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Delete all

Delete all workloads in the workspace.

await ws.workloads.deleteAll('ws_a1b2c3d4');
DELETE /workspace/:workspaceId/workloads
curl -X DELETE "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Start

Start a stopped workload.

await ws.workloads.start('ws_a1b2c3d4', 'wl_xyz789');
POST /workspace/:workspaceId/workloads/:workloadId/start
curl -X POST "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789/start" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Stop

Stop a running workload.

await ws.workloads.stop('ws_a1b2c3d4', 'wl_xyz789');
POST /workspace/:workspaceId/workloads/:workloadId/stop
curl -X POST "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789/stop" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Status

Get the current status of a workload.

const status = await ws.workloads.status('ws_a1b2c3d4', 'wl_xyz789');
GET /workspace/:workspaceId/workloads/:workloadId/status
curl "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789/status" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Logs

Get logs for a workload.

const logs = await ws.workloads.logs('ws_a1b2c3d4', 'wl_xyz789');
GET /workspace/:workspaceId/workloads/:workloadId/logs
curl "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789/logs" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Stream logs

Stream workload logs in real-time via SSE (Server-Sent Events).

for await (const entry of ws.workloads.logsStream('ws_a1b2c3d4', 'wl_xyz789')) {
  console.log(entry.line);
}
GET /workspace/:workspaceId/workloads/:workloadId/logs/stream

Returns an SSE stream with 15-second heartbeat. Initial comment: :ok\n\n

:ok

data: {"line":"Server started on port 3000","timestamp":"2026-02-24T10:30:01Z"}

data: {"line":"GET / 200 12ms","timestamp":"2026-02-24T10:30:05Z"}
curl -N "https://api.oblien.com/workspace/ws_a1b2c3d4/workloads/wl_xyz789/logs/stream" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Close the connection to stop streaming.