Image Delivery API
These endpoints synchronously return processed images or existing media objects and are suitable for browsers, CDNs, and upstream applications.
For the complete definitions of BASE_URL and HMAC_SECRET used by the signing examples below, see Configuration.
Endpoint overview
| Endpoint | Purpose | Auth | Backing bucket |
|---|---|---|---|
GET /img/{sig}/{opts}/{encoded_source}.{format} | transform an image on demand and cache the result | HMAC-signed URL | reads source bucket, writes image cache into media bucket |
GET /original/{sig}/{encoded_key} | proxy the original object | HMAC-signed URL | source bucket |
GET /thumb/{sig}/{encoded_key} | proxy an existing thumbnail or cover | HMAC-signed URL | media bucket |
GET /img/{sig}/{opts}/{encoded_source}.{format}
Path shape
/img/{sig}/{opts}/{encoded_source}.{format}
Examples:
/img/<sig>/w640_h360_q80/uploads%2Favatars%2Fsample.jpg.webp
/img/<sig>/w1200/uploads%2Fproducts%2Fhero.png.avif
Parameter semantics
| Segment | Meaning |
|---|---|
sig | hex-encoded HMAC-SHA256 signature |
opts | image options such as w640_h360_q80 |
encoded_source | URL-escaped source object key |
format | output format: webp, avif, jpg, png, or gif |
Canonicalization rules
Vylux signs a canonical form, not the raw browser URL string:
optsare normalized intow -> h -> qorderencoded_sourceis decoded before signingjpegis normalized tojpg
Conceptually, the signature input is:
{canonical_options}/{decoded_source_key}.{canonical_format}
shell signing and curl example
BASE_URL='http://localhost:3000'
HMAC_SECRET='replace-with-hmac-secret'
OPTIONS='w640_h360_q80'
ENCODED_SOURCE='uploads%2Favatars%2Fsample.jpg.webp'
CANONICAL_SOURCE='uploads/avatars/sample.jpg.webp'
SIG="$(printf '%s/%s' "$OPTIONS" "$CANONICAL_SOURCE" \
| openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex \
| sed 's/^.* //')"
curl -L "$BASE_URL/img/$SIG/$OPTIONS/$ENCODED_SOURCE"
Successful response behavior
200 OKContent-Typematches the output formatCache-Control: public, max-age=31536000, immutableETagderived from the returned bytes
Failure semantics
| Status | Meaning |
|---|---|
400 | invalid options, invalid source encoding, or unsupported output format |
403 | invalid signature |
404 | source object not found |
422 | source exists but cannot be processed |
502 | source storage temporarily unavailable |
500 | internal processing failure |
GET /original/{sig}/{encoded_key}
This endpoint proxies original objects from the source bucket without transforming them.
shell signing and curl example
BASE_URL='http://localhost:3000'
HMAC_SECRET='replace-with-hmac-secret'
ENCODED_KEY='uploads%2Fsample.mp4'
CANONICAL_KEY='uploads/sample.mp4'
SIG="$(printf '/%s' "$CANONICAL_KEY" \
| openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex \
| sed 's/^.* //')"
curl -L "$BASE_URL/original/$SIG/$ENCODED_KEY"
Behavior notes
- validates the HMAC before touching storage
- infers
Content-Typefrom extension first, then falls back to content sniffing - returns
404when the object does not exist
GET /thumb/{sig}/{encoded_key}
This endpoint proxies existing thumbnails, video covers, or other static media objects from the media bucket.
shell signing and curl example
BASE_URL='http://localhost:3000'
HMAC_SECRET='replace-with-hmac-secret'
ENCODED_KEY='videos%2Fab%2Fabcdef%2Fcover.jpg'
CANONICAL_KEY='videos/ab/abcdef/cover.jpg'
SIG="$(printf 'thumb/%s' "$CANONICAL_KEY" \
| openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex \
| sed 's/^.* //')"
curl -L "$BASE_URL/thumb/$SIG/$ENCODED_KEY"
Behavior notes
- the
thumb/signing domain prevents signature reuse across/thumband/original - successful responses include
Access-Control-Allow-Origin: *
Practical guidance
- never expose
HMAC_SECRETto browsers or public clients - generate signed URLs in your upstream application or auth service
- rely on stable object keys or content hashes so CDN caching stays predictable
Where the signer should live
In most deployments, the /img, /original, and /thumb signer should live in one of these trusted places:
- your main application backend
- a dedicated internal signing service
- a trusted edge worker that can safely read
HMAC_SECRET
The usual request flow is:
- the user asks your application for an image or asset
- your application checks whether that user may access the media record
- your application signs the Vylux URL server-side
- your application returns the final signed URL to the browser
That means browsers should receive only the final URL, never the secret and never the unsigned path.
If you are exposing generated covers, previews, or thumbnails from job results, convert the returned media-bucket key into a signed /thumb URL at that same trusted layer.