Nike and adidas serve product photos from Cloudinary on their own domains, static.nike.com and assets.adidas.com. Cloudinary puts the whole image recipe in the URL path, one transformation per segment, so you can read a product photo URL like a short program and edit it. I measured what each part does on 11 November 2026 with curl, reading pixel sizes from the files (and from the AVIF ispe box, since my Pillow build has no AVIF decoder).
Reading the chain
This is the main photo on the Air Force 1 '07 product page, as Chrome loads it:
https://static.nike.com/a/images/t_web_pdp_535_v2/f_auto,u_9ddf04c7-2a9a-4d76-add1-d15af8f0263d,c_scale,fl_relative,w_1.0,h_1.0,fl_layer_apply/b7d9211c-26e7-431a-ac24-b0540fb3c00f/AIR+FORCE+1+%2707.png
Segments between /a/images/ and the photo ID run left to right. Inside a segment, commas join parameters that apply together.
-
t_web_pdp_535_v2is a named transformation, a preset stored on Nike's account. You can't see what it contains, only what it outputs. -
f_autolets the server pick the format from the request'sAcceptheader. -
u_9ddf04c7-…is an underlay: another image placed behind this one.c_scale,fl_relative,w_1.0,h_1.0scales it to 100% of the photo's size andfl_layer_applycloses the layer. -
b7d9211c-…is the uploaded photo, and the product name after it is decoration.
The underlay is a real asset you can fetch on its own: /a/images/9ddf04c7-2a9a-4d76-add1-d15af8f0263d.png comes back as a 400×400 JPEG of flat grey, RGB (236, 236, 234). That is the light grey behind every Nike product shot.
What each edit returns
Same photo, same Chrome-style Accept: image/avif,image/webp,*/* header unless noted:
URL after /a/images/
|
Type | Pixels | Bytes |
|---|---|---|---|
t_web_pdp_535_v2/f_auto,u_…/<id> (desktop page) |
AVIF | 1070×1338 | 23,072 |
t_web_pdp_936_v2/f_auto,u_…/<id> (mobile carousel) |
AVIF | 1872×2340 | 76,245 |
t_default/u_…/<id> (what the raw HTML has) |
PNG | 320×400 | 147,200 |
f_auto,u_…/<id> (preset removed) |
AVIF | 2880×3600 | 117,444 |
same, Accept: image/webp,*/*
|
WebP | 2880×3600 | 219,000 |
same, Accept: */*
|
JPEG | 2880×3600 | 315,747 |
u_…/<id> (no f_auto) |
PNG, RGB | 2880×3600 | 6,130,065 |
<id> (bare upload) |
PNG, RGBA | 2880×3600 | 3,569,409 |
The stored photo is 2880×3600, and the page asks for 1070×1338. Delete t_web_pdp_535_v2/ and you get every pixel, still on the grey background, at 117 KB as AVIF.
f_auto matters more for bytes than the size step does. Drop it and the server falls back to the upload's own format, PNG, and the grey underlay makes it a 6.1 MB opaque PNG. The bare upload is smaller (3.6 MB) because it keeps the alpha channel: pixel (5, 5) is (255, 255, 255, 0), fully transparent. So the bare URL is the one you want for cutouts, and the underlay URL is the one that looks like the website.
The server answers with vary: Accept,User-Agent, so a cached JPEG for curl and a cached AVIF for Chrome live side by side. If you script this and save with a .png name because the URL ends in .png, you will write AVIF bytes into a .png file.
The server tells you the original size
Cloudinary adds a server-timing header with the output and the original:
$ curl -sI -H "Accept: image/avif" "https://static.nike.com/a/images/f_auto,u_9ddf…/b7d9211c-…/AIR+FORCE+1+%2707.png" | grep server-timing
server-timing: cld-akam;dur=5;start=…;desc=hit,rtt;dur=3,content-info;desc="width=2880,height=3600,bytes=117444,format=\"avif\",owidth=2880,oheight=3600,obytes=3569409,oformat=\"png\",…"
owidth, oheight and obytes describe the upload. On adidas the same header shows up on the resized URL: h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/…/Samba_OG_Shoes_White_IG1024_01_standard.jpg returns an 840×840 AVIF (13,028 bytes) and reports owidth=2400,oheight=2400,obytes=819017. Strip the whole step and the bare URL returns that 2400×2400 JPEG, 819,017 bytes. A HEAD request is enough to learn whether an edit is worth making.
Don't ask for more than the original
Cloudinary will upscale if you ask. Replacing the preset with w_4000 returned a 4000×5000 AVIF, bigger than anything Nike uploaded. Adding c_limit (w_4000,c_limit) capped it at 2880×3600. When you strip size steps instead of rewriting them, this can't happen, which is why I strip.
The rule in code
PixLasso, the Chrome extension I made for saving every image on a page, does the "preset removed" edit for both brands. It drops leading segments while each one is only size, crop, quality or format parameters, and stops at the first segment that does anything else, such as the u_ underlay or an adidas l_ overlay:
const [, head, rest] = /^(\/(?:a\/)?images\/)(.*)$/.exec(u.pathname);
const parts = rest.split('/');
const STEP = /^(?:t_[a-z0-9_]+|(?:(?:w|h|c|q|f|dpr|ar|g)_[^,/]*|fl_(?:progressive|lossy)(?::[^,/]*)?)(?:,(?:(?:w|h|c|q|f|dpr|ar|g)_[^,/]*|fl_(?:progressive|lossy)(?::[^,/]*)?))*)$/i;
while (parts.length > 2 && STEP.test(parts[0])) parts.shift();
u.pathname = head + parts.join('/');
parts.length > 2 keeps the photo ID and file name even if a malformed URL has nothing else. Run on the two URLs above it gives:
https://static.nike.com/a/images/f_auto,u_9ddf04c7-…,fl_layer_apply/b7d9211c-…/AIR+FORCE+1+%2707.png
https://assets.adidas.com/images/a34f007a106043afb2f3afab00e997ee_9366/Samba_OG_Shoes_White_IG1024_01_standard.jpg
On Nike, f_auto,u_… survives as one segment because the u_ parameter fails the test, so the result keeps the grey background and stays small. That was deliberate: people saving product photos mostly want them to look like the site.
If you only need a few photos, the edit works by hand in the address bar. I wrote the steps up in how to download Nike product images in full size. Cloudinary URLs change when a brand renames its presets, so check the server-timing header again before relying on any number here.
Top comments (1)
Useful breakdown of the delivery half. One thing that bit us on the source side of the same pipeline: phone photos that carry an EXIF orientation tag. A transform chain can look right in Chrome and still arrive sideways in another viewer or tool, because not every consumer applies the tag. Baking the rotation into the pixels once, at upload, before any presets or f_auto run, removes a whole class of surprises. Did you see any product shots on nike.com where the underlay or crop hid an orientation problem like that? Disclosure: I'm the founder of BlueVeta.com, we generate product images from a single photo, so I run into this a lot.