API Reference

Workspaces

Core CRUD operations for managing workspaces. A workspace is an isolated micro-VM with its own filesystem, network, and resources.

Create workspace

Create a new workspace from an image.

const workspace = await ws.create({
  name: 'my-app',
  image: 'node-20',
  namespace: 'production',
  mode: 'permanent',
  config: {
    cpus: 2,
    memory_mb: 2048,
    writable_size_mb: 1024,
    ttl: '1h',
    ttl_action: 'stop',
    remove_on_exit: false,
    restart_policy: 'always',
    max_restarts: 5,
    keep_logs: true,
    static_network: true,
    network_config: {
      allow_internet: true,
      public_ingress: false,
    },
    ssh_access: true,
    env: [
      { key: 'NODE_ENV', value: 'production' },
      { key: 'PORT', value: '3000' },
    ],
    cmd: ['node', 'server.js'],
    workloads: [],
    wait_for_init: true,
    proxy_assignment_id: 42,
  },
});
POST /workspace
{
  "name": "my-app",
  "image": "node-20",
  "namespace": "production",
  "mode": "permanent",
  "config": {
    "cpus": 2,
    "memory_mb": 2048,
    "writable_size_mb": 1024,
    "ttl": "1h",
    "ttl_action": "stop",
    "remove_on_exit": false,
    "restart_policy": "always",
    "max_restarts": 5,
    "keep_logs": true,
    "static_network": true,
    "network_config": {
      "allow_internet": true,
      "public_ingress": false
    },
    "ssh_access": true,
    "env": [
      { "key": "NODE_ENV", "value": "production" },
      { "key": "PORT", "value": "3000" }
    ],
    "cmd": ["node", "server.js"],
    "workloads": [],
    "wait_for_init": true,
    "proxy_assignment_id": 42
  }
}
curl -X POST https://api.oblien.com/workspace \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-app",
    "image": "node-20",
    "config": { "cpus": 2, "memory_mb": 2048 }
  }'

Parameters

ParameterTypeRequiredDescription
namestringNoDisplay name (max 255 characters)
imagestringYesBase image ID. See Images
namespacestringNoNamespace for organization (alphanumeric + hyphens)
modestringNo"permanent" or "temporary". Default: "temporary"
configobjectNoConfiguration object (see below)
typestringNoWorkspace type identifier

Config object

FieldTypeDefaultDescription
cpusnumber1CPU cores (1–32, subject to plan limits)
memory_mbnumber512Memory in MB (128–65536, subject to plan limits)
writable_size_mbnumber512Writable disk in MB (64–204800, subject to plan limits)
ttlstring-Time to live (e.g., "30m", "1h", "24h"). Only for temporary mode
ttl_actionstring"stop"Action when TTL expires: "stop" or "remove"
remove_on_exitbooleanfalseAuto-delete workspace when VM exits
restart_policystring"no""no", "always", "on-failure"
max_restartsnumber0Max restart attempts (0 = unlimited when policy is set)
keep_logsbooleantruePersist logs across restarts
static_networkbooleanfalseAssign a static internal IP
network_configobject-Network policy (see below)
ssh_accessbooleanfalseEnable SSH on creation
envarray[]Environment variables: [{ key, value }]
cmdarray-Override startup command: ["node", "server.js"]
workloadsarray[]Workloads to start on boot
wait_for_initbooleanfalseWait for VM to be fully initialized before returning
proxy_assignment_idnumber-Outbound IP proxy assignment ID

Network config

FieldTypeDefaultDescription
allow_internetbooleantrueAllow outbound internet access
public_ingressbooleanfalseAllow inbound from public internet

Response 201

{
  "success": true,
  "workspace": {
    "id": "ws_a1b2c3d4",
    "name": "my-app",
    "namespace": "production",
    "mode": "permanent",
    "image": "node-20",
    "ip": "10.0.0.15",
    "uptime": 0,
    "start_time": "2026-02-24T10:30:00Z",
    "info": {
      "status": "running",
      "is_running": true,
      "user_requested_stop": false
    },
    "access": {
      "ssh_enabled": false
    },
    "network": {
      "allow_internet": true,
      "ingress_ports": [],
      "egress_ports": [],
      "egress": [],
      "public_access": false,
      "ingress": []
    },
    "public_ports": [],
    "resources": {
      "cpus": 2,
      "memory_mb": 2048,
      "disk_size_mb": 1024
    },
    "created_at": "2026-02-24T10:30:00Z",
    "updated_at": "2026-02-24T10:30:00Z"
  }
}

Errors

CodeStatusCause
MISSING_USER_ID401Authentication failed
INVALID_NAMESPACE400Namespace contains invalid characters
INVALID_NAME_LENGTH400Name exceeds 255 characters
INVALID_IMAGE400Image ID is not a string or is empty
INVALID_CONFIG400Config is not an object
SANDBOX_LIMIT_REACHED402Maximum workspace count for your plan
RESOURCE_NOT_ALLOWED403Requested resources exceed plan limits
POOL_LIMIT_REACHED402Owned resource pool is full
RUNNING_POOL_REACHED402Running resource pool is full
VM_UNAVAILABLE503VM backend is unreachable
CREATE_FAILED500Workspace creation failed

