YouTube Thumbnail URL Format
Every size YouTube stores, when each file exists, and copy-paste code for the right fallback chain.
Every size YouTube stores, when each file exists, and copy-paste code for the right fallback chain.
Every public YouTube video exposes its thumbnails at predictable addresses. You do not need an API key, OAuth, or scraping. This page lists every known thumbnail file, when each one exists, and how to use them in code. Bookmark it; nothing here requires our tool, though the thumbnail grabber does it in one click.
https://img.youtube.com/vi/<VIDEO_ID>/<FILE>.jpg
https://i.ytimg.com/vi/<VIDEO_ID>/<FILE>.jpg (same files, CDN host)
The VIDEO_ID is the 11-character code in any YouTube link: after v= in a watch URL, after /shorts/ in a Shorts URL, or the path of a youtu.be link.
| File | Resolution | Aspect | Availability |
|---|---|---|---|
maxresdefault.jpg | 1280x720 | 16:9 | HD uploads and custom thumbnails only |
sddefault.jpg | 640x480 | 4:3 (letterboxed) | Most videos |
hqdefault.jpg | 480x360 | 4:3 (letterboxed) | Every video |
mqdefault.jpg | 320x180 | 16:9 | Every video |
default.jpg | 120x90 | 4:3 | Every video |
0.jpg | 480x360 | 4:3 | Every video (same as hqdefault) |
1.jpg 2.jpg 3.jpg | 120x90 | 4:3 | Auto frames from start, middle, end |
hq720.jpg | 1280x720 | 16:9 | Many HD videos |
oar2.jpg | Vertical | 9:16 | Shorts (see our Shorts downloader) |
The letterboxed 4:3 files (hqdefault, sddefault, 0.jpg) include black bars above and below the 16:9 image. If you need clean 16:9 with guaranteed availability, use mqdefault.jpg.
YouTube serves smaller WebP files from the vi_webp path:
https://i.ytimg.com/vi_webp/<VIDEO_ID>/hqdefault.webp
https://i.ytimg.com/vi_webp/<VIDEO_ID>/mqdefault.webp
Active live streams refresh their thumbnail at a _live suffix:
https://i.ytimg.com/vi/<VIDEO_ID>/hqdefault_live.jpg
The most common bug in thumbnail code: assuming maxresdefault.jpg always exists. It does not. For videos uploaded below 720p without a custom thumbnail, that URL returns a 404 (or a gray 120x90 placeholder via some CDN edges). Use this fallback order: maxresdefault, then sddefault, then hqdefault, which always exists.
function getThumbnail(videoId) {
const files = ['maxresdefault', 'sddefault', 'hqdefault'];
return new Promise((resolve) => {
const tryNext = (i) => {
const img = new Image();
const url = `https://i.ytimg.com/vi/${videoId}/${files[i]}.jpg`;
img.onload = () => (img.naturalWidth > 120 || i === files.length - 1) ? resolve(url) : tryNext(i + 1);
img.onerror = () => tryNext(i + 1);
img.src = url;
};
tryNext(0);
});
}
import requests
def get_thumbnail(video_id: str) -> str:
for f in ("maxresdefault", "sddefault", "hqdefault"):
url = f"https://i.ytimg.com/vi/{video_id}/{f}.jpg"
if requests.head(url, timeout=5).status_code == 200:
return url
return f"https://i.ytimg.com/vi/{video_id}/hqdefault.jpg"
const ID_RE = /(?:v=|\/(?:shorts|embed|live|v)\/|youtu\.be\/)([0-9A-Za-z_-]{11})/;
const id = (url.match(ID_RE) || [])[1];
https://www.youtube.com/oembed?url=...&format=json) also returns a thumbnail_url field if you prefer an API-style call.Prefer not to write code at all? Paste any link into the YouTube thumbnail grabber and download every size in one click.