Internal API

Files

The file system endpoints let you list, read, write, and delete files inside the workspace VM. All paths are absolute filesystem paths (e.g. /app/src/main.go).

Requires the internal server to be enabled. All requests require a valid token - see Connection & Auth.

List directory

List files and directories in a given path. Supports recursive traversal, content inclusion, hash computation, and filtering.

const result = await ws.files.list('ws_a1b2c3d4', {
  dirPath: '/app/src',
  nested: true,
  flatten: true,
  includeContent: true,
  codeFilesOnly: true,
  maxDepth: 5,
});

console.log(result.entries);       // fileEntry[]
console.log(result.count);         // number of entries
GET https://workspace.oblien.com/files?path=/app/src&nested=true&flatten=true&include_content=true&code_files_only=true&max_depth=5
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
curl "https://workspace.oblien.com/files?path=/app/src&nested=true&flatten=true&include_content=true&code_files_only=true&max_depth=5" \
  -H "Authorization: Bearer $GATEWAY_JWT"

Parameters

ParameterTypeRequiredDescription
pathstringNoDirectory path to list. Defaults to /
nestedbooleanNoRecurse into subdirectories. Default false
flattenbooleanNoReturn flat list instead of tree. Default false
lightbooleanNoOmit size and modified time for faster response. Default false
include_hashbooleanNoInclude SHA-256 hash for each file. Default false
include_contentbooleanNoInclude file content inline. Default false
include_extensionsbooleanNoInclude file extension field. Default false
code_files_onlybooleanNoOnly return code/config files. Default false
use_gitignorebooleanNoRespect .gitignore rules. Default true
max_depthintegerNoMaximum recursion depth. Default 20
path_filterstringNoCase-insensitive substring filter on path
include_extstringNoComma-separated extensions to include (e.g. js,ts,go)
ignore_patternsstringNoComma-separated glob patterns to ignore
max_content_budgetintegerNoMax total bytes for inline content. Default ~50 MiB

Response

{
  "success": true,
  "path": "/app/src",
  "entries": [
    {
      "name": "main.go",
      "path": "/app/src/main.go",
      "type": "file",
      "size": 1234,
      "modified": "2025-01-15T10:30:00Z",
      "extension": ".go",
      "content": "package main\n...",
      "hash": "a1b2c3..."
    },
    {
      "name": "utils",
      "path": "/app/src/utils",
      "type": "directory",
      "children": [...]
    }
  ],
  "count": 42
}

The list endpoint is capped at 50,000 entries. For large directories, use path_filter, include_ext, or code_files_only to narrow results, or use the stream endpoint for NDJSON streaming.


Stream directory

Stream directory entries as NDJSON (newline-delimited JSON). Ideal for large directories - entries flow to the client as they're discovered, without accumulating in memory.

const stream = ws.files.stream('ws_a1b2c3d4', {
  dirPath: '/app',
  includeContent: true,
  codeFilesOnly: true,
});

for await (const entry of stream) {
  console.log(entry.name, entry.path);
}
GET https://workspace.oblien.com/files/stream?path=/app&include_content=true&code_files_only=true
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Response: Content-Type: application/x-ndjson

curl -N "https://workspace.oblien.com/files/stream?path=/app&include_content=true&code_files_only=true" \
  -H "Authorization: Bearer $GATEWAY_JWT"

Parameters

Same as List directory. The nested and flatten options are always enabled for streaming.

Response format

Each line is a JSON object. The stream starts with a start event and ends with a done event:

{"event":"start","path":"/app"}
{"name":"main.go","path":"/app/main.go","type":"file","size":1234}
{"name":"utils.go","path":"/app/utils.go","type":"file","size":567}
{"event":"done","count":2}

The stream endpoint uses batched directory reads for memory efficiency. Entries are not sorted - they arrive in filesystem order. Use the list endpoint if you need sorted output.


Read file

Read the content of a file. Supports line ranges for partial reads.

const file = await ws.files.get('ws_a1b2c3d4', {
  filePath: '/app/src/main.go',
});

console.log(file.content);    // file content as string
console.log(file.lines);      // number of lines returned
console.log(file.size);       // file size in bytes

// Read specific line range
const partial = await ws.files.get('ws_a1b2c3d4', {
  filePath: '/app/src/main.go',
  startLine: 10,
  endLine: 25,
  withLineNumbers: true,
});
GET https://workspace.oblien.com/files/read?path=/app/src/main.go&start_line=10&end_line=25&with_line_numbers=true
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
curl "https://workspace.oblien.com/files/read?path=/app/src/main.go&start_line=10&end_line=25&with_line_numbers=true" \
  -H "Authorization: Bearer $GATEWAY_JWT"

Parameters

ParameterTypeRequiredDescription
pathstringYesAbsolute path to the file
start_lineintegerNoFirst line to read (1-based)
end_lineintegerNoLast line to read (1-based, inclusive)
with_line_numbersbooleanNoPrefix each line with its line number

