# BUD-02 ## Blob upload and management `draft` `optional` _All pubkeys MUST be in hex format_ Defines the `/upload`, `/list` and `DELETE /` endpoints ## Blob Descriptor A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, and `uploaded` fields - `url` A publicly accessible URL to the [BUD-01](./01.md#get-sha256---get-blob) `GET /` endpoint with a file extension - `sha256` The sha256 hash of the blob - `size` The size of the blob in bytes - `type` The MIME type of the blob (falling back to `application/octet-stream` if unknown) - `uploaded` The unix timestamp of when the blob was uploaded to the server Servers MUST include a file extension in the URL in the `url` field to allow clients to easily embed the URL in social posts or other content Servers MAY include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support Example: ```json { "url": "https://cdn.example.com/b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf", "sha256": "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553", "size": 184292, "type": "application/pdf", "uploaded": 1725105921 } ``` ## PUT /upload - Upload Blob The `PUT /upload` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` and `Content-Length` headers to get the MIME type and size of the data The endpoint MUST NOT modify the blob in any way and SHOULD return the exact same sha256 that was uploaded. This is critical to allow users to re-upload their blobs to new servers The endpoint MUST return a [Blob Descriptor](#blob-descriptor) if the upload was successful or an error object if it was not Servers MAY reject an upload for any reason and SHOULD respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection ### 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 /` endpoint is redirected to an external URL (see the [proxying and redirection section from BUD-01](./01.md#proxying-and-redirection-optional)), as external servers may rely on the file extension to serve the blob correctly. ### Upload Authorization (Optional) Servers MAY require an authorization token when uploading blobs. The server MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then perform the following additional checks: 1. The `t` tag MUST be set to `upload` 2. The authorization token MUST contain at least one `x` tag matching the sha256 hash of the body of the request. The `x` tag scopes the token to specific blob hashes (see [BUD-11](./11.md#tag-scoping)). Example authorization token: ```json { "id": "bb653c815da18c089f3124b41c4b5ec072a40b87ca0f50bbbc6ecde9aca442eb", "pubkey": "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e", "kind": 24242, "content": "Upload bitcoin.pdf", "created_at": 1708773959, "tags": [ ["t", "upload"], ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"], ["expiration", "1708858680"] ], "sig": "d0d58c92afb3f4f1925120b99c39cffe77d93e82f488c5f8f482e8f97df75c5357175b5098c338661c37d1074b0a18ab5e75a9df08967bfb200930ec6a76562f" } ``` ## GET /list/pubkey - List Blobs (Unrecommended) **Note:** The `/list` endpoint is optional and unrecommended. It is not necessary for all servers to implement the `/list` endpoint. Servers MAY implement this endpoint, but are not required to do so. The `/list/` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that were uploaded by the specified pubkey The endpoint MUST support `cursor` and `limit` query parameters for cursor based pagination. The `cursor` parameter MUST be the `sha256` hash of the last blob in the previous page, or omitted to request the first page. The `limit` parameter specifies the maximum number of results to return. The returned array of blob descriptors MUST be sorted by the `uploaded` date in descending order and MUST NOT include the blob at the cursor The endpoint MAY support `since` and `until` query parameters to filter the list of blobs by their `uploaded` date. These parameters are deprecated for pagination purposes as they do not preserve server resources Servers MAY reject a list request for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection ### List Authorization The server MAY require a `list` authorization token when listing blobs uploaded by the pubkey. If a server requires authorization it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then it MUST perform the following additional checks: 1. The `t` tag MUST be set to `list` Example authorization token: ```json { "id": "cbb1cab9566355bfdf04e1f1fc1e655fe903ecc193e8a750092ee53beec2a0e8", "pubkey": "a5fc3654296e6de3cda6ba3e8eba7224fac8b150fd035d66b4c3c1dc2888b8fc", "kind": 24242, "content": "List Blobs", "created_at": 1708772350, "tags": [ ["t", "list"], ["expiration", "1708858680"] ], "sig": "ff9c716f8de0f633738036472be553ce4b58dc71d423a0ef403f95f64ef28582ef82129b41d4d0ef64d2338eb4aeeb66dbc03f8b3a3ed405054ea8ecb14fa36c" } ``` ## DELETE /sha256 - Delete Blob Servers MUST accept `DELETE` requests to the `/` endpoint Servers MAY reject a delete request for any reason and SHOULD respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection ### Delete Authorization Servers MAY require a `delete` authorization token when deleting blobs. If a server requires authorization it MUST first perform the base validation checks defined in [BUD-11](./11.md#base-validation), then MUST perform the following additional checks: 1. The `t` tag MUST be set to `delete` 2. MUST contain at least one `x` tag matching the sha256 hash of the blob being deleted. **Multiple `x` tags in the authorization token MUST NOT be interpreted as the user requesting to delete multiple blobs.** Example authorization token: ```json { "id": "a92868bd8ea740706d931f5d205308eaa0e6698e5f8026a990e78ee34ce47fe8", "pubkey": "ae0063dd2c81ec469f2291ac029a19f39268bfc40aea7ab4136d7a858c3a06de", "kind": 24242, "content": "Delete bitcoin.pdf", "created_at": 1708774469, "tags": [ ["t", "delete"], ["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"], ["expiration", "1708858680"] ], "sig": "2ba9af680505583e3eb289a1624a08661a2f6fa2e5566a5ee0036333d517f965e0ffba7f5f7a57c2de37e00a2e85fd7999076468e52bdbcfad8abb76b37a94b0" } ```