Reports
CI test reports, rendered invoices, generated documents a client downloads once and keeps.
Public artifact hosting for AI agents and automation
Upload a report, export, log, archive, or build output — any file up to 25 MiB. Get one public download URL back. $1 per 1 GiB, one-time. No email. No password. No CAPTCHA. No dashboard.
# 1 — create an account. No email, no CAPTCHA, no human step.
curl -X POST https://durablefile.com/v1/accounts
→ {"api_key":"durable_…","status":"unpaid","next_step":"POST …/v1/credit"}
# 2 — buy storage. $1 = 1 GiB, one-time, stacks.
curl -X POST https://durablefile.com/v1/credit \
-H "Authorization: Bearer $DURABLEFILE_KEY" \
-H "Content-Type: application/json" -d '{"gb":1}'
→ {"checkout_url":"https://checkout.stripe.com/…","machine_payment_options":[…]}
# 3 — upload. The URL in the response is live.
curl -X POST https://durablefile.com/v1/upload \
-H "Authorization: Bearer $DURABLEFILE_KEY" \
-F "file=@report.pdf"
→ {"public_url":"https://f.durablefile.com/f/<sha256>/report.pdf","status":"live"}
One POST request returns the API key. The key is shown once — store it in a secret manager.
One dollar grants one GiB. Purchases stack and do not expire. A new account has zero quota until it pays.
Multipart field file or raw bytes. Synchronous checks, then the response carries the live URL.
Content-addressed, download-only delivery. The same bytes always map to the same URL.
CI test reports, rendered invoices, generated documents a client downloads once and keeps.
CSV and JSON dumps from a pipeline or cron job, ready for a spreadsheet or another agent to fetch.
Plain-text command output, linkable from a ticket instead of pasted into it.
Zips of artifacts, wheels, datasets, or binaries that a downstream step pulls by URL.
Screenshots, renders, and video clips delivered as downloads, not inline pages.
There is no allowlist. If the bytes are under 25 MiB, the upload works.
Any file type works, up to 25 MiB per file. Every download is forced attachment with nosniff, so nothing served here renders or executes in a browser. Files are public: do not upload secrets or personal data.
fix field that states the next call to make.Content-Disposition: attachment with nosniff. Nothing served here executes in a browser.| No expiry sent | The file serves for 14 days from upload. |
expires_after_hours / expires_at | Your own window, from minutes up to 180 days. One value only, never null. |
| Expiry passes | The URL returns 404 and the file stops using quota. A background purge removes the bytes soon after. |
Manual unpublish | Hides the link now; the bytes stay until their expiry time. |
POST /v1/files/:hash/publish | Republishes the identical URL and starts a fresh expiry window. |
DELETE /v1/files/:hash | Frees the caller's quota immediately. The shared object survives while another account still claims it. |
$1 = 1 GiB of storage. One-time, and it stacks.
No subscription, no metered bandwidth, no balance that drains. Buy a gigabyte when you need one. There is no free upload tier. Pay by card through Stripe, or machine-to-machine with stablecoins through usevig — the checkout response carries both options, and an agent can settle the usevig one without a human. Storage purchases never expire; files do — 14 days by default, 180 at most, renewable.
POST /v1/accounts | Create an account. Returns the API key once. |
POST /v1/credit | Buy storage. Body {"gb": N}. Returns Stripe and usevig options. |
GET /v1/me | Quota, bytes used, bytes remaining. |
POST /v1/upload | Multipart field file, or raw bytes with X-Filename. |
GET /v1/files | List your file claims, paginated. |
GET /v1/files/:hash | Metadata and publish state for one file. |
POST /v1/files/:hash/publish | Republish, or start a new expiry window. |
POST /v1/files/:hash/unpublish | Hide the link now. Bytes stay until their expiry. |
DELETE /v1/files/:hash | Remove your claim and free its quota. |
GET /f/:hash/:filename | Public download. Forced attachment. |
GET /health | Liveness. Public. |