Docs

The whole API is a URL

There is no SDK and no client library. You create a bucket that points at images you already host, then ask for a size by editing the URL. This page lists every parameter Sizy accepts and what it does when you leave one out.

The URL

https://sizy.io/your-bucket/path/to/image.jpg?width=800

your-bucket is the name you chose when you created the bucket. path/to/image.jpg is the path of the image relative to your source — Sizy appends it to the source URL exactly as written, so an image at https://cdn.example.com/photos/beach.jpg behind a bucket sourced at https://cdn.example.com is reached at /your-bucket/photos/beach.jpg.

Requests are plain GETs. There is no API key on the image URL — a bucket is a public front for a source you already serve publicly.

Creating a bucket

From /dashboard, create a bucket with two fields:

  • Name — the first path segment of every URL for this bucket. At least 3 characters, and unique across all of Sizy, so a common word may already be taken. Keep it to 30 characters or fewer: longer names can be saved but the image route will not resolve them. A name is not released when a bucket is deleted, so it cannot be reused later.
  • Source URL — the origin Sizy fetches from, for example https://cdn.example.com or an S3 website endpoint. A trailing slash is stripped for you. Anything the public internet can fetch over HTTP works; nothing is copied or migrated, and your originals stay where they are.

A bucket is live as soon as it is saved. Deleting a bucket stops its URLs from resolving.

Size

widthdefault: Source width

Whole number of pixels

Alias: w. They are the same parameter, and if you send both the short form wins — w=400&width=800 renders 400. Send one.

heightdefault: Source height

Whole number of pixels

Alias: h, with the same rule — h wins over height if both appear.

Give one dimension and the other is derived from the source aspect ratio. Give both and fit decides what happens to an image that does not match that shape.

Fit, crop and background

fitdefault: cover

cover · contain · fill · inside · outside

How the image is made to fit the box. cover crops to fill it, contain pads to fit inside it, fill stretches to it, inside and outside scale without cropping.

positiondefault: center

center · top · right top · right · right bottom · bottom · left bottom · left · left top, plus the compass names north, northeast, east, southeast, south, southwest, west, northwest

Where the crop is anchored when fit=cover discards part of the image. Multi-word values need URL encoding: position=left%20top.

gravitydefault: center

center · north · northeast · east · southeast · south · southwest · west · northwest

A compass-only alias for position, kept for compatibility. position is read first; gravity is used only when position is absent. Prefer position in new code.

backgrounddefault: Opaque black

Any CSS colour string, e.g. #ffffff, white, rgba(0,0,0,0.5)

The colour behind the image when fit=contain leaves empty space. An unrecognised colour fails the render and returns 500, so encode the # as %23.

Output format

formatdefault: Negotiated from the Accept header, else the source format

avif · webp · jpeg · png

Forces the output container. An explicit format always beats negotiation, so use it when you need a URL to return the same bytes to every client. Any other value returns 400.

withoutEnlargementdefault: false

true · 1 · yes · false · 0 · no, or the bare parameter

Never scale an image up past its source dimensions. Sending the parameter with no value — ?withoutEnlargement — reads as true.

fastShrinkOnLoaddefault: false

true · 1 · yes · false · 0 · no, or the bare parameter

Use the JPEG decoder’s shrink-on-load path for large downscales. Faster and cheaper in memory, at a small cost in quality.

By default you do not need any of these. Sizy reads the Accept header the browser already sends and serves AVIF where it is offered, then WebP, and the source format to everything else — which is usually the largest saving available on an image, often larger than the resize.

Each format is stored as its own object and every response carries Vary: Accept, so no cache between Sizy and your visitor can serve one browser’s AVIF to a browser that cannot decode it. It is still one billable transform per URL — you are not charged again because a visitor arrived in a different browser.

Two sources are never converted. An animated GIF would lose every frame but the first, and an SVG is vector — rasterising it is a different decision, not an optimisation.

How a request is handled

