Branches and file history
Files and directories have stable object_id values. An edit creates a file state; a rename preserves the object’s identity and history. A workspace commit records a consistent filesystem view. User KV stays disk-wide and is excluded from commits.
Select a view
Section titled “Select a view”Files, entries, stat, mkdir, move, history, restore and exec accept one optional query selector:
| Selector | Behavior |
|---|---|
| Omitted | Live main. |
branch=NAME |
Independently writable branch. |
commit=UUID |
Read-only committed filesystem. |
label=NAME |
Read-only commit or directory pin; a pinned directory appears at /. |
Supplying several selectors returns 400. A write to a historical view returns 403. JS, nested bash() and qjs share the selected view. Read a file pin with GET /label-content?name=NAME.
Endpoints
Section titled “Endpoints”All route suffixes below start at /v1/disks/{disk}/.
| Method | Suffix | Input and result |
|---|---|---|
| GET | stat?path=/log.txt |
Current metadata, including object/version IDs, revision and edit timestamps. |
| POST | mkdir?path=/notes&recursive=true |
Create a directory; 204. |
| POST | move |
JSON {"from":"/a","to":"/b"}; exact destination; 204. |
| GET / POST | branches |
NDJSON list / JSON {"name":"work","from":"COMMIT_UUID"}. |
| DELETE | branches?name=work |
Remove a nondefault branch; 204. |
| GET / POST | commits |
NDJSON list / JSON {"message":"daily","label":"daily"}; POST accepts branch. |
| DELETE | commits/UUID |
Remove an unreferenced commit; 204. |
| GET | history?path=/log.txt |
Newest-first NDJSON {metadata, sealed} including inherited base history. |
| GET | versions/UUID |
Exact sealed file bytes. |
| POST | restore |
JSON {"path":"/log.txt","version":"VERSION_UUID"}; publish a new file state. |
| GET / PUT | labels |
NDJSON list / JSON {"name":"keep","path":"/log.txt"} or {"name":"keep","commit":"COMMIT_UUID"}. |
| DELETE | labels?name=keep |
Remove a pin; 204. |
| GET | label-content?name=keep |
Pinned file bytes. |
Branch and label names contain 1 to 255 bytes without control characters. Names use query/JSON values, so normal URL encoding applies. Deleting a commit used as a branch head, base, parent or label returns 409. File/directory pins and commits remain until explicitly deleted. Move replaces a file or empty directory of the same kind; moving a directory into itself or beyond the path limit fails before publication.
Create a branch
Section titled “Create a branch”curl --fail-with-body -X POST "https://api.wabe.sh/v1/disks/demo/commits" \ -H "Authorization: Bearer YOUR_PROJECT_API_KEY" \ -H 'Content-Type: application/json' \ --data '{"message":"before edits","label":"before"}'The response includes id, branch_id, revision, root_directory_id, parent/base commit IDs, created_at_ms and message. Pass its id as from to POST /branches, then add ?branch=work to file or execution requests. A commit seals that branch’s drafts; other branches continue independently.
Autosave and retention
Section titled “Autosave and retention”New disks use autosave_interval_ms: 0, recording every completed edit. Set a nonzero interval through storage configuration to group rapid edits into one mutable draft. The window starts with its first edit, rather than restarting after every edit. At 10,000 ms, an edit after the window seals the prior version and creates a new draft. There is no timer-created version for an idle file.
Drafts keep the same version_id while their revision and last_edit_at_ms change. Commits, pins and eviction seal them. A sealed version is immutable; subsequent edits create another history point. Restoring file content creates a new state and reuses its immutable content.
history_retention_ms: null preserves all intermediate history. A duration trims old intermediate versions during GC; zero preserves only states needed by live branches, commits, labels and retained notification captures. A commit’s content remains readable after intermediate file history is trimmed.
PUT and append accept expected_id=VERSION_UUID&expected_revision=N together. A stale precondition returns 409. Restore accepts the equivalent optional JSON expected_version: {id, revision}. Retrying an append can duplicate bytes; a missing response after publication leaves an uncertain acknowledgement outcome.
Errors
Section titled “Errors”400 for invalid selectors, paths, names or types; 401 for authentication; 403 for historical writes; 404 for missing state; 409 for stale versions, conflicts or referenced objects; 500 for storage/corruption failures. Stream failures after HTTP headers terminate the body.