v2.0.0OpenAPI 3.0.3

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>.

Base URLhttps://feezy.eu
images

Get 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
GET/api/v2/images/{source}.{format}?w={w}&h={h}&fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}

Path parameters

sourcestringrequired

Source image URL in URL-safe base64 (- and _, padding optional). Standard base64 without / works as well.

formatstring · enumrequired

Output format. auto returns WebP when the client sends Accept: image/webp, otherwise JPEG (the response then has Vary: Accept). GIF and AVIF depend on the libvips build; unsupported formats return 400.

jpgjpegpngwebpavifgifauto

Query parameters

winteger

Width in pixels. Missing or 0 = derived from the height (or the original size when both are missing).

hinteger

Height in pixels. Missing or 0 = derived from the width.

fitstring · enumdefault: contain

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. cover and fill need both w and h.

containscale-downcoverfill
positionstring · enumdefault: center

As CSS object-position: which part cover keeps, or where a padded image is placed. smart (cover only) keeps the most interesting part.

centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
padbooleandefault: false

Output exactly w×h and fill the empty area with bg. Only with contain / scale-down and both dimensions.

bgstring

Background colour for transparent areas (e.g. PNG → JPEG) and padding: fff, ffffff, ffffff80 or transparent. Default: white for JPEG, transparent for other formats.

qinteger

Quality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).

vstring

Version for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.

Responses

  • 200

    The thumbnail

    image/jpeg, image/png, image/webp, image/avif, image/gif
  • 304

    The thumbnail did not change (If-None-Match matched)

  • 400

    Invalid parameters

    application/json
  • 403

    Source not allowed: not http(s), host not on the allowlist, or not a public address

    application/json
  • 404

    Source image not found (404/410 from its server)

    application/json
  • 413

    Source file or pixel count over the limit

    application/json
  • 415

    Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)

    application/json
  • 422

    Image processing failed

    application/json
  • 429

    Too many new thumbnails from this client; cached thumbnails are not limited

    application/json
  • 502

    Downloading the source failed

    application/json
  • 503

    Server busy

    application/json
curl "https://feezy.eu/api/v2/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY.{format}" \
  -o result
images

Get 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.

GET/api/v2/images/{source}/{filename}?w={w}&h={h}&fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}

Path parameters

sourcestringrequired

Source image URL in URL-safe base64 (- and _, padding optional). Standard base64 without / works as well.

filenamestringrequired

File name with extension: jpg, jpeg, png, webp, avif, gif or auto.

Query parameters

winteger

Width in pixels. Missing or 0 = derived from the height (or the original size when both are missing).

hinteger

Height in pixels. Missing or 0 = derived from the width.

fitstring · enumdefault: contain

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. cover and fill need both w and h.

containscale-downcoverfill
positionstring · enumdefault: center

As CSS object-position: which part cover keeps, or where a padded image is placed. smart (cover only) keeps the most interesting part.

centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
padbooleandefault: false

Output exactly w×h and fill the empty area with bg. Only with contain / scale-down and both dimensions.

bgstring

Background colour for transparent areas (e.g. PNG → JPEG) and padding: fff, ffffff, ffffff80 or transparent. Default: white for JPEG, transparent for other formats.

qinteger

Quality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).

vstring

Version for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.

Responses

  • 200

    The thumbnail

    image/jpeg, image/png, image/webp, image/avif, image/gif
  • 304

    The thumbnail did not change (If-None-Match matched)

  • 400

    Invalid parameters

    application/json
  • 403

    Source not allowed: not http(s), host not on the allowlist, or not a public address

    application/json
  • 404

    Source image not found (404/410 from its server)

    application/json
  • 413

    Source file or pixel count over the limit

    application/json
  • 415

    Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)

    application/json
  • 422

    Image processing failed

    application/json
  • 429

    Too many new thumbnails from this client; cached thumbnails are not limited

    application/json
  • 502

    Downloading the source failed

    application/json
  • 503

    Server busy

    application/json
curl "https://feezy.eu/api/v2/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY/{filename}" \
  -o result
images

Get 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.

GET/api/v1/images/{source}/{width}/{height}?fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}

Path parameters

sourcestringrequired

Source image URL in base64 (standard or URL-safe, padding optional). URLs whose standard base64 contains / must use the URL-safe form.

widthintegerrequired

heightintegerrequired

Query parameters

fitstring · enum

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. cover and fill need both w and h. v1 also accepts the PHP version's boolean form: 1 keeps the path default (with {background} the image is padded to the box), 0 with {background} resizes without padding (contain); without {background} the boolean has no effect.

containscale-downcoverfill10
positionstring · enumdefault: center

As CSS object-position: which part cover keeps, or where a padded image is placed. smart (cover only) keeps the most interesting part.

centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
padbooleandefault: false

Output exactly w×h and fill the empty area with bg. Only with contain / scale-down and both dimensions.

bgstring

Background colour for transparent areas (e.g. PNG → JPEG) and padding: fff, ffffff, ffffff80 or transparent. Default: white for JPEG, transparent for other formats.

qinteger

Quality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).

vstring

Version for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.

Responses

  • 200

    The thumbnail

    image/jpeg, image/png, image/webp, image/avif, image/gif
  • 304

    The thumbnail did not change (If-None-Match matched)

  • 400

    Invalid parameters

    application/json
  • 403

    Source not allowed: not http(s), host not on the allowlist, or not a public address

    application/json
  • 404

    Source image not found (404/410 from its server)

    application/json
  • 413

    Source file or pixel count over the limit

    application/json
  • 415

    Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)

    application/json
  • 422

    Image processing failed

    application/json
  • 429

    Too many new thumbnails from this client; cached thumbnails are not limited

    application/json
  • 502

    Downloading the source failed

    application/json
  • 503

    Server busy

    application/json
