{"id":"5ed3461ea5c54b5c5b88dea29c8ad051a7ac0c2009f9e5d2ef3c6b7089151978","pubkey":"1336a17e161d0e8af2b68ee95ad2a479fc38bef96a17d6127ea02a40d28dd97e","created_at":1776353799,"kind":30817,"tags":[["d","bud-07"],["title","BUD-07: Paid upload and download"],["summary","How a server charges for an endpoint: a 402 response carrying the payment terms, for uploads, downloads or media processing."],["s","draft"],["t","blossom"],["t","bud"],["alt","A specification: BUD-07: Paid upload and download"],["client","openspecs-import"],["published_at","1725957694"],["proxy","https://github.com/hzrd149/blossom/blob/b5bd2801d1763aa635fc8fea7a76597e0eb18990/buds/07.md","web"],["x","d6285d72932c58ec992a9227c5d9814c6c6a507bf0006fc7696907c22fe50c3b"]],"content":"# BUD-07\n\n## Paid upload and download\n\n`draft` `optional`\n\nPayment requirements for blob storage.\n\n## Payment Required\n\nSome servers MAY require payment for uploads, downloads, or any other endpoint. In such cases, these endpoints MUST return a **402 Payment Required** status code.\n\nSome endpoints a server may require payment for:\n\n- [`HEAD /upload`](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95crvcz6ed2) to signal that payment is required for the `PUT` request ( if that optional endpoint is supported )\n- [`PUT /upload`](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95cryxk74nh#put-upload---upload-blob) to require payment for uploads\n- [`HEAD /<sha256>`](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95crz6eas0q#head-sha256---has-blob) to signal that payment is required for the `GET` request\n- [`GET /<sha256>`](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95crz6eas0q#get-sha256---get-blob) to require payment for downloads ( maybe charge by MB downloaded? )\n- [`HEAD /media`](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95cr2ydeu3a) and [`PUT /media`](nostr:naddr1qvzqqqrcvypzqyek59lpv8gw3tetdrhfttf2g70u8zl0j6sh6cf8agp2grfgmkt7qqrxyaty95cr2ydeu3a) to require payment for media optimizations ( if the optional `HEAD /media`-style preflight is supported )\n\nWhen payment is required, the server MUST include one or more `X-{payment_method}` header(s), each corresponding to a supported payment method.\n\n## Server headers\n\nThe 402 status code and `X-{payment_method}` header is used by the server to inform the client that a payment is required for the requested operation. The server MUST provide specific headers for each supported payment method.\n\nSupported payment methods:\n\n- `X-Cashu`: Payment details for the cashu payment method, adhering to the [NUT-24](nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595erguhqp2q) standard.\n- `X-Lightning`: Payment details for the lightning payment method, adhering to the [BOLT-11](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md) standard.\n\nIf a server supports multiple payment methods, it MAY send multiple `X-{payment_method}` headers in the same response.\n\nSchema:\n\n```http\nHTTP/1.1 402 Payment Required\nX-{payment_method}: \"<encoded_payload_according_to_{payment_method}_spec>\"\n```\n\n### `X-Cashu` Header\n\nWhen using the X-Cashu header, the server MUST adhere to the [NUT-24](nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595erguhqp2q) standard.\n\nExample for cashu:\n\n```http\nHTTP/1.1 402 Payment Required\nX-Cashu: creqApWF0gaNhdGVub3N0cmFheKlucHJvZmlsZTFxeTI4d3VtbjhnaGo3dW45ZDNzaGp0bnl2OWtoMnVld2Q5aHN6OW1od2RlbjV0ZTB3ZmprY2N0ZTljdXJ4dmVuOWVlaHFjdHJ2NWhzenJ0aHdkZW41dGUwZGVoaHh0bnZkYWtxcWd5ZGFxeTdjdXJrNDM5eWtwdGt5c3Y3dWRoZGh1NjhzdWNtMjk1YWtxZWZkZWhrZjBkNDk1Y3d1bmw1YWeBgmFuYjE3YWloYjdhOTAxNzZhYQphdWNzYXRhbYF4Imh0dHBzOi8vbm9mZWVzLnRlc3RudXQuY2FzaHUuc3BhY2U\n```\n\n### `X-Lightning` Header\n\nWhen using the X-Lightning header, the server MUST adhere to the [BOLT-11](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md) standard.\nExample for lightning:\n\n```http\nHTTP/1.1 402 Payment Required\nX-Lightning: lnbc30n1pnnmw3lpp57727jjq8zxctahfavqacymellq56l70f7lwfkmhxfjva6dgul2zqhp5w48l28v60yvythn6qvnpq0lez54422a042yaw4kq8arvd68a6n7qcqzzsxqyz5vqsp5sqezejdfaxx5hge83tf59a50h6gagwah59fjn9mw2d5mn278jkys9qxpqysgqt2q2lhjl9kgfaqz864mhlsspftzdyr642lf3zdt6ljqj6wmathdhtgcn0e6f4ym34jl0qkt6gwnllygvzkhdlpq64c6yv3rta2hyzlqp8k28pz\n```\n\n### Client implementation\n\nClients MUST parse and validate the `X-{payment_method}` header received from the server. The client SHOULD provide a way for the user to complete the payment and retry the request using the same `X-{payment_method}` header.\n\nThe client MUST provide the payment proof when re-trying the request using the same `X-{payment_method}` header that was chosen. The payment proof MUST align with the payment method specification:\n\n- For cashu the payment proof should be a serialized `cashuB` token in the `X-Cashu` header according to [NUT-24](nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595erguhqp2q#client-payment).\n- For lightning the payment proof should be the preimage of the payment request according to [BOLT-11](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md).\n\nSchema:\n\n```http\nX-{payment_method}: \"<encoded_payment_proof_according_to_{payment_method}_spec>\"\n```\n\nExample for Cashu:\n\n```http\nX-Cashu: cashuBo2F0gqJhaUgA_9SLj17PgGFwgaNhYQFhc3hAYWNjMTI0MzVlN2I4NDg0YzNjZjE4NTAxNDkyMThhZjkwZjcxNmE1MmJmNGE1ZWQzNDdlNDhlY2MxM2Y3NzM4OGFjWCECRFODGd5IXVW\n```\n\nExample for Lightning:\n\n```http\nX-Lightning: 966fcb8f153339372f9a187f725384ff4ceae0047c25b9ce607488d7c7e93bba\n```\n\n**Special Note on HEAD Requests**\n\nThe HEAD endpoints are only used to retrieve blob or server information. They MUST NOT be retried with payment proof. Instead, clients should complete the payment and proceed with the `PUT` or `GET` request.\n\n### Error handling\n\nIf the client fails to provide the payment proof (expired invoice, invalid token, etc.) the server MUST respond with **400 Bad request** status code and include a `X-Reason` header with a human-readable message. The client SHOULD inform the user about the error and provide a way to retry the request.\n\n### Extending with Future Payment Methods\n\nTo support future payment methods (e.g., other Layer 2 solutions), the specification allows the addition of new X-{payment_method} headers. Each new method MUST adhere to the following:\n\nNew methods MUST use a unique `X-{payment_method}` header containing the specific payment details.\n\nNew methods MUST adhere their own specification, which MUST be publicly available and linked in the header.\n","sig":"a54978c64e377a5b2138a31647719cc1f1d2a855688c4bdead59ac7d601d71dd2a168b7edbc4241c8b726fae9bedeaf75ad37629fab952a43044fb6829696b3b"}