{"id":"370b03c777f3e2740a9230257a27817e93eb17dac6ea8465a0fc91f82dc4fecb","pubkey":"1336a17e161d0e8af2b68ee95ad2a479fc38bef96a17d6127ea02a40d28dd97e","created_at":1775926010,"kind":30817,"tags":[["d","bud-05"],["title","BUD-05: Media optimization endpoints"],["summary","Defines PUT /media, where a server transcodes and optimises what it is given rather than storing the bytes untouched."],["s","draft"],["t","blossom"],["t","bud"],["alt","A specification: BUD-05: Media optimization endpoints"],["client","openspecs-import"],["published_at","1721575823"],["proxy","https://github.com/hzrd149/blossom/blob/b5bd2801d1763aa635fc8fea7a76597e0eb18990/buds/05.md","web"],["x","5c4979ae317ed6a7fe4561a96eb6acb666b7397c679ef236a3486cd5f59a12bf"]],"content":"# BUD-05\n\n## Media optimization endpoints\n\n`draft` `optional`\n\nDefines the `PUT /media` endpoint for processing and optimizing media\n\n## PUT /media\n\nThe `PUT /media` endpoint MUST accept binary data in the request body.  \nThe server SHOULD perform any optimizations or conversions it deems necessary in order to make the media more suitable for distribution.\n\nClients SHOULD include `Content-Type` and `Content-Length` headers specifying the MIME type and size of the data. Clients MAY provide an `X-SHA-256` header containing the lowercase hex-encoded sha256 of the request body. A server MAY use this value to enforce rejection policies or perform authorization checks prior to persisting the blob.\n\nOn success, the endpoint MUST respond with either `200 OK` or `201 Created` and a [Blob Descriptor](#blob-descriptor) in the response body. Clients MUST treat both status codes as successful media creation.  \nOn failure, the endpoint MUST return an appropriate `4xx` or `5xx` status code and an error message explaining the reason for the rejection.\n\n### PUT /media status codes\n\nServers SHOULD use the following status codes for `PUT /media` responses:\n\n| Status Code                  | Meaning                                                        |\n| ---------------------------- | -------------------------------------------------------------- |\n| `200 OK`                     | The media was accepted, processed, and stored successfully.    |\n| `201 Created`                | The media was accepted, processed, and stored successfully.    |\n| `400 Bad Request`            | The request headers or body are malformed.                     |\n| `401 Unauthorized`           | Authorization is required and missing or invalid.              |\n| `403 Forbidden`              | The request is understood but not allowed by server policy.    |\n| `409 Conflict`               | The provided `X-SHA-256` does not match the request body.      |\n| `411 Length Required`        | A required `Content-Length` header is missing.                 |\n| `413 Content Too Large`      | The media exceeds server size limits.                          |\n| `415 Unsupported Media Type` | The media type is not supported.                               |\n| `422 Unprocessable Content`  | The media is well-formed but cannot be processed successfully. |\n| `429 Too Many Requests`      | The client has exceeded a rate limit or quota.                 |\n| `503 Service Unavailable`    | The media processing service is temporarily unavailable.       |\n\n### Upload Authorization\n\nServers MAY require authorization when processing media as defined by [BUD-11](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95cnzuvmwmm#endpoint-authorization-requirements).\n\n## HEAD /media\n\nServers MAY implement `HEAD /media` as an optimization step before `PUT /media`.\nClients can use it to avoid uploading media that would be rejected, and servers can use it to evaluate whether a media-processing request would be accepted based on the supplied metadata and current server policy.\n\nThis pre-flight request is only an optimization. Clients MAY skip it entirely, and the result is not a guarantee of the eventual `PUT /media` outcome because server state may change between requests.\n\nThe `HEAD /media` endpoint MUST use the `X-SHA-256`, `X-Content-Type` and `X-Content-Length` headers sent by client to get the sha256 hash, MIME type and size of the media that will be uploaded, returning an HTTP status code and an optional custom header `X-Reason` to indicate a human readable message about the upload requirements. Because `HEAD` responses do not include a message body, clients MUST determine the result from the status code and response headers alone.\n\nServers SHOULD use the following status codes for `HEAD /media` responses:\n\n| Status Code                  | Meaning                                                     |\n| ---------------------------- | ----------------------------------------------------------- |\n| `200 OK`                     | Based on the supplied headers and current server policy, the media-processing request would be accepted and the client MAY proceed with `PUT /media`. |\n| `400 Bad Request`            | The request headers are malformed.                          |\n| `401 Unauthorized`           | Authorization is required and missing or invalid.           |\n| `402 Payment Required`       | Payment is required before the media-processing request can proceed. See [BUD-07](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95crwt8m678). |\n| `403 Forbidden`              | The request is understood but not allowed by server policy. |\n| `411 Length Required`        | A required `X-Content-Length` header is missing.            |\n| `413 Content Too Large`      | The media would exceed server size limits.                  |\n| `415 Unsupported Media Type` | The media type is not supported.                            |\n| `429 Too Many Requests`      | The client has exceeded a rate limit or quota.              |\n| `503 Service Unavailable`    | The media processing service is temporarily unavailable.    |\n\nIf included, `X-Reason` MUST be treated as a human readable diagnostic message only and clients MUST NOT parse it for control flow.\n\nClients that do not implement this optimization may still perform `PUT /media` directly, and servers MUST handle that correctly.\n\nAfter receiving `200 OK` from `HEAD /media`, clients MUST still be prepared for `PUT /media` to return either `200 OK` or `201 Created`, depending on how the media-processing result is handled by the server.\n\n## Limitations\n\nThe goal of this endpoint is to provide a simple \"trusted\" optimization endpoint clients can use to optimize media for distribution.\nHow the blob is optimized is the sole responsibility of the server and the client should have no say in what optimization process is used.\n\nIf a longer optimization or transformation process is needed, or if the client needs to specify how a blob should be transformed, other protocols should be used.\n\n## Client Implementation\n\nClients MAY let a user selected a \"trusted processing\" server for uploading images or short videos.\n\nOnce a server has been selected, the client uploads the original media to the `/media` endpoint of the trusted server and get the optimized blob back.\n\nThen the client can call the `/mirror` endpoint on other servers to distribute the blob.\n","sig":"9055f1f6a0708e9dfbd191e659c50772edeb2e75ada966bff7a68e54174ce58bdebdac6c0e4374991786d20b2ce62aef0460fce44ec53a56d782e5e90616e388"}