Files
2026-06-25 11:57:41 -05:00

7.8 KiB

BUD-13

Path-based blob upload

draft optional

All pubkeys MUST be in hex format

This document supersedes the PUT /upload endpoint definition from BUD-02.

Servers that implement this document MAY continue to support the PUT /upload endpoint from BUD-02 for compatibility.

Defines the PUT /<sha256> endpoint.

The Blob Descriptor type is defined in BUD-02.

PUT /sha256 - Upload Blob

The PUT /<sha256> endpoint MUST accept binary data in the request body. The <sha256> path segment MUST be a lowercase hex-encoded sha256 hash of the blob being stored.

When the request body is binary data, the server MUST NOT modify the blob in any way and MUST compute the sha256 hash over the exact bytes received. This requirement ensures that users can re-upload blobs to other servers without discrepancies.

For binary uploads, clients SHOULD include Content-Type and Content-Length headers specifying the MIME type and size of the blob.

If the computed sha256 of a binary request body does not match the <sha256> path segment, the server MUST reject the request with 409 Conflict and MUST NOT persist the blob.

Remote Source Upload

Servers MAY also accept one or more url query parameters that tell the server to fetch the blob from remote URLs instead of receiving the blob bytes in the request body. This rolls the mirroring flow from BUD-04 into the same path-addressed upload endpoint and allows clients to reuse the same BUD-11 upload authorization token as long as at least one x tag matches the <sha256> path.

When one or more url query parameters are present, the request body MUST be empty and servers MUST ignore Content-Type and Content-Length as blob metadata. If a client sends both url query parameters and a non-empty request body, servers MUST reject the request with 400 Bad Request.

To provide a single remote source, clients MUST send one url query parameter:

PUT /b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553?url=https%3A%2F%2Fcdn.example.com%2Fb1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf

To provide multiple remote sources, clients MUST repeat the url query parameter:

PUT /b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553?url=https%3A%2F%2Fcdn-a.example.com%2Fb1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf&url=https%3A%2F%2Fcdn-b.example.com%2Fb1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf

Remote source URLs MUST be URL-encoded absolute http or https URLs. Servers MUST reject requests that include invalid url parameters with 400 Bad Request.

When multiple url query parameters are provided, servers MAY try any or all of the URLs in any order. Servers MUST only store the blob if the sha256 hash of the fetched bytes matches the <sha256> path segment. If the fetched blob hash does not match the <sha256> path segment, the server MUST reject the request with 409 Conflict and MUST NOT persist the blob.

The destination server SHOULD use the Content-Type header returned from the successful origin response to infer the MIME type of the blob. If the Content-Type header is not present, the destination server SHOULD attempt to detect the Content-Type from the blob contents and file extension, falling back to application/octet-stream if it cannot determine the type.

Servers MAY use the origin Content-Length header to reject blobs that exceed server size limits before downloading the full response.

If the blob was newly stored, the endpoint MUST respond with 201 Created and a Blob Descriptor in the response body. If the blob already exists, the endpoint MUST respond with 200 OK and a Blob Descriptor in the response body.

Servers MUST handle uploads correctly regardless of whether the client performed a HEAD /upload request first.

Status codes

Servers SHOULD use the following status codes for PUT /<sha256> responses:

Status Code Meaning
200 OK The blob already exists and the server is returning the existing Blob Descriptor.
201 Created The blob was stored successfully and the server is returning its Blob Descriptor.
400 Bad Request The sha256 path, request headers, body, or remote URL parameters are malformed.
401 Unauthorized Authorization is required and missing or invalid. See BUD-11.
402 Payment Required Payment is required before the upload can proceed. See BUD-07.
403 Forbidden The request is understood but not allowed by server policy.
409 Conflict The sha256 from the path does not match the request body or fetched remote blob.
411 Length Required A required Content-Length header is missing.
413 Content Too Large The blob exceeds server size limits.
415 Unsupported Media Type The blob type is not supported.
429 Too Many Requests The client has exceeded a rate limit or quota.
502 Bad Gateway The server could not fetch the blob from any remote URL or every origin response was unusable.

If included, X-Reason MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow.

File extension normalization (Optional)

When storing blobs, servers MAY normalise the file extension to a standard format (e.g. .pdf, .png, etc.) based on the MIME type of the blob. This can be especially useful when the GET /<sha256> endpoint is redirected to an external URL (see the proxying and redirection section from BUD-01), as external servers may rely on the file extension to serve the blob correctly.

Pre-flight upload acceptance checks

Clients MAY use HEAD /upload from BUD-06 as an optimization step before PUT /<sha256>.

Servers that implement PUT /<sha256> SHOULD preserve the existing HEAD /upload semantics from BUD-06 so clients can continue checking whether an upload would be accepted before sending the request body.

This pre-flight request is only an optimization. Clients MAY skip it entirely, and the result is not a guarantee of the eventual PUT /<sha256> outcome because server state may change between requests.

Clients that want to check whether a blob already exists on the server SHOULD use HEAD /<sha256> from BUD-01.

HTTP 100 Continue (Optional)

Clients MAY use the HTTP Expect: 100-continue mechanism with PUT /<sha256> to allow a server or intermediary to reject an upload before the request body is sent.

Servers MAY support this optimization, but clients MUST NOT rely on it because support varies across server frameworks, reverse proxies, and intermediaries.

Clients that need a portable and explicit pre-flight mechanism SHOULD use HEAD /upload.