feezy API
Image thumbnail service. Pass a source image URL (base64 encoded) and the wanted size; the thumbnail is rendered on the first request, stored and served from cache afterwards.
The v1 endpoints are compatible with the original feezy URLs; v2 adds CSS-like fit / position, padding to an exact size and background colours. v2 query parameters are accepted by v1 URLs as well.
Admin endpoints (sources, variants, stats) require Authorization: Bearer <token>.
https://feezy.euGet a thumbnail
Examples:
/api/v2/images/{source}.jpg?w=800&h=600&fit=scale-down&pad=true– never upscale, place the image on a white 800×600 canvas/api/v2/images/{source}.jpg?bg=eee– PNG with transparency converted to JPEG on a grey background, size unchanged/api/v2/images/{source}.webp?w=200&h=200&fit=cover&position=top– square crop keeping the top
/api/v2/images/{source}.{format}?w={w}&h={h}&fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}Path parameters
sourcestringrequiredSource image URL in URL-safe base64 (
-and_, padding optional). Standard base64 without/works as well.formatstring · enumrequired- jpgjpegpngwebpavifgifauto
Output format.
autoreturns WebP when the client sendsAccept: image/webp, otherwise JPEG (the response then hasVary: Accept). GIF and AVIF depend on the libvips build; unsupported formats return 400.
Query parameters
wintegerWidth in pixels. Missing or 0 = derived from the height (or the original size when both are missing).
hintegerHeight in pixels. Missing or 0 = derived from the width.
fitstring · enumdefault: contain- containscale-downcoverfill
How the image fits the box, as CSS
object-fit:contain– fit inside, may upscale;scale-down– fit inside, never upscale;cover– fill the box and crop;fill– stretch.coverandfillneed bothwandh. positionstring · enumdefault: center- centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
As CSS
object-position: which partcoverkeeps, or where a padded image is placed.smart(cover only) keeps the most interesting part. padbooleandefault: falseOutput exactly
w×hand fill the empty area withbg. Only withcontain/scale-downand both dimensions.bgstringBackground colour for transparent areas (e.g. PNG → JPEG) and padding:
fff,ffffff,ffffff80ortransparent. Default: white for JPEG, transparent for other formats.qintegerQuality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).
vstringVersion for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.
Responses
- 200image/jpeg, image/png, image/webp, image/avif, image/gif
The thumbnail
- 304
The thumbnail did not change (If-None-Match matched)
- 400application/json
Invalid parameters
- 403application/json
Source not allowed: not http(s), host not on the allowlist, or not a public address
- 404application/json
Source image not found (404/410 from its server)
- 413application/json
Source file or pixel count over the limit
- 415application/json
Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)
- 422application/json
Image processing failed
- 429application/json
Too many new thumbnails from this client; cached thumbnails are not limited
- 502application/json
Downloading the source failed
- 503application/json
Server busy
curl "https://feezy.eu/api/v2/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY.{format}" \
-o resultGet a thumbnail with a file name
Same as /api/v2/images/{source}.{format}; the file name is only used for Content-Disposition and does not affect caching. Its extension sets the output format.
/api/v2/images/{source}/{filename}?w={w}&h={h}&fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}Path parameters
sourcestringrequiredSource image URL in URL-safe base64 (
-and_, padding optional). Standard base64 without/works as well.filenamestringrequiredFile name with extension: jpg, jpeg, png, webp, avif, gif or auto.
Query parameters
wintegerWidth in pixels. Missing or 0 = derived from the height (or the original size when both are missing).
hintegerHeight in pixels. Missing or 0 = derived from the width.
fitstring · enumdefault: contain- containscale-downcoverfill
How the image fits the box, as CSS
object-fit:contain– fit inside, may upscale;scale-down– fit inside, never upscale;cover– fill the box and crop;fill– stretch.coverandfillneed bothwandh. positionstring · enumdefault: center- centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
As CSS
object-position: which partcoverkeeps, or where a padded image is placed.smart(cover only) keeps the most interesting part. padbooleandefault: falseOutput exactly
w×hand fill the empty area withbg. Only withcontain/scale-downand both dimensions.bgstringBackground colour for transparent areas (e.g. PNG → JPEG) and padding:
fff,ffffff,ffffff80ortransparent. Default: white for JPEG, transparent for other formats.qintegerQuality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).
vstringVersion for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.
Responses
- 200image/jpeg, image/png, image/webp, image/avif, image/gif
The thumbnail
- 304
The thumbnail did not change (If-None-Match matched)
- 400application/json
Invalid parameters
- 403application/json
Source not allowed: not http(s), host not on the allowlist, or not a public address
- 404application/json
Source image not found (404/410 from its server)
- 413application/json
Source file or pixel count over the limit
- 415application/json
Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)
- 422application/json
Image processing failed
- 429application/json
Too many new thumbnails from this client; cached thumbnails are not limited
- 502application/json
Downloading the source failed
- 503application/json
Server busy
curl "https://feezy.eu/api/v2/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY/{filename}" \
-o resultGet a thumbnail (v1)
Legacy URL. Behaves like fit=contain; the output format is taken from the source URL's extension (JPEG if it has none). v2 query parameters override the defaults.
/api/v1/images/{source}/{width}/{height}?fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}Path parameters
sourcestringrequiredSource image URL in base64 (standard or URL-safe, padding optional). URLs whose standard base64 contains
/must use the URL-safe form.widthintegerrequiredheightintegerrequired
Query parameters
fitstring · enum- containscale-downcoverfill10
How the image fits the box, as CSS
object-fit:contain– fit inside, may upscale;scale-down– fit inside, never upscale;cover– fill the box and crop;fill– stretch.coverandfillneed bothwandh. v1 also accepts the PHP version's boolean form:1keeps the path default (with{background}the image is padded to the box),0with{background}resizes without padding (contain); without{background}the boolean has no effect. positionstring · enumdefault: center- centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
As CSS
object-position: which partcoverkeeps, or where a padded image is placed.smart(cover only) keeps the most interesting part. padbooleandefault: falseOutput exactly
w×hand fill the empty area withbg. Only withcontain/scale-downand both dimensions.bgstringBackground colour for transparent areas (e.g. PNG → JPEG) and padding:
fff,ffffff,ffffff80ortransparent. Default: white for JPEG, transparent for other formats.qintegerQuality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).
vstringVersion for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.
Responses
- 200image/jpeg, image/png, image/webp, image/avif, image/gif
The thumbnail
- 304
The thumbnail did not change (If-None-Match matched)
- 400application/json
Invalid parameters
- 403application/json
Source not allowed: not http(s), host not on the allowlist, or not a public address
- 404application/json
Source image not found (404/410 from its server)
- 413application/json
Source file or pixel count over the limit
- 415application/json
Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)
- 422application/json
Image processing failed
- 429application/json
Too many new thumbnails from this client; cached thumbnails are not limited
- 502application/json
Downloading the source failed
- 503application/json
Server busy
curl "https://feezy.eu/api/v1/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY=/200/200" \
-o resultGet a thumbnail with a file name or a background (v1)
The last segment is a file name if it contains a dot (new-image.jpg, the extension sets the format), otherwise a background colour (fff, ff0088). With a background colour the image is never upscaled and is padded to exactly width×height (fit=scale-down&pad=true&bg=...). v2 query parameters override the defaults.
/api/v1/images/{source}/{width}/{height}/{nameOrBackground}?fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}Path parameters
sourcestringrequiredSource image URL in base64 (standard or URL-safe, padding optional). URLs whose standard base64 contains
/must use the URL-safe form.widthintegerrequiredheightintegerrequirednameOrBackgroundstringrequired
Query parameters
fitstring · enum- containscale-downcoverfill10
How the image fits the box, as CSS
object-fit:contain– fit inside, may upscale;scale-down– fit inside, never upscale;cover– fill the box and crop;fill– stretch.coverandfillneed bothwandh. v1 also accepts the PHP version's boolean form:1keeps the path default (with{background}the image is padded to the box),0with{background}resizes without padding (contain); without{background}the boolean has no effect. positionstring · enumdefault: center- centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
As CSS
object-position: which partcoverkeeps, or where a padded image is placed.smart(cover only) keeps the most interesting part. padbooleandefault: falseOutput exactly
w×hand fill the empty area withbg. Only withcontain/scale-downand both dimensions.bgstringBackground colour for transparent areas (e.g. PNG → JPEG) and padding:
fff,ffffff,ffffff80ortransparent. Default: white for JPEG, transparent for other formats.qintegerQuality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).
vstringVersion for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.
Responses
- 200image/jpeg, image/png, image/webp, image/avif, image/gif
The thumbnail
- 304
The thumbnail did not change (If-None-Match matched)
- 400application/json
Invalid parameters
- 403application/json
Source not allowed: not http(s), host not on the allowlist, or not a public address
- 404application/json
Source image not found (404/410 from its server)
- 413application/json
Source file or pixel count over the limit
- 415application/json
Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)
- 422application/json
Image processing failed
- 429application/json
Too many new thumbnails from this client; cached thumbnails are not limited
- 502application/json
Downloading the source failed
- 503application/json
Server busy
curl "https://feezy.eu/api/v1/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY=/200/200/{nameOrBackground}" \
-o resultGet a thumbnail on a background (v1)
Never upscales and pads to exactly width×height with the background colour (fit=scale-down&pad=true). v2 query parameters override the defaults, e.g. ?position=left.
/api/v1/images/{source}/{width}/{height}/{background}/{name}?fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}Path parameters
sourcestringrequiredSource image URL in base64 (standard or URL-safe, padding optional). URLs whose standard base64 contains
/must use the URL-safe form.widthintegerrequiredheightintegerrequiredbackgroundstringrequiredHex colour:
fff,fffffforffffff80.namestringrequiredFile name; its extension sets the output format.
Query parameters
fitstring · enum- containscale-downcoverfill10
How the image fits the box, as CSS
object-fit:contain– fit inside, may upscale;scale-down– fit inside, never upscale;cover– fill the box and crop;fill– stretch.coverandfillneed bothwandh. v1 also accepts the PHP version's boolean form:1keeps the path default (with{background}the image is padded to the box),0with{background}resizes without padding (contain); without{background}the boolean has no effect. positionstring · enumdefault: center- centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
As CSS
object-position: which partcoverkeeps, or where a padded image is placed.smart(cover only) keeps the most interesting part. padbooleandefault: falseOutput exactly
w×hand fill the empty area withbg. Only withcontain/scale-downand both dimensions.bgstringBackground colour for transparent areas (e.g. PNG → JPEG) and padding:
fff,ffffff,ffffff80ortransparent. Default: white for JPEG, transparent for other formats.qintegerQuality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).
vstringVersion for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.
Responses
- 200image/jpeg, image/png, image/webp, image/avif, image/gif
The thumbnail
- 304
The thumbnail did not change (If-None-Match matched)
- 400application/json
Invalid parameters
- 403application/json
Source not allowed: not http(s), host not on the allowlist, or not a public address
- 404application/json
Source image not found (404/410 from its server)
- 413application/json
Source file or pixel count over the limit
- 415application/json
Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)
- 422application/json
Image processing failed
- 429application/json
Too many new thumbnails from this client; cached thumbnails are not limited
- 502application/json
Downloading the source failed
- 503application/json
Server busy
curl "https://feezy.eu/api/v1/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY=/200/200/{background}/{name}" \
-o resultEncode a source URL for v2
Returns the URL-safe base64 (no padding) used in v2 URLs. In JavaScript: btoa(url).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '').
/api/v2/url/encode?url={url}Query parameters
urlstringrequired
Responses
- 200text/plain
Encoded URL
curl "https://feezy.eu/api/v2/url/encode?url=https://dummyimage.com/600x400/000/fff" \
-o resultEncode a source URL for v1
Returns the standard base64 of the URL (v1 compatible).
/api/v1/url/hash?url={url}Query parameters
urlstringrequired
Responses
- 200text/plain
Encoded URL
curl "https://feezy.eu/api/v1/url/hash?url=https://dummyimage.com/600x400/000/fff" \
-o resultHealth check
/healthzResponses
- 200text/plain
Service is running
curl "https://feezy.eu/healthz" \
-o result