ProductsFor your stack

Image API

Every size and format, from one URL.

Upload the original once. Ask for any width, crop, format or pixel density in the URL, and Capa renders it at the edge and keeps it there for a year. Try it below.

hero.jpg · 3200 × 1984 original
An illustrated mountain landscape at dawn, used to show the transforms.
1,600 × 900 pxwebp1 year at the edge

https://cdn.capacms.com/files/brand/hero.jpg?dpr=2&fit=cover&format=webp&height=450&width=800

crop
fit
format
dpr
Smaller files

Five times lighter, one parameter later.

The same photo, measured. Asking for WebP at the width you show cuts the bytes your visitors download by more than three quarters.

  1. Source JPEG, no transformhero.jpg7,243 B
  2. JPEG, 400 px?width=4004,222 B
  3. AVIF, 400 px?format=avif&width=4001,740 B
  4. WebP, 400 px?format=webp&width=4001,380 B
  5. WebP at quality 50?format=webp&quality=50&width=400892 B

PNG is lossless: the same photo at 400 px is 216,943 bytes, which is why Capa never picks it for you. Measured on a 600 × 400 JPEG.

Parameters

Nine parameters. That is the whole API.

Every value is checked before anything runs. A value Capa cannot use is a 400 naming the parameter, never a silently ignored one.

ParameterValuesWhat it does
width1 to 4096Target width in pixels, before dpr.
height1 to 4096Target height in pixels, before dpr.
fitinside cover containKeep the ratio inside the box, fill it and crop, or fill it and pad.
dpr1 to 3Multiplies width and height. ?width=200&dpr=2 renders 400 px.
upscale0 1Images are never enlarged past their original unless you ask.
blur1 to 256A tiny blurred placeholder to draw under the real image.
formatwebp avif jpeg pngThe output format. Leave it out to keep the source format.
quality1 to 100Encoder quality for lossy formats. 80 when you leave it out.
keepMetadata0 1EXIF and color profiles are stripped unless you keep them.

The longest edge is capped at 4,096 pixels after dpr. A request past it is refused rather than clamped, so two URLs never hold the same bytes.

Details

The fiddly parts, handled.

  • Cache

    One URL per image

    Spell the same transform two ways and Capa redirects to one URL, keys sorted and defaults dropped, so each size is one object at the edge.

  • Orientation

    Turned the right way

    Phone photos are rotated from their EXIF tag before they are resized, so 400 px means 400 px of the picture as a person sees it.

  • Privacy

    Metadata stripped

    Location and camera data are removed by default. Keep them with keepMetadata=1 when a photographer needs them.

  • SVG

    Logos, safely

    An SVG served as is passes a strict allow-list first. Ask for a size or a format and Capa renders it to a sharp raster instead.

  • Purge

    Replace in place

    Replace a file in the media library and every size of it is purged at once, under the same URL.

  • Errors

    A transform is never a 500

    A file Capa cannot transform, like a PDF or a 30 MB original, is served as stored with a header saying why.

In your code

Responsive images without a pipeline.

  • One attribute for every screen

    List a few widths in srcset and the browser picks the one it needs. Each is rendered once and served from the edge after that.

  • Works with next/image

    A five-line loader hands Next.js the URL for each width it asks for, in the spelling the edge caches.

  • Blur-up for free

    Draw ?blur=24 under the real image: a tiny, blurred square with the right colors, on screen while the photo loads.

index.html
<img
  src="https://cdn.capacms.com/files/brand/hero.jpg?format=webp&width=800"
  srcset="https://cdn.capacms.com/files/brand/hero.jpg?format=webp&width=400 400w,
          https://cdn.capacms.com/files/brand/hero.jpg?format=webp&width=800 800w,
          https://cdn.capacms.com/files/brand/hero.jpg?format=webp&width=1600 1600w"
  sizes="(max-width: 720px) 100vw, 800px"
  alt="The harbour at dusk">

Upload once. Serve every size.

Every image in your media library already has an Image API URL. Add a width and see.