Download an asset via signed capability URL (no session)
Differently-prefixed public route (NOT under /api/projects). Authorization is the HMAC signature in the query string; no session/role check. Two modes: assetId-based (email_assets row) or internal key-based (dynamic attachment R2 copy). Returns the binary file on success.
Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Expiry (ms epoch), bound into the signature.
HMAC signature.
Asset id (assetId mode). Mutually exclusive with key.
Internal R2 key (dynamic-attachment mode); requires filename + contentType.
Responses
Section titled “Responses”File bytes (Content-Disposition attachment).
Missing download parameters.
object
Human-readable error message.
Examplegenerated
{ "error": "example", "message": "example"}Invalid signature.
object
Human-readable error message.
Examplegenerated
{ "error": "example", "message": "example"}Asset/object not found, or R2 binding missing.
object
Human-readable error message.
Examplegenerated
{ "error": "example", "message": "example"}Download link expired.
object
Human-readable error message.
Examplegenerated
{ "error": "example", "message": "example"}EMAIL_ASSET_SIGNING_KEY not configured.
object
Human-readable error message.
Examplegenerated
{ "error": "example", "message": "example"}