Generated renders (thumbnails, sizes, crops) are served in one of two modes. The mode is an operator setting; as an API client you consume whatever render URLs the API hands you — both shapes always work.

## direct (default)

Render URLs point straight at the public bucket or its custom domain, e.g.

```
https://img.peinture.gumeniuk.com/r/{id}/{crop}.{ext}?v={spec_version}
```

The app is not in the data path — the CDN/bucket serves the bytes.

## proxy

Render URLs point back at the app, which streams the bytes from the public store:

```
https://peinture.gumeniuk.com/i/{id}/{crop}.{ext}
```

The `GET /i/{id}/{file}` route always exists, even in direct mode, as a fallback. It serves only public renders — never originals.

## Cache-busting

Every render URL carries a `?v={spec_version}` query parameter. When an image is regenerated (new preset set, or [`image.regenerate`](/docs/methods/image.regenerate)), the version changes, so a browser or CDN never serves a stale render under the same URL.

You do not choose the mode per request; [`image.get`](/docs/methods/image.get) and [`image.list`](/docs/methods/image.list) return URLs already in the active shape.
