Skip to content

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.

exp
required
integer

Expiry (ms epoch), bound into the signature.

sig
required
string

HMAC signature.

assetId
string

Asset id (assetId mode). Mutually exclusive with key.

key
string

Internal R2 key (dynamic-attachment mode); requires filename + contentType.

filename
string
contentType
string

File bytes (Content-Disposition attachment).

Media typeapplication/octet-stream
string format: binary

Missing download parameters.

Media typeapplication/json
object
error
required

Human-readable error message.

string
message
string
Examplegenerated
json
{
"error": "example",
"message": "example"
}

Invalid signature.

Media typeapplication/json
object
error
required

Human-readable error message.

string
message
string
Examplegenerated
json
{
"error": "example",
"message": "example"
}

Asset/object not found, or R2 binding missing.

Media typeapplication/json
object
error
required

Human-readable error message.

string
message
string
Examplegenerated
json
{
"error": "example",
"message": "example"
}

Download link expired.

Media typeapplication/json
object
error
required

Human-readable error message.

string
message
string
Examplegenerated
json
{
"error": "example",
"message": "example"
}

EMAIL_ASSET_SIGNING_KEY not configured.

Media typeapplication/json
object
error
required

Human-readable error message.

string
message
string
Examplegenerated
json
{
"error": "example",
"message": "example"
}