Response

{
  "success": true,
  "path": "/app/src/main.go",
  "content": "package main\n\nfunc main() {\n\tfmt.Println(\"hello\")\n}",
  "size": 1234,
  "lines": 5,
  "extension": ".go",
  "start_line": 10,
  "end_line": 25
}

start_line and end_line are only included when a line range was requested.


Write file

Create or overwrite a file. Uses atomic write (temp file + rename) by default. Accepts both POST and PUT.

const result = await ws.files.create('ws_a1b2c3d4', {
  fullPath: '/app/src/hello.txt',
  content: 'Hello, world!',
  createDirs: true,
});

console.log(result.path);  // "/app/src/hello.txt"
console.log(result.size);  // 13

// Append to an existing file
await ws.files.create('ws_a1b2c3d4', {
  fullPath: '/app/logs/output.log',
  content: 'New log entry\n',
  append: true,
  createDirs: true,
});
POST https://workspace.oblien.com/files/write
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json

{
  "path": "/app/src/hello.txt",
  "content": "Hello, world!",
  "create_dirs": true
}
curl -X POST "https://workspace.oblien.com/files/write" \
  -H "Authorization: Bearer $GATEWAY_JWT" \
  -H "Content-Type: application/json" \
  -d '{"path":"/app/src/hello.txt","content":"Hello, world!","create_dirs":true}'

Parameters

ParameterTypeRequiredDescription
pathstringYesAbsolute path for the file
contentstringYesFile content
create_dirsbooleanNoCreate parent directories if they don't exist. Default false
appendbooleanNoAppend to existing file instead of overwriting. Default false
modestringNoFile permissions in octal (e.g. "0644"). Default "0644"

Response

{
  "success": true,
  "path": "/app/src/hello.txt",
  "size": 13
}

HTTP status: 201 Created


Create directory

Create a directory and any necessary parent directories.

await ws.files.mkdir('ws_a1b2c3d4', {
  path: '/app/src/utils/helpers',
});
POST https://workspace.oblien.com/files/mkdir
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json

{
  "path": "/app/src/utils/helpers"
}
curl -X POST "https://workspace.oblien.com/files/mkdir" \
  -H "Authorization: Bearer $GATEWAY_JWT" \
  -H "Content-Type: application/json" \
  -d '{"path":"/app/src/utils/helpers"}'

Parameters

ParameterTypeRequiredDescription
pathstringYesDirectory path to create
modestringNoDirectory permissions in octal (e.g. "0755"). Default "0755"

Response

{
  "success": true,
  "path": "/app/src/utils/helpers"
}

HTTP status: 201 Created


Stat

Get detailed information about a file or directory.

const info = await ws.files.stat('ws_a1b2c3d4', {
  path: '/app/src/main.go',
});

console.log(info.type);        // "file"
console.log(info.size);        // 1234
console.log(info.permissions); // "0644"
console.log(info.is_code);     // true
GET https://workspace.oblien.com/files/stat?path=/app/src/main.go
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
curl "https://workspace.oblien.com/files/stat?path=/app/src/main.go" \
  -H "Authorization: Bearer $GATEWAY_JWT"

Parameters

ParameterTypeRequiredDescription
pathstringYesPath to the file or directory

Response

{
  "success": true,
  "path": "/app/src/main.go",
  "name": "main.go",
  "type": "file",
  "size": 1234,
  "modified": "2025-01-15T10:30:00Z",
  "permissions": "0644",
  "is_code": true,
  "extension": ".go"
}

For symlinks:

{
  "success": true,
  "path": "/app/link",
  "name": "link",
  "type": "symlink",
  "size": 0,
  "modified": "2025-01-15T10:30:00Z",
  "permissions": "0777",
  "is_code": false,
  "symlink_target": "/app/src/main.go"
}

Delete

Delete a file or directory. Directories are removed recursively.

await ws.files.delete('ws_a1b2c3d4', {
  path: '/app/src/old-file.txt',
});
DELETE https://workspace.oblien.com/files/delete?path=/app/src/old-file.txt
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
curl -X DELETE "https://workspace.oblien.com/files/delete?path=/app/src/old-file.txt" \
  -H "Authorization: Bearer $GATEWAY_JWT"

Parameters

ParameterTypeRequiredDescription
pathstringYesPath to the file or directory to delete

The path can also be provided in the request body as {"path": "..."}.

Response

{
  "success": true,
  "path": "/app/src/old-file.txt"
}

System paths (/, /bin, /sbin, /usr, /lib, /lib64, /etc, /dev, /proc, /sys, /boot, /run) are protected and cannot be deleted.


Error responses

All file endpoints return errors in a consistent format:

{
  "error": "file not found: /app/missing.txt"
}
StatusMeaning
400Invalid parameters (missing path, path is a directory when file expected, etc.)
401Missing or invalid token
403Attempted to delete a protected system path
404File or directory not found
413File too large to read or content too large to write
500Internal server error