For the complete documentation index, see llms.txt. This page is also available as Markdown.

Media Delivery

Render Amondo media at the right size on web, iOS and Android using delivery URL templates.

Overview

Every CloudinaryMedia object in the API exposes a delivery field with server-built URL templates for sized delivery. Instead of downloading the full-size publicUrl, substitute a width into a template and fetch a variant that matches the size you actually render. This gives smaller downloads, automatic format negotiation (WebP/AVIF for images, best codec for video) and automatic quality tuning.

media {
  publicUrl
  width
  height
  delivery {
    __typename
    ... on ImageDelivery {
      image { urlTemplate widths }
      avatar { urlTemplate widths }
    }
    ... on VideoDelivery {
      video { urlTemplate widths }
      poster { urlTemplate widths }
    }
  }
}

The field is available on both endpoints (gql.amondo.com and pub.amondo.com) wherever CloudinaryMedia appears — tile media, author avatars, form images, backgrounds and so on.

Template fields

delivery is a union: ImageDelivery for IMAGE media, VideoDelivery for VIDEO media. Switch on __typename.

Type
Field
Use for

ImageDelivery

image

Rendering the image at layout size

ImageDelivery

avatar

Small round author avatars (fixed widths 20, 30, 40, 60, 80)

VideoDelivery

video

Video playback at layout size

VideoDelivery

poster

JPG still of the first video frame — placeholder before playback

Each of these is a DeliveryTemplate:

Field
Type
Description

urlTemplate

String!

Absolute URL containing the literal token {w}

widths

[PositiveInt!]!

Valid substitutions for {w}, ascending

Example urlTemplate values:

Choosing a width

To build a URL:

  1. Take the width the media is rendered at, in layout units (CSS px, iOS points, Android dp).

  2. Multiply by the device pixel ratio, clamped to 2 — beyond 2× the extra pixels are not worth the bytes.

  3. Pick the smallest widths entry ≥ that product, or the largest entry if none is.

  4. Substitute it for the {w} token in urlTemplate.

Only the listed widths are supported — do not substitute arbitrary values.

The widths ladder runs in 100px steps and is capped at the source media width (rounded up to the next 100) and at 2000 — e.g. a 1080px-wide source yields [100, 200, …, 1100]. The ladder is per-media; always read it from the response.

Scaling and crop rules

Delivery URLs scale, they never crop. Every template uses c_limit:

  • Aspect ratio is always preserved. The returned file is the source scaled down so its width fits {w}; height follows the source aspect ratio.

  • Never upscaled. If {w} exceeds the source width you get the source size. Don't assume the returned file is exactly {w} pixels wide.

  • Never cropped server-side. Fitting media into a box of a different aspect ratio (a square grid cell, a 9:16 story) is always done by the renderer.

Tiles tell you which fit the editor chose. MediaTileAttributes (and the other tile attribute types) carry two TileCrop settings:

  • crop — how media displays in the grid: FILL crops to fill the cell, FIT letterboxes.

  • cropFrame — the same choice for the expanded frame view.

Map FILL/FIT to your platform's fit modes:

TileCrop

CSS

UIKit

SwiftUI

Android View

Jetpack Compose

FILL

object-fit: cover

.scaleAspectFill + clipsToBounds

.scaledToFill().clipped()

centerCrop

ContentScale.Crop

FIT

object-fit: contain

.scaleAspectFit

.scaledToFit()

fitCenter

ContentScale.Fit

Uploaded Cloudinary media is ingested with a maximum 4K resolution preset. Larger source uploads may be normalised at ingest before delivery templates are generated.

Web — CSS only

No JavaScript needed: expand the ladder into srcset and let the browser pick, then crop with object-fit.

Generate the srcset string directly from widths:

For background-image, use background-size: cover (FILL) or contain (FIT).

With srcset the browser applies the full device pixel ratio (3× on many phones) and may pick one ladder step higher than the clamp-to-2 rule would. Every listed width is valid, so this is fine. If you want the bandwidth-optimal 2× cap, select the width yourself with the JS helper above.

iOS

Select the width from the view's point size and screen scale, then let the image view crop:

UIKit:

SwiftUI:

Android

View widths are already in physical pixels; rescale them so densities above 2× don't fetch oversized files:

Views (with Coil or Glide):

Jetpack Compose:

Videos and posters

For VideoDelivery, pick widths for video and poster with the same algorithm, sized to the player:

  • Show the poster URL as the placeholder (<video poster="…">, AVPlayerLayer overlay, Compose placeholder) while the video loads. It is a JPG of the first frame at low quality — cheap and instant.

  • Feed the video URL to your player. Format and codec are negotiated automatically via f_auto.

Fallback

Code the delivery == null path from day one — it is not an edge case. Media served from Instagram's CDN, direct S3 objects and uploads that are still processing all return null. In that case render publicUrl unchanged (it may be full-size) with the same client-side FILL/FIT treatment.

Full example

Query a published imprint on pub.amondo.com (no auth) and render its media tiles:

Example media payload:

Rendering this tile in a 400 CSS px column on a 3× phone: target = 400 × min(3, 2) = 800 → pick w_800. The tile's crop is FILL, so the image gets object-fit: cover.

Last updated