List workspaces

Retrieve a paginated list of your workspaces.

const result = await ws.list({
  page: 1,
  limit: 20,
  mode: 'permanent',
});

console.log(result.workspaces); // WorkspaceResponse[]
console.log(result.total);     // Total count
GET /workspace?page=1&limit=20&mode=permanent
curl "https://api.oblien.com/workspace?page=1&limit=20" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Query parameters

ParameterTypeDefaultDescription
pagenumber1Page number
limitnumber20Results per page (max 100)
modestring-Filter by mode: "permanent" or "temporary"

Response

{
  "success": true,
  "workspaces": [ /* WorkspaceResponse[] */ ],
  "total": 42,
  "page": 1,
  "limit": 20
}

Get workspace

Get a single workspace by ID.

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

Response

{
  "success": true,
  "workspace": { /* WorkspaceResponse */ }
}

Get details

Aggregated workspace details - combines workspace info, live stats, SSH status, API access status, and lifecycle config in a single call.

const details = await ws.details('ws_a1b2c3d4');
// details.workspace includes: token, stats, ssh, api_access, lifecycle, config
GET /workspace/:workspaceId/details
curl "https://api.oblien.com/workspace/ws_a1b2c3d4/details" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Response

Returns the standard workspace object plus:

{
  "success": true,
  "workspace": {
    "...standard fields...",
    "token": "eyJhbG...",
    "stats": {
      "cpuUsage": 12.5,
      "memoryUsage": 45.2,
      "memoryUsedMB": 230,
      "memoryTotalMB": 512,
      "networkIn": "1.2 MB",
      "networkOut": "0.5 MB"
    },
    "ssh": {
      "ssh_enabled": true,
      "ssh_id": "abc123",
      "connection": { "command": "ssh root@abc123 -J root@ssh.oblien.com" }
    },
    "api_access": { "terminal": true, "preview": false },
    "lifecycle": {
      "mode": "permanent",
      "restart_policy": "always",
      "uptime": 3600
    },
    "config": { /* raw VM config */ }
  }
}

Update workspace

Update workspace name or config.

const updated = await ws.update('ws_a1b2c3d4', {
  name: 'renamed-workspace',
});
PUT /workspace/:workspaceId
{
  "name": "renamed-workspace"
}
curl -X PUT "https://api.oblien.com/workspace/ws_a1b2c3d4" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "name": "renamed-workspace" }'

Parameters

ParameterTypeDescription
namestringNew display name
configobjectUpdated config fields

Only name and config are updatable. Unknown fields are rejected.


Delete workspace

Permanently delete a workspace. The VM is destroyed and all data is removed.

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

Response

{
  "success": true,
  "message": "Workspace deleted"
}

This action is irreversible. All workspace data, snapshots, and logs are permanently deleted.


Get quota

Check your current resource quota based on your plan.

const quota = await ws.quota();
GET /workspace/quota
curl "https://api.oblien.com/workspace/quota" \
  -H "X-Client-ID: $OBLIEN_CLIENT_ID" \
  -H "X-Client-Secret: $OBLIEN_CLIENT_SECRET"

Response

{
  "success": true,
  "plan": "pro",
  "planLabel": "Pro",
  "limits": {
    "cpus": { "min": 1, "max": 8, "default": 1 },
    "memory_mb": { "min": 128, "max": 4096, "default": 512 },
    "writable_size_mb": { "min": 64, "max": 51200, "default": 512 }
  },
  "pool": { "cpus": 16, "memory_mb": 16384, "disk_mb": 51200 },
  "pool_usage": { "cpus": 4, "memory_mb": 4096, "disk_mb": 2048 },
  "running_pool": { "cpus": 8, "memory_mb": 8192, "disk_mb": 25600 },
  "running_pool_usage": { "cpus": 2, "memory_mb": 2048, "disk_mb": 1024 },
  "maxSandboxes": 10,
  "currentSandboxes": 3,
  "canCreate": true,
  "reason": null
}

See Resource Pools for how pool quotas work.


Workspace object

All workspace endpoints return this shape:

interface WorkspaceResponse {
  id: string;
  name: string;
  namespace: string;
  mode: 'permanent' | 'temporary';
  image: string;
  ip: string;
  uptime: number;
  start_time: string;
  info: {
    status: string;         // 'running' | 'stopped' | 'paused' | 'creating' | ...
    is_running: boolean;
    user_requested_stop: boolean;
  };
  access: {
    ssh_enabled: boolean;
  };
  network: {
    allow_internet: boolean;
    ingress_ports: number[];
    egress_ports: number[];
    egress: string[];
    public_access: boolean;
    ingress: string[];
  };
  public_ports: Array<{
    port: number;
    hash: string;
    label: string;
    url: string;
  }>;
  resources: {
    cpus: number;
    memory_mb: number;
    disk_size_mb: number;
  };
  created_at: string;
  updated_at: string;
}