From 014bc528ebefb4d114074330a5c852a6c2ac0178 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Sat, 27 Apr 2024 12:14:03 -0500 Subject: [PATCH 1/9] move server implementation to bud-01 write draft bud-02 --- Client.md | 13 ----------- README.md | 30 ++++--------------------- Server.md => buds/bud-01.md | 44 +++++++++++++++++++++++++++---------- buds/bud-02.md | 21 ++++++++++++++++++ 4 files changed, 57 insertions(+), 51 deletions(-) delete mode 100644 Client.md rename Server.md => buds/bud-01.md (79%) create mode 100644 buds/bud-02.md diff --git a/Client.md b/Client.md deleted file mode 100644 index 6d4e560..0000000 --- a/Client.md +++ /dev/null @@ -1,13 +0,0 @@ -# Blossom Client Implementation - -## Upload Blob - -Clients should perform the following steps when uploading blobs - -1. Prompt the user to sign an [Authorization event](./Server.md#upload-authorization-required) for the blob -2. Get the users [Server Discovery](./Nostr.md#user-server-discovery) -3. Make a `PUT /upload` request with the authorization event to each server on the list - -## Implementations - -Example implementation (Typescript) [blossom-client](https://github.com/hzrd149/blossom-client) diff --git a/README.md b/README.md index a5c2968..af5cb74 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -# 🌸 Blossom WIP - -Blobs stored simply on mediaservers +# 🌸 Blossom - Blobs stored simply on mediaservers ## What is it? @@ -25,31 +23,11 @@ Blossom Servers expose four endpoints for managing blobs - `DELETE /` - `Authentication`: Signed [nostr event](./Server.md#delete-authorization-required) -## Blob Descriptor +## Protocol specification -A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, and `created` fields +BUDs stand for Blossom Upgrade Possibilities. -- `url` A public facing url this blob can retrieved from -- `sha256` The sha256 hash of the blob -- `size` The size of the blob in bytes -- `type` (optional) The MIME type of the blob -- `created` The unix timestamp of when the blob was uploaded to the server - -Servers may include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support - -## Nostr Identities - -Blossom uses nostr public / private keys for identities. Users are expected to sign authorization events to prove their identity when interacting with servers - -See [Nostr](./Nostr.md) - -## Server Implementation - -See [Server](./Server.md) - -## Client Implementation - -See [Client](./Client.md) +See the [BUDs](./buds) folder and specifically [BUD-01](./buds/bud-01.md) for a detailed explanation of the endpoints ## License diff --git a/Server.md b/buds/bud-01.md similarity index 79% rename from Server.md rename to buds/bud-01.md index b4a5086..37b18fc 100644 --- a/Server.md +++ b/buds/bud-01.md @@ -1,14 +1,20 @@ -# Blossom Server Implementation +# BUD-01 + +## Core endpoint outline + +`draft` `mandatory` + +Blossom uses [nostr](https://github.com/nostr-protocol/nostr) public / private keys for identities. Users are expected to sign authorization events to prove their identity when interacting with servers _All pubkeys MUST be in hex format_ -## CORS +## Cross origin headers -Servers MUST set `Access-Control-Allow-Origin: *`, `Access-Control-Allow-Headers: Authorization,*` and `Access-Control-Allow-Methods: GET, PUT, DELETE` headers on all endpoint to ensure compatibility with apps hosted on other domains +Servers MUST set the `Access-Control-Allow-Origin: *`, `Access-Control-Allow-Headers: Authorization,*` and `Access-Control-Allow-Methods: GET, PUT, DELETE` headers on all endpoints to ensure compatibility with apps hosted on other domains ## Authorization events -Authorization events are used to identify the users pubkey with the server +Authorization events are used to identify the users to the server Authorization events must be generic and must NOT be scoped to specific servers. This allows pubkeys to sign a single event and interact the same way with multiple servers. @@ -52,6 +58,18 @@ Example HTTP Authorization header: Authorization: Nostr eyJpZCI6IjhlY2JkY2RkNTMyOTIwMDEwNTUyNGExNDI4NzkxMzg4MWIzOWQxNDA5ZDhiOTBjY2RiNGI0M2Y4ZjBmYzlkMGMiLCJwdWJrZXkiOiI5ZjBjYzE3MDIzYjJjZjUwOWUwZjFkMzA1NzkzZDIwZTdjNzIyNzY5MjhmZDliZjg1NTM2ODg3YWM1NzBhMjgwIiwiY3JlYXRlZF9hdCI6MTcwODc3MTIyNywia2luZCI6MjQyNDIsInRhZ3MiOltbInQiLCJnZXQiXSxbImV4cGlyYXRpb24iLCIxNzA4ODU3NTQwIl1dLCJjb250ZW50IjoiR2V0IEJsb2JzIiwic2lnIjoiMDJmMGQyYWIyM2IwNDQ0NjI4NGIwNzFhOTVjOThjNjE2YjVlOGM3NWFmMDY2N2Y5NmNlMmIzMWM1M2UwN2I0MjFmOGVmYWRhYzZkOTBiYTc1NTFlMzA4NWJhN2M0ZjU2NzRmZWJkMTVlYjQ4NTFjZTM5MGI4MzI4MjJiNDcwZDIifQ== ``` +## Blob Descriptor + +A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, and `created` fields + +- `url` A public facing url this blob can retrieved from +- `sha256` The sha256 hash of the blob +- `size` The size of the blob in bytes +- `type` (optional) The MIME type of the blob +- `created` The unix timestamp of when the blob was uploaded to the server + +Servers may include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support + ## Endpoints All endpoints MUST be served from the root path (eg. `https://cdn.example.com/upload`, etc). This allows clients to talk to servers interchangeably when uploading or fetching blobs @@ -68,6 +86,8 @@ content-type: application/json; charset=utf-8 content-length: 32 access-control-allow-origin: * access-control-expose-headers: * +access-control-allow-headers: authorization,* +access-control-allow-methods: get, put, delete {"message":"Missing Auth event"} ``` @@ -117,14 +137,14 @@ The `PUT /upload` endpoint should expect the `Content-Type` header of the reques The endpoint MUST return a [Blob Descriptor](./README.md#blob-descriptor) if the upload was successful or an error object if 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 +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 #### Upload Authorization (required) -Servers must accept an authorization event when uploading blobs and should perform additional checks +Servers MUST accept an authorization event when uploading blobs and should perform additional checks -1. The `t` tag must be set to `upload` -2. A `size` tag must be present and set to the total size of the uploaded blob +1. The `t` tag MUST be set to `upload` +2. A `size` tag MUST be present and set to the total size of the uploaded blob Example Authorization event: @@ -146,11 +166,11 @@ Example Authorization event: ### GET /list/pubkey - List Blobs -The `/list/` endpoint must return a JSON array of [Blob Descriptor](./README.md#blob-descriptor) that where uploaded by the specified pubkey +The `/list/` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that where uploaded by the specified pubkey -The endpoint must support a `since` and `until` query parameter to limit the returned blob descriptors by the `created` field +The endpoint MUST support a `since` and `until` query parameter to limit the returned blob descriptors by the `created` field -Servers may reject an upload for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection +Servers may reject a list 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 (optional) @@ -185,7 +205,7 @@ Servers may reject a delete request for any reason and should respond with the a #### Delete Authorization (required) -Servers must accept an authorization event when deleting blobs +Servers MUST accept an authorization event when deleting blobs Servers should perform additional checks on the authorization event diff --git a/buds/bud-02.md b/buds/bud-02.md new file mode 100644 index 0000000..6c04d25 --- /dev/null +++ b/buds/bud-02.md @@ -0,0 +1,21 @@ +# BUD-02 + +## Media processing endpoint + +`draft` `optional` + +### PUT /process + +A server MAY expose a `/process` endpoint for the purpose of processing and/or optimizing any blob the user uploads + +The endpoint MUST accept the `Content-Type` of `multipart/form-data` with the field `blob` containing the raw binary of the blob being upload + +Similar to the `/upload` endpoint the server MUST respond with a [Blob Descriptor](./bud-01.md#blob-descriptor) + +The server MUST also require authentication for the endpoint. in which case it MUST accept the same `upload` [authorization event](./bud-01#upload-authorization-required) as the `/upload` endpoint + +### HEAD /process + +If a server is exposing a `PUT /process` endpoint is MUST also expose a `HEAD /process` endpoint to allow clients to check if the `PUT /process` endpoint is available + +The endpoint MUST respond with the `200` status code From 6fd565785892da955496366202b97001d32240a9 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Mon, 29 Apr 2024 20:01:23 -0500 Subject: [PATCH 2/9] add requirement to not modify blob on /upload --- README.md | 2 +- buds/bud-01.md | 6 ++++-- buds/bud-02.md | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index af5cb74..d53c6d3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 🌸 Blossom - Blobs stored simply on mediaservers +# 🌸 Blossom - Blobs stored simply on mediaservers ## What is it? diff --git a/buds/bud-01.md b/buds/bud-01.md index 37b18fc..eca0940 100644 --- a/buds/bud-01.md +++ b/buds/bud-01.md @@ -133,9 +133,11 @@ The endpoint MUST accept an optional file extension in the URL similar to the `G ### PUT /upload - Upload Blob -The `PUT /upload` endpoint should expect the `Content-Type` header of the request to be set to the MIME type of the blob and the body of the request to the raw data of the blob. +The `PUT /upload` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` header to get the MIME type of the data -The endpoint MUST return a [Blob Descriptor](./README.md#blob-descriptor) if the upload was successful or an error object if not. +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](./README.md#blob-descriptor) if the upload was successful or an error object if 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 diff --git a/buds/bud-02.md b/buds/bud-02.md index 6c04d25..5d6fe0a 100644 --- a/buds/bud-02.md +++ b/buds/bud-02.md @@ -8,7 +8,9 @@ A server MAY expose a `/process` endpoint for the purpose of processing and/or optimizing any blob the user uploads -The endpoint MUST accept the `Content-Type` of `multipart/form-data` with the field `blob` containing the raw binary of the blob being upload +Just like the `/upload` endpoint the `/process` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` header to get the MIME type of the data + +The endpoint MUST also accept the `Content-Type` of `multipart/form-data` with the field `blob` containing the raw binary of the blob being upload Similar to the `/upload` endpoint the server MUST respond with a [Blob Descriptor](./bud-01.md#blob-descriptor) From 3c4aaa25fd6ed6c83c6ff31fc647aad1bab5642a Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Mon, 29 Apr 2024 21:39:09 -0500 Subject: [PATCH 3/9] fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d53c6d3..50227bf 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Blossom Servers expose four endpoints for managing blobs ## Protocol specification -BUDs stand for Blossom Upgrade Possibilities. +BUDs stand for Blossom Upgrade Documents. See the [BUDs](./buds) folder and specifically [BUD-01](./buds/bud-01.md) for a detailed explanation of the endpoints From 2f398baad05ab7310368dcc7c9c4cb4719f96b98 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Tue, 30 Apr 2024 09:08:46 -0500 Subject: [PATCH 4/9] use "server" instead of "r" in 10063 --- Nostr.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Nostr.md b/Nostr.md index 8a6b662..9206007 100644 --- a/Nostr.md +++ b/Nostr.md @@ -6,21 +6,21 @@ See [Authorization events](./Server.md#authorization-events) ## User Server Discovery -Users should publish a kind `10063` event with a list of ordered `r` tags indicating servers that others users should use when getting their blobs +Users should publish a kind `10063` event with a list of ordered `server` tags indicating servers that others users should use when getting their blobs ### Example ```json { - "id": "90718dd2f481ad1d9dd72eab2b210d1b3d03231f114b0825bf967465748934f0", - "pubkey": "7d917f22b84356a3c4e5ef7ec6d4464fb1dc3258cbf58c58d8bf079580c12c91", + "id": "e4bee088334cb5d38cff1616e964369c37b6081be997962ab289d6c671975d71", + "pubkey": "781208004e09102d7da3b7345e64fd193cd1bc3fce8fdae6008d77f9cabcd036", "content": "", "kind": 10063, "created_at": 1708774162, "tags": [ - ["r", "https://cdn.self.hosted"], - ["r", "https://cdn.satellite.earth"] + ["server", "https://cdn.self.hosted"], + ["server", "https://cdn.satellite.earth"] ], - "sig": "805a0c00cdad7ae25de70740751b8e5985bec24bb6aead8c65e0cc33d6205dd5a06689b566e62589885ad86bfb55c5c7dfb5a9ce6ddb29cf04507fa76e485040" + "sig": "cc5efa74f59e80622c77cacf4dd62076bcb7581b45e9acff471e7963a1f4d8b3406adab5ee1ac9673487480e57d20e523428e60ffcc7e7a904ac882cfccfc653" } ``` From f1129535c21dec0760eac42a4bb9910969c4ffae Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Tue, 30 Apr 2024 16:58:49 -0500 Subject: [PATCH 5/9] add requirement for size and name tag in upload update upload example --- buds/bud-01.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/buds/bud-01.md b/buds/bud-01.md index eca0940..20821d9 100644 --- a/buds/bud-01.md +++ b/buds/bud-01.md @@ -18,27 +18,30 @@ Authorization events are used to identify the users to the server Authorization events must be generic and must NOT be scoped to specific servers. This allows pubkeys to sign a single event and interact the same way with multiple servers. -Events must be kind `24242` and have a `t` tag with a verb of `get`, `upload`, `list`, or `delete` +Events MUST be kind `24242` and have a `t` tag with a verb of `get`, `upload`, `list`, or `delete` -Events must have the `content` set to a human readable string explaining to the user what the events inteded use is. For example `Upload Blob`, `Delete dog-picture.png`, `List Images`, etc +Events MUST contain a `size` set to the blob size in bytes and a `name` tag set to the original filename -All events must have a [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) `expiration` tag set to a unix timestamp at which the event should be considered expired. +Events MUST have the `content` set to a human readable string explaining to the user what the events inteded use is. For example `Upload Blob`, `Delete dog-picture.png`, `List Images`, etc + +All events MUST have a [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) `expiration` tag set to a unix timestamp at which the event should be considered expired. Example event: ```json { - "id": "65c72db0c3b82ffcb395589d01f3e2849c28753e9e7156ceb88e5dd937ca845f", - "pubkey": "6ea2ab6f206844b1fe48bd8a7eb22ed6e4114a5b2a5252700a729a88142b2bc3", + "id": "2f770debbc651f5b0d13b5b5459ccc271e861d9bfd010add894435277b6719de", + "pubkey": "4e3b5ad6d831b3598b03ca38c959bfa56ed63b203052c5a99941701cda7a4d77", "kind": 24242, "content": "Upload bitcoin.pdf", "created_at": 1708773959, "tags": [ ["t", "upload"], ["size", "184292"], + ["name", "bitcoin.pdf"], ["expiration", "1708858680"] ], - "sig": "df099ecaeadb7ebcd7ec8247eb57eb6720d39f64a024be3ef1ed9b5d51087b0e866bd08fd317d5167f9bdb9cdae4e593539b86678c4d922db17d0463e0f9e0e3" + "sig": "44f5dbe16f7db8bce5c7709a616c772a3ac950e42ab8b0df99a9d05605f87c335aec18078543627c24c7ee1edb3a6356705d4137eff71af880c24be8388a6525" } ``` From ff33d9c52f3446401b0c9a4213682c45c505577d Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Wed, 1 May 2024 16:45:06 -0500 Subject: [PATCH 6/9] remove bud-02 --- buds/bud-01.md | 11 ++++------- buds/bud-02.md | 23 ----------------------- 2 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 buds/bud-02.md diff --git a/buds/bud-01.md b/buds/bud-01.md index 20821d9..6ab807d 100644 --- a/buds/bud-01.md +++ b/buds/bud-01.md @@ -20,8 +20,6 @@ Authorization events must be generic and must NOT be scoped to specific servers. Events MUST be kind `24242` and have a `t` tag with a verb of `get`, `upload`, `list`, or `delete` -Events MUST contain a `size` set to the blob size in bytes and a `name` tag set to the original filename - Events MUST have the `content` set to a human readable string explaining to the user what the events inteded use is. For example `Upload Blob`, `Delete dog-picture.png`, `List Images`, etc All events MUST have a [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) `expiration` tag set to a unix timestamp at which the event should be considered expired. @@ -30,18 +28,17 @@ Example event: ```json { - "id": "2f770debbc651f5b0d13b5b5459ccc271e861d9bfd010add894435277b6719de", - "pubkey": "4e3b5ad6d831b3598b03ca38c959bfa56ed63b203052c5a99941701cda7a4d77", + "id": "a2d97d0c8b19d6d91b8bd3c36feeb69f176861f9443ba575cbabf9941d4200bf", + "pubkey": "2db760eae90b5764f3503e0c5660a1a74be9ded5eb8b493e81f65c28a088e9fe", "kind": 24242, "content": "Upload bitcoin.pdf", "created_at": 1708773959, "tags": [ ["t", "upload"], ["size", "184292"], - ["name", "bitcoin.pdf"], ["expiration", "1708858680"] ], - "sig": "44f5dbe16f7db8bce5c7709a616c772a3ac950e42ab8b0df99a9d05605f87c335aec18078543627c24c7ee1edb3a6356705d4137eff71af880c24be8388a6525" + "sig": "1442c68d5a661d821e9a4b91999b433a1d11557eeb6255496c6875c00d02497deb03dcb54597f210582cd62b621df21b080a0eadbd66ae703264b5929b160d05" } ``` @@ -149,7 +146,7 @@ Servers MAY reject an upload for any reason and should respond with the appropri Servers MUST accept an authorization event when uploading blobs and should perform additional checks 1. The `t` tag MUST be set to `upload` -2. A `size` tag MUST be present and set to the total size of the uploaded blob +2. A `size` tag MUST be present and set to the total size of the uploaded blob in bytes Example Authorization event: diff --git a/buds/bud-02.md b/buds/bud-02.md deleted file mode 100644 index 5d6fe0a..0000000 --- a/buds/bud-02.md +++ /dev/null @@ -1,23 +0,0 @@ -# BUD-02 - -## Media processing endpoint - -`draft` `optional` - -### PUT /process - -A server MAY expose a `/process` endpoint for the purpose of processing and/or optimizing any blob the user uploads - -Just like the `/upload` endpoint the `/process` endpoint MUST accept binary data in the body of the request and MAY use the `Content-Type` header to get the MIME type of the data - -The endpoint MUST also accept the `Content-Type` of `multipart/form-data` with the field `blob` containing the raw binary of the blob being upload - -Similar to the `/upload` endpoint the server MUST respond with a [Blob Descriptor](./bud-01.md#blob-descriptor) - -The server MUST also require authentication for the endpoint. in which case it MUST accept the same `upload` [authorization event](./bud-01#upload-authorization-required) as the `/upload` endpoint - -### HEAD /process - -If a server is exposing a `PUT /process` endpoint is MUST also expose a `HEAD /process` endpoint to allow clients to check if the `PUT /process` endpoint is available - -The endpoint MUST respond with the `200` status code From 077084ad45fc4a9139c8b3f2abd67ef3dfc6ce64 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Wed, 1 May 2024 16:49:15 -0500 Subject: [PATCH 7/9] add requirement for redirects to include sha256 hash --- buds/bud-01.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/buds/bud-01.md b/buds/bud-01.md index 6ab807d..b30ff25 100644 --- a/buds/bud-01.md +++ b/buds/bud-01.md @@ -98,6 +98,9 @@ The `GET /` endpoint MUST return the contents of the blob with the `Cont The endpoint MUST accept an optional file extension in the URL. ie. `.pdf`, `.png`, etc +If the endpoints returns a 301 or 302 redirect it MUST redirect to a URL containing the same sha256 hash as requested blob. +This ensures that if a user was to copy or reuse the redirect URL it would still contain the original sha256 hash + #### Get Authorization (optional) The server may optionally require authorization when fetching blobs from the `GET /` endpoint From 6cb4e3a5cf010162ec845de1d59f8b90b77b1af6 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Wed, 1 May 2024 16:51:09 -0500 Subject: [PATCH 8/9] fix --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50227bf..b4f75b3 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,9 @@ Blossom Servers expose four endpoints for managing blobs - `DELETE /` - `Authentication`: Signed [nostr event](./Server.md#delete-authorization-required) -## Protocol specification +## Protocol specification (BUDs) -BUDs stand for Blossom Upgrade Documents. +BUDs stand for **Blossom Upgrade Documents**. See the [BUDs](./buds) folder and specifically [BUD-01](./buds/bud-01.md) for a detailed explanation of the endpoints From e66695bb178bacb778c1dd87ab964ee139a23e40 Mon Sep 17 00:00:00 2001 From: hzrd149 Date: Thu, 2 May 2024 17:10:17 -0500 Subject: [PATCH 9/9] rename "created" field to "uploaded" --- buds/bud-01.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/buds/bud-01.md b/buds/bud-01.md index b30ff25..672a874 100644 --- a/buds/bud-01.md +++ b/buds/bud-01.md @@ -60,13 +60,13 @@ Authorization: Nostr eyJpZCI6IjhlY2JkY2RkNTMyOTIwMDEwNTUyNGExNDI4NzkxMzg4MWIzOWQ ## Blob Descriptor -A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, and `created` fields +A blob descriptor is a JSON object containing `url`, `sha256`, `size`, `type`, and `uploaded` fields - `url` A public facing url this blob can retrieved from - `sha256` The sha256 hash of the blob - `size` The size of the blob in bytes - `type` (optional) The MIME type of the blob -- `created` The unix timestamp of when the blob was uploaded to the server +- `uploaded` The unix timestamp of when the blob was uploaded to the server Servers may include additional fields in the descriptor like `magnet`, `infohash`, or `ipfs` depending on other protocols they support @@ -173,7 +173,7 @@ Example Authorization event: The `/list/` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that where uploaded by the specified pubkey -The endpoint MUST support a `since` and `until` query parameter to limit the returned blob descriptors by the `created` field +The endpoint MUST support a `since` and `until` query parameter to limit the returned blobs by thier `uploaded` date Servers may reject a list for any reason and MUST respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection