Skip to content

The Reading Files API provides two endpoints for listing directory contents and downloading files. The WebDAV-style /{path} endpoint returns HTML by default and integrates with the Web UI, while /api/v1/files/{path} returns JSON and supports advanced features like grep, glob, and zip downloads.

Returns a directory listing in HTML or JSON format, or downloads a file. For file paths, append ?download (or ?download=true) to force a Content-Disposition: attachment response. Supports revision history via ?history, point-in-time reads via ?at or ?revision, and unified diffs via ?diff.

NameInTypeRequiredDescription
pathpathstringYesFile or directory path
jsonquerystringNoReturn JSON format instead of HTML
simplequerystringNoReturn simple text listing
sortquerystringNoSort by field. Accepted values: name, mtime, size
orderquerystringNoSort order. Accepted values: asc, desc
hashquerystringNoGet SHA256 hash of file (returns plain text hash)
sha256querystringNoGet SHA256 hash of file (alias for hash)
base64querystringNoGet file content as base64 encoded string
editquerystringNoOpen file in Web UI editor (requires allow-upload permission)
viewquerystringNoView file in Web UI (read-only mode)
downloadquerystringNoFor file paths only: force browser download (Content-Disposition: attachment). Accepted values: empty, 1, or true. For directory paths, ?download triggers the URL download-manager operation.
content-typequerystringNoOverride Content-Type header for file downloads
historyquerystringNoList all revisions of a file. Returns JSON with revisions array, pagination via after_id. Mutually exclusive with at/revision/diff.
atquerystringNoRead file content at a point in time. Accepts RFC3339 timestamp or Unix milliseconds. Mutually exclusive with history/revision/diff. Composable with ?lines, ?hash, ?base64.
revisionqueryintegerNoRead file content by stable per-path sequence number. Mutually exclusive with history/at/diff. Composable with ?lines, ?hash, ?base64.
diffquerystringNoCompute unified diff between two versions. Requires from_seq or from_ts. Optional to_seq or to_ts (defaults to current file). Mutually exclusive with history/at/revision.
from_seqqueryintegerNoSource revision seq number for ?diff. Mutually exclusive with from_ts.
from_tsquerystringNoSource timestamp for ?diff (RFC3339 or Unix ms). Mutually exclusive with from_seq.
to_seqqueryintegerNoTarget revision seq number for ?diff. Mutually exclusive with to_ts. Default: current file on disk.
to_tsquerystringNoTarget timestamp for ?diff (RFC3339 or Unix ms). Mutually exclusive with to_seq.
after_idqueryintegerNoCursor for ?history pagination. Returns entries with id > after_id.
limitqueryintegerNoMax entries to return for ?history. Default: 100.
{
"allow_archive": true,
"allow_delete": true,
"allow_search": true,
"allow_upload": true,
"auth": true,
"dir_exists": true,
"href": "/projects/web-app",
"kind": "Index",
"paths": [
{
"mtime": 1706000000000,
"name": "src",
"path_type": "Dir",
"revisions": null,
"size": 42
},
{
"mtime": 1706100000000,
"name": "README.md",
"path_type": "File",
"revisions": 7,
"size": 2048
}
],
"uri_prefix": "/api/v1/files/",
"user": "alice"
}
// List a directory in JSON format
await client.files.listDirectory({
path: "/projects/web-app",
json: ""
});
// Get the SHA256 hash of a file
await client.files.listDirectory({
path: "/projects/web-app/README.md",
hash: ""
});
// Force a browser download
await client.files.listDirectory({
path: "/projects/web-app/README.md",
download: "1"
});
// Read a file at a specific point in time
await client.files.listDirectory({
path: "/projects/web-app/README.md",
at: "2024-01-15T10:30:00Z"
});
// Compute a unified diff between two revisions
await client.files.listDirectory({
path: "/projects/web-app/README.md",
diff: "",
from_seq: 3,
to_seq: 5
});

Returns a directory listing, file content, search results, or a streaming archive. This endpoint exposes the full feature set including ?grep, ?glob, ?lines, and ?zip. Append ?zip to download an entire directory as a streaming zip archive (requires --allow-archive).

