How to move files in and out of an AI agent's computer on Orgo
Upload inputs, drop a file in one exact folder, send large files in two steps, and export what the agent made.
TL;DR: POST /files/upload sends a file of up to 10 MB to every running computer in a workspace, or to one folder on one computer. POST /files/uploads plus POST /files/uploads/complete sends a larger file to one computer. POST /files/export copies a file off a computer and returns a one-hour download link. Large transfers are capped at 2 GB, and the computer's copy must finish within 90 seconds, so big files need a fast link.
An AI agent that works on a real computer usually needs two things from you: input files to work on, and a way to hand back what it made. On Orgo, the Files API covers both.
All of it uses the same API key and base URL as the rest of the API, https://www.orgo.ai/api.
What is the Orgo Files API?
The Files API moves files between your code and the computers your agents use. It has two kinds of operations:
- Into a computer. Upload a file to a workspace and have it pushed to running computers, or place it in a folder you choose on one computer.
- Out of a computer. Export a file from a running computer into workspace storage, then fetch it from a signed link.
Files that pass through workspace storage get a record you can list, download again, and delete. Files placed straight into a folder do not.
Which way of moving a file should I use?
| You want to | Endpoint | Size limit | Where the file lands | Stored in the workspace? |
|---|---|---|---|---|
| Give a small file to every running computer | POST /files/upload | 10 MB | The desktop folder of each running computer | Yes, with source upload |
| Put a small file in one folder on one computer | POST /files/upload with destPath | 10 MB | The folder you name, on one computer | No |
| Send a large file to one computer | POST /files/uploads, then POST /files/uploads/complete | 2 GB, copied within 90 s | The folder you name, on one computer | No |
| Get a file the agent made | POST /files/export | 2 GB, copied within 90 s | Workspace storage, plus a one-hour link | Yes, with source export |
The rest of this post walks through each one, with the details from the Files API reference.
How do I upload a file to every computer in a workspace?
Send a multipart/form-data request to POST /files/upload with the file and a workspaceId. You can also send a desktopId to associate the file with one computer, but that does not change where it goes (Upload file).
curl -X POST https://www.orgo.ai/api/files/upload \
-H "Authorization: Bearer $ORGO_API_KEY" \
-F "file=@./document.pdf" \
-F "workspaceId=$WORKSPACE_ID"What happens next:
- The file is stored in the workspace and pushed to the desktop folder of every Linux or Windows computer running at that moment. On Linux, that is
/root/Desktop. - Computers that are stopped, or created afterwards, do not receive it. Upload again to reach them.
- The push runs in the background and is best-effort, so the response does not tell you whether each computer got the file.
- Each push sends the workspace's full set of uploaded files. A computer skips any file whose name already exists in its desktop folder instead of overwriting it.
The response is the stored record under file, including the id you pass to the download and delete endpoints. size_bytes is a decimal string, such as "102400", so parse it before doing arithmetic.
How do I put a file in one exact folder on one computer?
Add destPath and desktopId to the same upload request. The file lands at <destPath>/<file name> on that one computer, and nothing else receives it.
curl -X POST https://www.orgo.ai/api/files/upload \
-H "Authorization: Bearer $ORGO_API_KEY" \
-F "file=@./document.pdf" \
-F "workspaceId=$WORKSPACE_ID" \
-F "desktopId=$COMPUTER_ID" \
-F "destPath=/root/Documents"The response is {"ok": true, "placedIn": "/root/Documents"}.
destPathmust be an absolute folder, such as/root/Documentsor, on Windows,C:\Users\Public. The literal valuedesktopmeans the desktop folder of the computer's user.- A folder that does not exist is created, on Linux and on Windows. A file of the same name is replaced.
- No file record is created. The file does not show up in the list endpoint, and you cannot download or delete it through the API.
- If the computer does not confirm it wrote the file, or the request runs past 130 seconds, you get
502. If the computer can't be addressed, you get503with "Computer could not be reached." AdesktopIdthat is not inworkspaceIdalso gets this503, not a404, so check the pair first. - A computer locked for capacity takes no file and returns
402COMPUTER_LOCKED.
This is the mode to use when an agent expects its input in a specific place, for example a folder its script watches.
How do I upload a file larger than 10 MB?
Use the two-step upload. Its size limit is 2 GB. The bytes go straight to storage and never pass through Orgo's API (Start large upload, Complete large upload).
- Start.
POST /files/uploadswithdesktopId,filename, andsize_bytes, plus an optionaldestPath. WithoutdestPath, the file lands on the computer's desktop. You get back anupload_urland anupload_token. - PUT the bytes to
upload_url. Send exactlysize_bytesbytes. The URL is valid for 15 minutes. - Complete.
POST /files/uploads/completewith the samedesktopIdand theupload_token. The computer pulls the file into place.
SIZE=$(wc -c < ./dataset.zip | tr -d ' ')
START=$(curl -s -X POST https://www.orgo.ai/api/files/uploads \
-H "Authorization: Bearer $ORGO_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"desktopId\": \"$COMPUTER_ID\", \"filename\": \"dataset.zip\", \"size_bytes\": $SIZE, \"destPath\": \"/root/Documents\"}")
curl -T ./dataset.zip "$(echo "$START" | jq -r .upload_url)"
curl -X POST https://www.orgo.ai/api/files/uploads/complete \
-H "Authorization: Bearer $ORGO_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"desktopId\": \"$COMPUTER_ID\", \"upload_token\": \"$(echo "$START" | jq -r .upload_token)\"}"Things to know:
filenameis a plain name only: no/or\, not.or.., and at most 255 characters.- The computer does not need to be running when you start, but it must be running when you complete. Otherwise you get
400with "Desktop is not running. Start it, then finish the upload." - Complete replaces a file of the same name in the destination folder. A destination folder that does not exist is created, on Linux and on Windows.
- The computer pulls the file from storage with a 90 second limit. If the copy doesn't finish in time, complete returns
502"Could not place ...". 2 GB in 90 seconds needs about 24 MB/s, so a file near the limit only works over a fast link. - Start returns
upload_url,upload_token,method(PUT),expires_in(900), andnext. Complete returnsok,filename,placedIn, andsize_bytes. - The
upload_tokenis valid for one hour, and only for the same caller and computer. If placing the file fails, the stored copy is kept, so you can call complete again with the same token. - Like a folder-targeted upload, the file lands on one computer and no file record is written.
How do I get a file the agent made off the computer?
Call POST /files/export with the desktopId and the absolute path of the file. The computer sends the file straight to storage, with a 2 GB size limit (Export file).
curl -X POST https://www.orgo.ai/api/files/export \
-H "Authorization: Bearer $ORGO_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"desktopId\": \"$COMPUTER_ID\", \"path\": \"/root/Desktop/results.txt\"}"The response has the stored file record and a signed url that expires after one hour. The export is also recorded in the workspace with source set to export, so you can list it and get a fresh link later.
- The computer must be running. A stopped one returns
400with "Desktop is not running". pathmust point to a regular file. A folder returns404with "No file at ...", so archive a folder into one file first, for example withtarthrough the bash endpoint.- A file over 2 GB returns
413. Split or compress it first. - The computer's copy to storage must finish within 90 seconds, or you get
502"Could not copy ...". Large files need a fast link, so compress them first when you can. - The path has to match the computer's OS. A Linux path on a Windows computer, or the reverse, returns
400.
What does a full round trip look like in code?
This Python sample places an input file in a folder on the agent's computer, then exports the agent's output and saves it locally. It follows the upload and export examples in the docs.
import os
import requests
API = "https://www.orgo.ai/api"
headers = {"Authorization": f"Bearer {os.environ['ORGO_API_KEY']}"}
workspace_id = os.environ["WORKSPACE_ID"]
computer_id = os.environ["COMPUTER_ID"]
# 1. Put the input in one folder on the agent's computer
with open("leads.csv", "rb") as f:
placed = requests.post(
f"{API}/files/upload",
headers=headers,
files={"file": f},
data={
"workspaceId": workspace_id,
"desktopId": computer_id,
"destPath": "/root/Documents",
},
)
placed.raise_for_status()
print(placed.json()["placedIn"])
# 2. Your agent works on /root/Documents/leads.csv and writes report.csv
# 3. Copy the result off the computer and save it
export = requests.post(
f"{API}/files/export",
headers=headers,
json={"desktopId": computer_id, "path": "/root/Documents/report.csv"},
)
export.raise_for_status()
body = export.json()
with open("report.csv", "wb") as out:
out.write(requests.get(body["url"]).content)
print("Stored file id:", body["file"].get("id"))If the export record could not be saved, the response still carries a working url, but file has only filename, size_bytes, content_type, and source. That is why the sample reads id with .get().
How do I list, download again, and delete stored files?
Files with a record, from a workspace upload or an export, can be managed later:
- List:
GET /files?workspaceId=...returns the workspace's files, newest first. AdddesktopIdto filter to one computer. Each entry hassource, eitheruploadorexport(List files). - Download:
GET /files/download?id=...returns a signed URL, not the bytes. The URL works in any HTTP client without an auth header, carries the original file name, and expires one hour after it is issued. Request a new one instead of storing it (Download file). - Delete:
DELETE /files/delete?id=...permanently removes the file from storage and the workspace. Links issued before the delete stop working. A copy already pushed to a computer's desktop stays on that computer (Delete file).
Which errors should my code handle?
| Status | Message or code | What it means | What to do |
|---|---|---|---|
400 | "File too large (max 10MB)" | A single-step upload was over 10 MB | Use the two-step upload |
400 | "destPath requires desktopId" | You named a folder but not a computer | Add desktopId |
400 | "Desktop is not running" | Export or complete needs a running computer | Start the computer, then retry |
400 | "This upload expired." or "Invalid upload token." | The upload_token is over an hour old or not valid | Start the upload again |
404 | "No file at ..." | The export path is missing or is a folder | Check the path, or archive the folder first |
409 | "Upload is ... bytes, expected ..." | The bytes you PUT don't match size_bytes | Start the upload again with the right size |
409 | "Nothing uploaded yet. PUT the file to upload_url first." | Complete ran before the PUT | PUT the bytes, then complete |
409 | "A folder named ... already exists in ..." | The destination has a folder with that name | Start again with another file name |
413 | "File is ... bytes; the limit is 2147483648" | The file is over 2 GB | Split or compress it |
402 | COMPUTER_LOCKED | The computer is locked for capacity | Free capacity, then retry |
403 | workspace_read_only | The key belongs to a Can chat member | Ask the owner for Full access |
403 | workspace_scope_mismatch | A workspace-scoped key named another workspace | Use a key scoped to the right workspace |
502 | "Could not place ..." or "Could not copy ..." | The computer didn't finish in time (90 s for large transfers) | Retry on a faster link, or compress. A large upload keeps its stored copy, so reuse the token |
503 | "Computer not ready" or "Computer could not be reached." | Orgo can't address the computer | Retry shortly |
Members with Can chat access can't upload, export, or delete files through the API. Export, the two-step upload, and delete return 403 with workspace_read_only. A single-step POST /files/upload returns 403 with "Access denied".
Can an MCP client or the Orgo CLI move files?
Yes, with a few differences from the REST API:
- CLI.
orgo fileshaslist,upload,download,export, anddelete. Upload caps at 10 MB, and there is no two-step upload command. For larger files, use the REST or MCP start and complete flow, or pull the data in from inside the computer (CLI guide). - Local MCP server. The Files tools are
orgo_upload_file,orgo_start_file_upload,orgo_complete_file_upload,orgo_list_files,orgo_export_file,orgo_download_file, andorgo_delete_file(MCP guide). - Hosted MCP server. A sign-in with OAuth can list, export, download, and delete files, and can do the two-step upload with
orgo_start_file_uploadandorgo_complete_file_upload.orgo_upload_fileis not offered over the hosted URL, because it reads the file from the machine running the server. With an API key it is refused there. Use the local server for that, or the two-step upload.
For more on wiring an agent to Orgo over MCP, see Orgo MCP for AI agents.
Limits to know
- 10 MB for a single-step upload, and 2 GB for the two-step upload and for export.
- 90 seconds for the computer's side of a large transfer. Near 2 GB, that takes a fast link (about 24 MB/s).
- A workspace upload reaches only computers that are running at that moment. Stopped computers and new ones need another upload.
- Folder-targeted and large uploads leave no record, so they don't appear in the list and can't be downloaded or deleted through the API.
- Signed links expire after one hour. Ask the download endpoint for a fresh one.
- Export takes one file at a time, not folders.
FAQ
Where does an uploaded file show up on the computer?
Without destPath, in the desktop folder of each running computer, which is /root/Desktop on Linux. With destPath, in the folder you named, on the one computer you named.
Does uploading a file with the same name overwrite the old one? It depends on the mode. A workspace upload skips a file whose name already exists in the desktop folder. A folder-targeted upload and a completed large upload replace a file of the same name.
Can I upload to a computer that is stopped? A workspace upload is stored but not pushed to stopped computers. A large upload can start while the computer is stopped, but it must be running when you complete it.
How long do download links last? One hour, for both export links and links from the download endpoint.
Does deleting a file remove it from the computer? No. Delete removes the stored file and its record. A copy pushed to a computer's desktop stays there.
Does this work on Windows computers?
Yes. Use Windows paths such as C:\Users\Public for destPath and export paths. Missing folders are created, as on Linux. A Linux path on a Windows computer returns 400 on export and on the two-step upload. A single-step upload does not check, so always send a Windows path there.
Can I send a full 2 GB file?
2 GB is the size limit, but the computer must finish copying within 90 seconds. That works on a fast link. If you get 502, compress the file or split it.
What happens to files when a computer stops? Files on the computer's disk are kept across stop and start (Stop computer). Deleting the computer removes them, so export anything you need to keep first. With no plan, an hourly computer stopped because its credit ran out keeps its files for 7 days, then the computer and its files are deleted unless you add credit or pick a plan with room for it (pricing).
Related
- Orgo MCP for AI agents
- The Orgo computer use API
- Pause, fork, and clone an AI agent's computer
- How to scale AI agent computers to thousands on Orgo