Upfile
pilotctl appstore install io.pilot.upfileAbout Upfile
Upfile turns a file on the host into a URL an agent can hand to a human or another service. There is no dashboard and no browser step anywhere in the loop: upfile.signup creates an account and saves the key locally, and from then on upfile.upload returns a live, permanent link.
Everything returns JSON. The upload methods emit {id, url, visibility, size, type, expires_at, storage_used, storage_limit}, so an agent reads .url rather than scraping console output.
Three shapes of link. A plain upload is public and permanent — an unauthenticated URL that keeps working. upload_private puts it behind authentication. upload_expiring gives it a TTL in seconds, which is the right choice for build logs, debug dumps, and anything you would rather not leave permanently reachable.
Housekeeping. status shows tier and quota, list enumerates what is stored with each file's id, and remove deletes one by id and reclaims the space. The free tier is 1GB total across all files.
The CLI ships with the app as a per-platform binary verified by sha256 at install, so there is no Node install and no package manager involved on the host.
Methods · 10
upfile.signupupfile.uploadupfile.upload_privateupfile.upload_expiringupfile.statusupfile.listupfile.removeupfile.versionupfile.cli_helpupfile.runFull usage demo
When your agent has produced a file — a render, a report, a screenshot, a log — and needs a URL it can paste somewhere a human or another service will open.
pilotctl appstore call io.pilot.upfile upfile.signup '{"email":"[email protected]"}'Account created. API key: upf_... Tier: free (1GB). Key saved.The key is written to the CLI config on this host, so every later call just works. No dashboard, no browser.
Worked examples
pilotctl appstore call io.pilot.upfile upfile.upload '{"path":"/tmp/report.pdf"}'{"id":"tRbBqIyEiB","url":"https://cdn.upfile.sh/tRbBqIyEiB.pdf","visibility":"public","size":6941}The URL is live immediately and permanent. Always JSON, so read .url straight out of it.
pilotctl appstore call io.pilot.upfile upfile.upload_expiring '{"path":"/tmp/build.log","expiry":3600}'{"id":"...","url":"https://cdn.upfile.sh/....log","expires_at":"2026-08-06T17:00:00.000Z"}expiry is seconds. Use it for anything you would not want indexed a year from now.
pilotctl appstore call io.pilot.upfile upfile.status '{}'Tier: free Storage: 0.01GB / 1GBFree tier is 1GB. upfile.list shows individual files; upfile.remove deletes one by id.
Good to know
- Run upfile.signup once per host if there is no key. Everything else fails with No API key until you do.
- Read .url from the JSON — the human-readable output is not stable.
- A plain upload is a permanent, unauthenticated URL. Use upload_private or upload_expiring for anything sensitive.
- expiry is in SECONDS, not minutes. 3600 is an hour.
- Free tier is 1GB total, not per file. Use upfile.remove to reclaim space.
Next
io.pilot.upfile upfile.help '{}'
What’s New
- First release on the Pilot app store.