Resizing only happens when you ask for a size
If neither width nor height is present, fit, position, gravity and background have nothing to act on and the image is returned at its original dimensions.
The format is negotiated from the browser
Sizy reads the Accept header and serves AVIF to browsers that offer it, then WebP, and the source format to everything else. A client that sends only */* gets the source format — plenty of non-browser clients send it and cannot decode AVIF. Animated GIF and SVG are never converted. Set ?format= to opt out and pin a container.
One URL is one transform, whatever the format
The negotiated format decides which stored object answers a request, not which transform was performed. Each format is stored separately so a cache can never hand an AVIF to a browser that cannot decode it — and every response carries Vary: Accept so caches in between keep them apart — but you are billed once for the URL, not once per browser your visitors use.
Unrecognised parameters do not change the image
Anything not in the tables above is dropped before the image is identified, so a tracking parameter such as ?utm_source=newsletter will not create a second copy of the same image. Two exceptions are forwarded to your source rather than dropped — see below.
Some parameters are passed through to your source
v, x-id and the X-Amz-* signing parameters (X-Amz-Algorithm, X-Amz-Content-Sha256, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-Signature, X-Amz-SignedHeaders) are appended to the request Sizy makes to your source, so a bucket can point at a presigned S3 URL. They are forwarded but not part of what identifies the image, so a changing signature does not re-render anything.
The same URL always gives the same image
An image is identified by its bucket, its path and the parameters above. The first request for a combination renders it and stores the result; every later request that month is answered from that stored copy. The URL itself never changes, so it is safe to hard-code and share.
Stored copies are cleared at the end of each month
A rendered image is kept until the end of the calendar month it was rendered in — or for seven days, whichever is longer — and then removed. The next request for it renders it again, which counts as one more transform. A URL you serve every month therefore costs one transform per month, not one forever, and a URL nobody asks for again costs nothing after it is cleared. The seven-day floor means an image rendered on the last day of a month is not cleared the next morning.

Responses

307
Found

The normal response. Sizy redirects to a signed URL for the rendered image in its own storage. The signature is valid for 15 minutes, so follow the redirect rather than saving the target — browsers and image tags do this for you. Keep pointing at the sizy.io URL.

400
Invalid input parameters

A parameter was present but not accepted — a width that is not a number, a fit outside the five listed values, or a format outside avif, webp, jpeg and png. The body is a plain-text message naming the parameter.

404
Bucket not found

No active bucket with that name, or the name is one Sizy reserves for itself (see below).

Your origin’s
Source did not return the image

When the fetch from your source URL fails, Sizy answers with the status your origin gave — so a missing file at your origin surfaces as a 404 here, and a 403 stays a 403.

500
Error processing image

The source responded but the file could not be rendered — it is not an image Sharp understands, or a parameter such as background is not a colour.

Examples

A 400×300 thumbnail, cropped from the centre

https://sizy.io/your-bucket/photos/beach.jpg?width=400&height=300

The same box, but anchored to the top so faces survive the crop

https://sizy.io/your-bucket/photos/team.jpg?width=400&height=300&position=top

Fit the whole image inside the box and pad it with white

https://sizy.io/your-bucket/products/lamp.png?width=600&height=600&fit=contain&background=%23ffffff

Width only — height follows the source aspect ratio

https://sizy.io/your-bucket/photos/beach.jpg?w=1200

In an image tag, with a 2× source for retina screens

<img
  src="https://sizy.io/your-bucket/photos/beach.jpg?w=600"
  srcset="https://sizy.io/your-bucket/photos/beach.jpg?w=1200 2x"
  alt="Beach"
/>

Reserved bucket names

These names are used by the site itself and always return 404 as a bucket:

assetsavatarsimagesfilesfavicon.ico.well-knowndevpublic

What Sizy does not do yet

So that this page is the whole truth rather than the flattering part of it:

  • No quality parameter. Encoder quality is fixed. You can choose the container with format, but not how hard it is compressed.
  • No rotation, blur, sharpen or watermarking. The parameters above are the complete set.
  • No custom domains. Images are served from sizy.io.

What this costs

Every account gets 5,000 transforms free each month, and delivery is never billed at all. Beyond the allowance you pay for transforms and nothing else, with no monthly fee. See pricing, or compare it against the other image CDNs.

Your dashboard breaks both numbers down by month and by bucket.

Something here wrong, or a parameter you need missing? help@sizy.io.