AgentFS

Files

Find files by path, tag, or run, read them back, update them in place, and delete them.

Use a bearer API key for the file API. A path starts with a project name and ends with a filename, for example research/notes/summary.md. Paths in JSON responses do not start with /.

Paths and projects

Use letters, numbers, ., _, and - in each path segment. A path can contain at most 16 segments and 2,048 encoded characters. The first segment addresses the project; the remaining segments address folders and the file.

A project name starts with a letter or number and is at most 100 characters. Project names are case-insensitive. A file ID starts with f_ and is stable after a rename, so use the ID for API operations and the returned URL for downloads.

List and find files

Call GET /v1/files. Pass a project name or project ID in project, and an optional case-insensitive search in q:

curl -sS "https://agentfs.cloud/v1/files?project=research&q=summary&limit=50" \
  -H "Authorization: Bearer $AGENTFS_KEY"

limit defaults to 50 and accepts 1–200. Use the opaque next_cursor value as the cursor query parameter for the next page.

These filters combine, and all of them narrow within what the key is allowed to read:

FilterMatches
projectOne project, by name or ID.
pathOne exact path, for an agent that remembers where it wrote.
prefixA path prefix such as research/2026, and everything below it.
qText in the file name or path. search is the same filter under its older name.
run_id / agent_idFiles written by requests that sent that X-Run-ID or X-Agent-ID.
statusready (the default), uploading, failed, or trashed, as a comma list.
everything one run wrote
curl -sS -G https://agentfs.cloud/v1/files \
  -H "Authorization: Bearer $AGENTFS_KEY" \
  --data-urlencode "run_id=run-2026-04-01"

The response includes project and project_id on every item:

{
  "items": [
    {
      "type": "file",
      "id": "f_8f2c",
      "name": "summary.md",
      "path": "research/notes/summary.md",
      "label": null,
      "content_type": "text/markdown",
      "content_disposition": "inline",
      "size_bytes": 8192,
      "sha256": "0000000000000000000000000000000000000000000000000000000000000000",
      "etag": "\"demo-etag\"",
      "revision": 1,
      "visibility": "unlisted",
      "expires_at": null,
      "agent_id": "research-agent",
      "run_id": "run-2026-04-01",
      "url": "https://f.agentfsusercontent.com/f/f_8f2c",
      "markdown": "[summary.md](https://f.agentfsusercontent.com/f/f_8f2c)",
      "created_at": "2026-04-01T12:00:00.000Z",
      "updated_at": "2026-04-01T12:00:00.000Z",
      "project": "research",
      "project_id": "p_a13b",
      "status": "ready"
    }
  ],
  "next_cursor": null
}

Get a file

Use the file ID to get one file object:

curl -sS https://agentfs.cloud/v1/files/f_8f2c \
  -H "Authorization: Bearer $AGENTFS_KEY"

A private file has url: null and markdown: null. Create a signed URL as described in Sharing.

Update a file you wrote before

Send the same path again with if_exists=replace. One call, no lookup:

curl -sS -X POST https://agentfs.cloud/v1/files \
  -H "Authorization: Bearer $AGENTFS_KEY" \
  -F "file=@./summary.md" \
  -F "path=research/notes/summary.md" \
  -F "if_exists=replace"

The file keeps its ID, path, and hosted URL, so anything you already shared keeps working. revision goes up by one and the response is 200 instead of 201. Only the bytes and content type change; visibility, label, and expiry stay as they were.

Writing the same bytes again is a no-op that returns the current file, so a retry is safe. To make the write conditional on the version you last read, add -H "If-Match: <etag>"; a file that changed first returns 412 precondition_failed.

Without if_exists, a path already in use returns 409 path_exists.

Rename a file

The file rename endpoint uses the signed-in dashboard session, not a bearer API key:

PATCH /v1/dashboard/files/f_8f2c
Content-Type: application/json

{"name":"final-summary.md"}

The name must be 1–255 characters, start with a letter or number, and then contain only letters, numbers, ., _, and -. This changes only the final path segment in the same folder. It does not move the file or replace its bytes. The file ID and hosted URL stay the same. A name already used in that folder returns 409 path_exists.

With a bearer key, use PATCH /v1/files/:id with a full path to rename or move a file inside its project. Send If-Match: <etag> to make the move conditional; a file that changed first returns 409 precondition_failed.

Delete a file

Delete by ID with a bearer key:

curl -sS -X DELETE https://agentfs.cloud/v1/files/f_8f2c \
  -H "Authorization: Bearer $AGENTFS_KEY"

A successful delete returns 204 with no body. A later get or download returns not found.

The file sits in the trash for 30 days before it is purged. It still counts toward your storage while it is there. Add ?permanent=true to remove it for good and free the space now.

Restore a deleted file

While a file is in the trash, you can bring it back. List the trash with status=trashed, then restore by ID:

curl -sS "https://agentfs.cloud/v1/files?status=trashed" \
  -H "Authorization: Bearer $AGENTFS_KEY"

curl -sS -X POST https://agentfs.cloud/v1/files/f_8f2c/restore \
  -H "Authorization: Bearer $AGENTFS_KEY"

The file comes back at the same path, with the same ID and hosted URL, and the response is the file object. Restoring a file that is already live returns it again. If another file now holds the path, the response is 409 path_exists. A purged or permanently deleted file returns 404 file_not_found.

On this page