curl "https://feezy.eu/api/v1/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY=/200/200" \
  -o result
images

Get 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.

GET/api/v1/images/{source}/{width}/{height}/{nameOrBackground}?fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}

Path parameters

sourcestringrequired

Source image URL in base64 (standard or URL-safe, padding optional). URLs whose standard base64 contains / must use the URL-safe form.

widthintegerrequired

heightintegerrequired

nameOrBackgroundstringrequired

Query parameters

fitstring · enum

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. cover and fill need both w and h. v1 also accepts the PHP version's boolean form: 1 keeps the path default (with {background} the image is padded to the box), 0 with {background} resizes without padding (contain); without {background} the boolean has no effect.

containscale-downcoverfill10
positionstring · enumdefault: center

As CSS object-position: which part cover keeps, or where a padded image is placed. smart (cover only) keeps the most interesting part.

centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
padbooleandefault: false

Output exactly w×h and fill the empty area with bg. Only with contain / scale-down and both dimensions.

bgstring

Background colour for transparent areas (e.g. PNG → JPEG) and padding: fff, ffffff, ffffff80 or transparent. Default: white for JPEG, transparent for other formats.

qinteger

Quality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).

vstring

Version for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.

Responses

  • 200

    The thumbnail

    image/jpeg, image/png, image/webp, image/avif, image/gif
  • 304

    The thumbnail did not change (If-None-Match matched)

  • 400

    Invalid parameters

    application/json
  • 403

    Source not allowed: not http(s), host not on the allowlist, or not a public address

    application/json
  • 404

    Source image not found (404/410 from its server)

    application/json
  • 413

    Source file or pixel count over the limit

    application/json
  • 415

    Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)

    application/json
  • 422

    Image processing failed

    application/json
  • 429

    Too many new thumbnails from this client; cached thumbnails are not limited

    application/json
  • 502

    Downloading the source failed

    application/json
  • 503

    Server busy

    application/json
curl "https://feezy.eu/api/v1/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY=/200/200/{nameOrBackground}" \
  -o result
images

Get 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.

GET/api/v1/images/{source}/{width}/{height}/{background}/{name}?fit={fit}&position={position}&pad={pad}&bg={bg}&q={q}&v={v}

Path parameters

sourcestringrequired

Source image URL in base64 (standard or URL-safe, padding optional). URLs whose standard base64 contains / must use the URL-safe form.

widthintegerrequired

heightintegerrequired

backgroundstringrequired

Hex colour: fff, ffffff or ffffff80.

namestringrequired

File name; its extension sets the output format.

Query parameters

fitstring · enum

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. cover and fill need both w and h. v1 also accepts the PHP version's boolean form: 1 keeps the path default (with {background} the image is padded to the box), 0 with {background} resizes without padding (contain); without {background} the boolean has no effect.

containscale-downcoverfill10
positionstring · enumdefault: center

As CSS object-position: which part cover keeps, or where a padded image is placed. smart (cover only) keeps the most interesting part.

centertopbottomleftrighttop-lefttop-rightbottom-leftbottom-rightsmart
padbooleandefault: false

Output exactly w×h and fill the empty area with bg. Only with contain / scale-down and both dimensions.

bgstring

Background colour for transparent areas (e.g. PNG → JPEG) and padding: fff, ffffff, ffffff80 or transparent. Default: white for JPEG, transparent for other formats.

qinteger

Quality 1–100 (JPEG default 82, WebP 80, AVIF 55; ignored for PNG and GIF).

vstring

Version for cache busting, e.g. the source's modification time. A new value renders a new thumbnail.

Responses

  • 200

    The thumbnail

    image/jpeg, image/png, image/webp, image/avif, image/gif
  • 304

    The thumbnail did not change (If-None-Match matched)

  • 400

    Invalid parameters

    application/json
  • 403

    Source not allowed: not http(s), host not on the allowlist, or not a public address

    application/json
  • 404

    Source image not found (404/410 from its server)

    application/json
  • 413

    Source file or pixel count over the limit

    application/json
  • 415

    Source is not a supported image (JPEG, PNG, GIF, WebP, TIFF, HEIF, AVIF)

    application/json
  • 422

    Image processing failed

    application/json
  • 429

    Too many new thumbnails from this client; cached thumbnails are not limited

    application/json
  • 502

    Downloading the source failed

    application/json
  • 503

    Server busy

    application/json
curl "https://feezy.eu/api/v1/images/aHR0cHM6Ly9kdW1teWltYWdlLmNvbS82MDB4NDAwLzAwMC9mZmY=/200/200/{background}/{name}" \
  -o result
helpers

Encode 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(/=+$/, '').

GET/api/v2/url/encode?url={url}

Query parameters

urlstringrequired

Responses

  • 200

    Encoded URL

    text/plain
curl "https://feezy.eu/api/v2/url/encode?url=https://dummyimage.com/600x400/000/fff" \
  -o result
helpers

Encode a source URL for v1

Returns the standard base64 of the URL (v1 compatible).

GET/api/v1/url/hash?url={url}

Query parameters

urlstringrequired

Responses

  • 200

    Encoded URL

    text/plain
curl "https://feezy.eu/api/v1/url/hash?url=https://dummyimage.com/600x400/000/fff" \
  -o result
system

Health check

GET/healthz

Responses

  • 200

    Service is running

    text/plain
curl "https://feezy.eu/healthz" \
  -o result