The file API provides authenticated access to every app-layer file through a consistent set of logical path operations. All endpoints delegate toDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/agent0ai/space-agent/llms.txt
Use this file to discover all available pages before exploring further.
server/lib/customware/file_access.js for permission checks, quota enforcement, and layer inheritance — endpoint handlers stay intentionally thin. Every mutating endpoint validates all targets before any write begins, and in clustered mode each worker commits changed logical paths back to the primary before the response finishes.
Path Conventions
The file API accepts logical app paths rather than raw disk paths. The server resolves these at request time regardless of whereCUSTOMWARE_PATH has relocated writable storage.
| Path form | Resolves to |
|---|---|
~/note.txt | Authenticated user’s L2/<username>/note.txt |
~/folder/ | Trailing slash identifies a directory |
L2/alice/note.txt | Explicit user layer path |
L1/team/shared.md | Group layer path |
L0/app/config.yaml | Base firmware layer path |
/app/L2/alice/note.txt | Absolute logical path form |
.git metadata paths are reserved. The API blocks direct reads, writes, fetches, and path-index entries for .git/ subtrees in every owner root.GET or POST /api/file_read
Reads one file or a batch of files from the app layer. Returns base64-encoded content by default for binary files; useencoding: "utf8" for text. The frontend client coalesces same-tick reads into a single backend request and retries entries individually on failure. Accepts both GET (with query params) and POST (with a JSON body).
Request — single file
Logical app path to the file, e.g.
~/notes.md or L1/team/config.yaml."utf8" or "base64". Applied to the returned content.Request — batch read
Array of file descriptors. When present, single-file fields are ignored.
Response
Array of read results.
POST /api/file_write
Writes content to a file. Defaults to full replacement but supports incremental mutations via theoperation field. Batch writes are supported via the files array. When USER_FOLDER_SIZE_LIMIT_BYTES is set, quota is checked before any write.
Request — single write
Logical app path to the destination file.
Content to write. Text or base64 string depending on
encoding."utf8" or "base64".Mutation mode. One of
"replace", "append", "prepend", or "insert". Insert mode requires exactly one of line, before, or after.1-based line number for
insert operations. 1 inserts at the top; one past the last line appends at the end.Literal string anchor for
insert; content is inserted before the first match.Literal string anchor for
insert; content is inserted after the first match.Request — batch write
Array of write descriptors. Top-level
operation, line, before, and after act as defaults for each entry.Response
Resolved logical path of the written file.
Always
"written".GET or POST /api/file_list
Lists the contents of a directory. Accepts optional access filters for permission-aware discovery. PassgitRepositories: true with access: "write" to discover writable owner roots eligible for Git history operations. Accepts both GET (with query params) and POST (with a JSON body).
Request
Logical directory path to list. Use a trailing
/ for directories.Recursively list all nested entries.
"write" limits results to paths the authenticated user can write.Equivalent shorthand for
access: "write".When
true, returns writable layer owner roots (e.g. L2/alice/) rather than exposing .git metadata paths.Response
Resolved directory path.
Directory entries.
POST or DELETE /api/file_delete
Deletes a single file or folder, or a batch of paths. All targets are validated before any deletion begins. Quota metrics are updated after the delete. Accepts bothPOST (with a JSON body) and DELETE.
Request — single delete
Logical path to delete.
Request — batch delete
Array of logical path strings. When present,
path is ignored.Response
The deleted path.
Always
"deleted".POST /api/file_move
Moves or renames a file or folder. Supports a batch form viaentries. All source and destination paths are validated before any move begins.
Request — single move
Source logical path.
Destination logical path.
Request — batch move
Array of move pairs. When present, top-level
fromPath/toPath are ignored.Response
Original path.
New path.
Always
"moved".POST /api/file_copy
Copies a file or folder. Supports a batch form viaentries. When USER_FOLDER_SIZE_LIMIT_BYTES is set, the projected size growth is quota-checked before the copy.
Request — single copy
Source logical path.
Destination logical path.
Request — batch copy
Array of copy pairs.
Response
Source path.
Destination path.
Always
"copied".GET or POST /api/file_info
Returns metadata for a single logical path without reading file content. Useful for checking whether a path exists, its type, and layer ownership before a read or write. Accepts bothGET (with query params) and POST (with a JSON body).
Request
Logical path to inspect.
Response
Resolved logical path.
Whether the path exists.
"file" or "directory" if it exists.Whether the current user can read the path.
Whether the current user can write the path.
File size in bytes (files only).
GET or POST /api/file_paths
Resolves one or more glob patterns against the indexed file tree. This is the recommended endpoint for catalog and panel discovery; it reads from sharedfile_index shards rather than walking the filesystem. Supports the same access filters as file_list. Accepts both GET (with query params) and POST (with a JSON body).
Request
Array of glob pattern strings to match, e.g.
["mod/*/*/ext/panels/*.yaml"]."write" to return only writable matches.Shorthand for
access: "write".Return writable layer owner roots when combined with a
**/.git/ pattern.Cap resolution to a specific layer:
0 = L0 only, 1 = L0 + L1. Omit to include all readable layers.Response
One result group per input pattern.
GET /api/folder_download
Downloads a readable folder as a streaming ZIP attachment. The server creates the archive inserver/tmp/ using the Node ZIP helper and streams it without buffering the archive in memory.
Query Parameters
Logical path to the folder to download, e.g.
~/projects/.Response
Returns a binaryapplication/zip response with:
Content-Disposition: attachment; filename="<folder-name>.zip"Content-Lengthset to the archive file sizeContent-Type: application/zipCache-Control: no-store