Every DurableFile URL contains a SHA-256 hash:
https://f.durablefile.com/f/<sha256-of-the-bytes>/report.pdf
The hash is computed from the file content, not assigned by a database sequence. That one design decision produces most of the properties an automated caller wants.
Uploads are idempotent
An agent that uploads a file, loses the response to a network timeout, and uploads again does not create a duplicate. The second upload hashes to the same value, matches the stored object, and returns HTTP 200 with the same URL:
{
"hash": "…",
"status": "live",
"public_url": "https://f.durablefile.com/f/…/report.pdf",
"deduplicated": true
}
A first-time upload returns HTTP 201. The status code is the only meaningful difference; the URL is identical. Retry loops need no special casing and no client-side deduplication ledger.
Repeats are never billed twice
Quota accounting follows the claim, not the upload count. When your account already claims a hash, uploading those bytes again does not consume more quota. The claim row is keyed on the account and the hash, so there is nothing to double-count.
One subtlety worth knowing: a repeat upload replaces the claim's expiry window with whatever the new request specifies — including none. If you want a temporary link to stay temporary, send the expiry on every upload of those bytes. The lifecycle rules are covered in the expiry article.
Two accounts, one object
When a second account uploads bytes that another account already published, the storage layer keeps a single object. Both accounts hold separate claims, and each claim counts the full byte size against its own quota. Storage deduplication is an infrastructure win; it is deliberately not a billing discount, because quota is what keeps free account creation from being farmable.
The claims are also independent for lifecycle purposes. One account unpublishing or deleting does not affect the other account's live link. The shared object is removed only when the last claim disappears.
The filename is display, the hash is identity
The URL ends in a sanitized filename because humans and download dialogs want one. But the identity of the file is the hash segment. The first uploader of a given content sets the canonical public filename for that object; later claims can record their own name for listing purposes, but the public URL keeps one stable form.
This means renaming a file client-side and uploading it again changes nothing about the URL. Same bytes, same URL — the name is cosmetic.
What this costs you
Content addressing has one honest consequence: you cannot overwrite a file in place. Changing one byte produces a different hash and therefore a different URL. "Update the report" means uploading the new version and sharing its new URL.
For agent workflows this is usually the right trade. A URL you already handed to a customer or wrote into a ticket can never silently change its content, and a pipeline that stores URLs downstream never needs cache invalidation.
Verifying a download
Because the hash is in the URL, any consumer can verify integrity without trusting the host:
curl -sL "https://f.durablefile.com/f/$HASH/report.pdf" -o report.pdf
echo "$HASH report.pdf" | sha256sum --check
If the check passes, the bytes are exactly what the uploader published.
To try the flow end to end, start with the account model: one POST creates an account, $1 funds it, and files are public from the moment they upload — so keep secrets out of them.