# gophercloud — micro file cloud for AI agents A tiny self-hosted file store. Upload, download, and share files over a clean REST API. Neural nets / agents: read this file, then call the endpoints below. BASE_URL: the origin serving this file (e.g. http://localhost:8080) AUTH: send header Authorization: Bearer on every /api/* call. (If the server was started without TOKEN it is open and no header is needed.) Public endpoints (no auth): GET /api/health, GET /llm.txt, GET /s/{id} ## Endpoints GET /api/health -> {"ok":true,"service":"gophercloud","version":"..."} GET /api/files -> {"files":[{name,size,modified,shared,share_url,url}],"count":N} POST /api/files (multipart "file") -> upload a file; returns {"name","size","url"} optional form field "name" overrides filename PUT /api/files/{name} (raw body) -> upload/overwrite raw bytes; returns {"name","size","url"} GET /api/files/{name} -> download bytes (add ?dl=1 to force download) DELETE /api/files/{name} -> {"deleted":"{name}"} POST /api/files/{name}/share -> make public; returns {"id","share_url"} (idempotent) DELETE /api/files/{name}/share -> revoke public link GET /s/{id} -> PUBLIC download via short link (NO auth) — share this URL with anyone ## curl recipes (TOK=, BASE=) # upload raw bytes (simplest for agents) curl -X PUT --data-binary @report.pdf -H "Authorization: Bearer $TOK" "$BASE/api/files/report.pdf" # upload via multipart curl -F file=@cat.png -H "Authorization: Bearer $TOK" "$BASE/api/files" # list files (JSON) curl -H "Authorization: Bearer $TOK" "$BASE/api/files" # download curl -H "Authorization: Bearer $TOK" -o out.pdf "$BASE/api/files/report.pdf" # create a public short link, then anyone can fetch it curl -X POST -H "Authorization: Bearer $TOK" "$BASE/api/files/report.pdf/share" # -> {"id":"ab3xk9q","share_url":"http://.../s/ab3xk9q"} curl -o r.pdf "$BASE/s/ab3xk9q" # public, no token # delete curl -X DELETE -H "Authorization: Bearer $TOK" "$BASE/api/files/report.pdf" ## notes - filenames are sanitized (no paths / traversal). one flat namespace. - errors come back as {"error":"..."} with a matching HTTP status. - max upload size ~2 GB.