
# Format & Quality

A stored JPEG does not have to leave as a JPEG. The same download URL that [resizes](/en/docs/image-transforms) can also transcode, and by default it does so on its own — a modern browser gets AVIF from a PNG original without anyone asking.

## Explicit Format

```http
GET /api/buckets/photos/files/{key}?format=webp
```

| Value    | Output       | Use it for                                            |
| -------- | ------------ | ----------------------------------------------------- |
| `avif`   | `image/avif` | Smallest payload. Broad but not universal support.    |
| `webp`   | `image/webp` | Strong compression, effectively universal today.      |
| `jpeg`   | `image/jpeg` | Photos where nothing may be assumed about the client. |
| `png`    | `image/png`  | Transparency and lossless output.                     |
| `origin` | source       | Opt out of transcoding for this request.              |

The response `Content-Type` always reflects what was actually produced. An unrecognised value — `bmp`, `tiff` — answers `400`.

## Automatic Negotiation

Omit `format` and the server reads the request's `Accept` header:

```http
GET /api/buckets/photos/files/{key}
Accept: image/avif,image/webp,image/*
```

| `Accept` contains | Output                        |
| ----------------- | ----------------------------- |
| `image/avif`      | AVIF                          |
| `image/webp`      | WebP                          |
| Neither           | The original bytes, untouched |

AVIF wins over WebP when both are offered. This is why an ordinary `<img src>` with no query string still gets a modern format in a modern browser and the untouched original in an old one — no `<picture>` element, no `srcset` juggling, no server-side user-agent sniffing.

`format=origin` is the way to bypass negotiation deliberately: use it when a downstream consumer needs the exact stored bytes, or when you are debugging what was actually uploaded.

:::callout
**`ECO_IMAGE_FORMAT` does not govern this route.** That env var sets the default output of the `file.transformImage` automation action. URL transforms negotiate from `Accept` and honour an explicit `format` — nothing else. Setting `ECO_IMAGE_FORMAT=jpeg` will not stop a browser advertising AVIF from receiving AVIF here.
:::

## Quality

```http
GET /api/buckets/photos/files/{key}?quality=95
GET /api/buckets/photos/files/{key}?width=100&quality=30
```

| Behaviour                         | Detail                           |
| --------------------------------- | -------------------------------- |
| Accepted range                    | Integer, 1 to 100 inclusive.     |
| Default                           | `80` when omitted.               |
| Applies to                        | Lossy output — JPEG, WebP, AVIF. |
| Ignored for                       | PNG, which is lossless.          |
| Outside the range, or non-integer | `400`                            |

Eighty is not a placeholder — it is close to the point where further quality stops being visible and starts only being bytes. Raising it to 95 can double the payload for a difference most viewers will not see on most images.

The pairing worth remembering is `width` with a low `quality`. A 100-pixel-wide thumbnail at `quality=30` is a fraction of a full-quality one and looks identical at that size, because compression artefacts are themselves scaled away. Reserve high quality for images that will be viewed large.

## Choosing in Practice

Three defaults that cover almost every case:

- **Content images in a page** — no `format` at all. Let negotiation do it; you get AVIF where it helps and correctness everywhere else.
- **Thumbnails and avatars** — `?width=…&quality=60`. The size does the work; quality is nearly free to lower.
- **Downloads a user asked for** — `?format=origin`. Someone clicking "download original" means it.

## Related Pages

- [Resize & Crop](/en/docs/image-transforms) — dimensions, fit modes, crop strategies.
- [Presets & Caching](/en/docs/image-presets-caching) — bundling these parameters under a name.
- [File Operations](/en/docs/file-operations) — the endpoint being decorated.
- [Ecoconception](/en/docs/ecoconception) — where `ECO_IMAGE_FORMAT` does apply.
- [Environment Variables: Services](/en/docs/env-vars-services) — the `ECO_*` reference.