NameInTypeRequiredDescription
pathpathstringYesFile or directory path
backendquerystringNoBackend ID for remote file access
hashquerystringNoGet SHA256 hash of file
sha256querystringNoGet SHA256 hash of file (alias for hash)
base64querystringNoGet file content as base64
previewquerystringNoPreview archive contents (for zip/tar files). Alias: ?contents
contentsquerystringNoAlias for ?preview - list archive contents
statquerystringNoGet file/directory metadata (stat) without downloading content
thumbnailquerystringNoGenerate thumbnail (not yet implemented in API v1, returns 501)
grepquerystringNoSearch file/directory contents for regex pattern (or literal if fixed_string=true). Requires --allow-grep.
ignore_casequerybooleanNoCase-insensitive grep matching. Default: false
fixed_stringquerybooleanNoTreat grep pattern as literal string, not regex. Default: false
globquerystringNoFind files matching glob pattern (e.g. **/*.rs, src/**/*.{ts,tsx}). Requires --allow-search. Directory paths only.
contextqueryintegerNoNumber of context lines before/after each grep match. Default: 0
max_countqueryintegerNoMax matches per file for grep. Default: 50
max_matchesqueryintegerNoTotal max matches across all files for grep. Default: 500
max_depthqueryintegerNoDirectory recursion depth for grep. Default: 50
max_filesizequeryintegerNoSkip files larger than this (bytes) during grep. Default: 10485760
timeoutqueryintegerNoGrep timeout in seconds. Default: 30
no_ignorequerybooleanNoBypass .gitignore filtering during grep. Default: false
max_resultsqueryintegerNoMax entries returned for glob search. Default: 1000
max_files_scannedqueryintegerNoMax filesystem entries scanned during glob search. Default: 100000
sortquerystringNoSort glob results by mtime (default), name, or size. Default: "mtime".
orderquerystringNoSort order for glob results. Default: desc for mtime, asc for name/size. Accepted values: asc, desc.
linesquerystringNoExtract specific lines from a file. Formats: 10-50 (range, 1-indexed inclusive), 100 (single line), -20 (last 20 lines / tail), 50- (line 50 to end). Returns text/plain with X-Line-Range header. X-Total-Lines header included when naturally known (scan reached EOF). Max 100,000 lines or 64MB per request.
historyquerystringNoList all revisions of a file. Returns JSON with revisions array, pagination via after_id. Mutually exclusive with at/revision/diff.
atquerystringNoRead file content at a point in time. Accepts RFC3339 timestamp or Unix milliseconds. Mutually exclusive with history/revision/diff. Composable with ?lines, ?hash, ?base64.
revisionqueryintegerNoRead file content by stable per-path sequence number. Mutually exclusive with history/at/diff. Composable with ?lines, ?hash, ?base64.
diffquerystringNoCompute unified diff between two versions. Requires from_seq or from_ts. Optional to_seq or to_ts (defaults to current file). Mutually exclusive with history/at/revision.
from_seqqueryintegerNoSource revision seq number for ?diff. Mutually exclusive with from_ts.
from_tsquerystringNoSource timestamp for ?diff (RFC3339 or Unix ms). Mutually exclusive with from_seq.
to_seqqueryintegerNoTarget revision seq number for ?diff. Mutually exclusive with to_ts. Default: current file on disk.
to_tsquerystringNoTarget timestamp for ?diff (RFC3339 or Unix ms). Mutually exclusive with to_seq.
after_idqueryintegerNoCursor for ?history pagination. Returns entries with id > after_id.
limitqueryintegerNoMax entries to return for ?history. Default: 100.
zipquerystringNoDownload a directory as a streaming zip archive (bare flag, e.g. ?zip). Local directories only; requires --allow-archive. Same behavior as the WebDAV-style /{directory}?zip.

For directory listings, file content, grep results, glob results, or line-range content depending on the query string. The response body is application/json for listings/searches, application/octet-stream for raw files, or application/zip for ?zip downloads.

{
"allow_archive": true,
"allow_delete": true,
"allow_search": true,
"allow_upload": true,
"auth": true,
"dir_exists": true,
"href": "/projects/web-app",
"kind": "Index",
"paths": [
{
"mtime": 1706000000000,
"name": "src",
"path_type": "Dir",
"revisions": null,
"size": 42
},
{
"mtime": 1706100000000,
"name": "README.md",
"path_type": "File",
"revisions": 7,
"size": 2048
}
],
"uri_prefix": "/api/v1/files/",
"user": "alice"
}

For a ?grep query, the response matches files_GrepResults:

{
"duration_ms": 42,
"matches": [
{
"column_byte": 12,
"context_after": [],
"context_before": [],
"line": "function handleAuth(token: string) {",
"line_number": 38,
"path": "/projects/web-app/src/auth.ts"
}
],
"path": "/projects/web-app",
"pattern": "handleAuth",
"total_files_matched": 1,
"total_files_searched": 18,
"total_matches": 1,
"truncated": false
}
// List a directory in JSON format
await client.files.get({
path: "/projects/web-app"
});
// Search file contents with grep
await client.files.get({
path: "/projects/web-app/src",
grep: "handleAuth",
ignore_case: true,
context: 2
});
// Find files matching a glob
await client.files.get({
path: "/projects/web-app",
glob: "**/*.rs"
});
// Extract a specific line range
await client.files.get({
path: "/projects/web-app/src/auth.ts",
lines: "10-50"
});
// Get SHA256 hash of a file via remote backend
await client.files.get({
path: "/projects/web-app/README.md",
backend: "s3-primary",
hash: ""
});
// Download a directory as a streaming zip
await client.files.get({
path: "/projects/web-app",
zip: ""
});