# via.placeholder.com > Free placeholder images, avatars, photos, QR codes, test-safe barcodes and fictional brand images by URL. No sign-up, no API key. The same URL always returns the same bytes (cached for a year). For mockups, prototypes, tests and demos only: never ship these URLs or files to production, and run placeholder-check in CI (https://tools.placeholder.com/placeholder-check). All endpoints: GET/HEAD, CORS `*`, header `X-Placeholder: via.placeholder.com` on every image. Always set `width` and `height` on ``. ## Images (placehold.it syntax) ``` https://via.placeholder.com/{size}[@{scale}x][/{bg}[/{fg}]][.{format}][?text={text}] ``` - size: `150` (square) or `600x400` (width x height). 1..4000 px per side. Larger returns a 200 image reading "Max size is 4000 x 4000". - bg, fg: 3/6-digit hex WITHOUT `#` (`ff6600`, `09f`) or a CSS colour name (`navy`). Defaults: bg `cccccc`, fg `969696`. Unknown colours fall back to the default. - format: `png` (default), `jpg`/`jpeg`, `gif`, `webp`, `svg`. The extension may go on any segment. `avif`: see below. - text: URL-encoded, max 120 characters. Default text is the size, e.g. "600 x 400". - retina: `@2x` or `@3x` (also `@1.5x`; clamped to 1..3) on the SIZE segment only: `/600x400@2x` is 1200x800 pixels with the same layout and text. Before or after the extension (`/600x400@2x.png`, `/600x400.png@2x`). Output capped at 4000 px per side (scale lowered to fit). `?dpr=` is IGNORED on these classic URLs; use the suffix. SVG keeps the logical viewBox with width/height multiplied. - avif: put `.avif` on the size segment (`/600x400.avif`, `/600x400.avif/ff6600/fff`) or anywhere once the size carries a scale (`/600x400@2x/ff6600/fff.avif`). `/600x400/ff6600/fff.avif` is NOT AVIF: it returns a PNG with the default text colour (legacy URL, frozen bytes). Above 2.1 MP (e.g. `1200x800@2x`) AVIF is served as WebP, `Content-Type: image/webp`. Examples: - https://via.placeholder.com/150 - https://via.placeholder.com/600x400 - https://via.placeholder.com/600x400/ff6600/ffffff - https://via.placeholder.com/600x400.svg - https://via.placeholder.com/600x400.webp?text=Hero+image - https://via.placeholder.com/1200x630/1c1d19/ecf34d.jpg?text=Open+Graph+image - https://via.placeholder.com/600x400@2x.webp - https://via.placeholder.com/600x400.avif These classic images have no embedded marker (their bytes are frozen; retina PNG/JPEG/GIF/WebP/SVG neither), so downloaded copies are not detectable: link to them, don't download them. Exception: classic AVIF carries the marker. ## Avatars ``` https://via.placeholder.com/avatar/{name}[@{scale}x][.{format}][?size=&shape=&style=&bg=&fg=&seed=&dpr=] ``` - name: URL-encoded full name -> initials (`Anna%20Svensson` -> "AS"). Slugs (`anna-svensson`) and e-mail local parts work. Or `?name=`. - format: `png` (default), `svg`, `webp`, `jpg`, `gif`, `avif` (keeps transparent corners). - size: 16..512 (clamped), default 128. Also `?s=` or a path segment `/avatar/128/{name}`. - retina: `@2x`/`@3x` (also `@1.5x`) at the end of any segment (`/avatar/Anna%20Svensson@2x.png`, `/avatar/64@2x/Anna`) or `?dpr=1..3` (suffix wins). Output = size x scale px, capped at 512. E-mail names (`anna@x.se`) are not scales. - shape: `circle` (default), `square`, `rounded`. - style: `initials` (default for names), `shapes`, `identicon`, `silhouette`; also as a path segment: `/avatar/identicon/{seed}`. - bg, fg: hex (with or without `#`) or CSS colour name. Without fg, text colour is chosen for contrast. - seed: any string; picks colours/pattern. Default: the name as written. Use a stable user ID. - Never errors. Never draws a human face. Descriptor slugs (`woman-40s-smiling`, `u/42`) get abstract shapes; generic words (`default`, `user`) get a silhouette. Examples: - https://via.placeholder.com/avatar/Anna%20Svensson.png - https://via.placeholder.com/avatar/Anna%20Svensson.svg?size=64&seed=user-1842 - https://via.placeholder.com/avatar/Anna%20Svensson.png?bg=1c1d19&fg=ecf34d&shape=rounded - https://via.placeholder.com/avatar/identicon/user-42.png - https://via.placeholder.com/avatar/default.png - https://via.placeholder.com/avatar/Anna%20Svensson@2x.png - https://via.placeholder.com/avatar/Anna%20Svensson.avif ## Photos ``` https://via.placeholder.com/photo/{subject-words}/{width}x{height}[@{scale}x][.{format}][?seed=&grayscale&blur=&dpr=] ``` - subject words: separated by `-`, `_`, `+` or spaces; several segments allowed (`food/pizza`). Synonyms and plurals are understood. Also `?q=`. No words = any photo. - size: `1200x800`, one number for a square, or `/{w}/{h}`. Also `?w=` `?h=`. Default 1200x800. Max 2000 px per side; larger requests are scaled down keeping the aspect ratio. - format: `jpg` (default), `webp`, `png`, `avif`. AVIF above 2.7 MP (e.g. 2000x1500) is served as WebP, `Content-Type: image/webp`. - retina: `@2x`/`@3x` (also `@1.5x`) at the end of any segment, or `?dpr=1..3` (suffix wins). Same crop, more pixels; output capped at 2000 px per side (so `1200x800@2x` is 2000x1333). Sources are at most 1600 px; larger outputs are upscaled. - seed: another equally good match, still fixed per URL. `grayscale`: flag. `blur`: 1..10 (bare `blur` = 2). - Segments can be in any order. Unknown subjects return a grey placeholder of the requested size with the words on it (still 200, no `X-Photo-Id` header). - Response headers: `X-Photo-Id`, `X-Photo-License` (CC0 / public domain), `Link: ; rel="license"`. - Available subjects: https://via.placeholder.com/photo/tags (JSON). Credits: https://via.placeholder.com/photo/credits Examples: - https://via.placeholder.com/photo/coffee/1200x800 - https://via.placeholder.com/photo/mountain-lake/800x600.webp - https://via.placeholder.com/photo/cafe-interior/600x400?grayscale - https://via.placeholder.com/photo/coffee/800x600?seed=3 - https://via.placeholder.com/photo/coffee/800x600@2x.webp - https://via.placeholder.com/photo/coffee/1200x800.avif ## QR codes ``` https://via.placeholder.com/qr/{url-encoded text}[.png|.svg|.webp|.gif|.jpg][?size=&ecc=&margin=&fg=&bg=&scale=] https://via.placeholder.com/qr.png?text={text} https://via.placeholder.com/qr?data={text}&format=svg ``` - text: everything after `/qr/` (slashes included) minus a trailing image extension; `?text=`/`?data=` win. Max 1024 UTF-8 bytes, else 400. No text = `https://placeholder.com/`. Percent-encode URLs: an unencoded URL's query keys that clash with ours (size, color, margin...) are taken as ours. - format: `png` (default), `svg`, `webp`, `gif`, `jpg`. Other extensions (avif too) -> png. - size: 16..2000, default 200 (exact square; grows if the code doesn't fit). `scale`: 1..50 px per module instead. - ecc: `L`, `M` (default), `Q`, `H`. margin: 0..20 modules, default 4. fg/bg: hex, CSS name or `r-g-b`; `bg=transparent` for png/svg/webp/gif. - Header `X-QR-Version` (e.g. `2-M`). Alias `/qrcode/...`; Google Charts params `chl`, `chs`, `chld` work. Examples: - https://via.placeholder.com/qr/https%3A%2F%2Fexample.com%2F - https://via.placeholder.com/qr/hello.svg - https://via.placeholder.com/qr.png?text=Hello%20world&size=300 - https://via.placeholder.com/qr/hello?ecc=H&margin=2&fg=1c1d19&bg=ecf34d ## Barcodes (test-safe) ``` https://via.placeholder.com/barcode/{type}/{value}[.png|.svg|.webp|.gif|.jpg] https://via.placeholder.com/barcode/{type}[?seed={s}&prefix=company|region|demo] a test-safe code https://via.placeholder.com/barcode/{type}/test.json?count={1..100}&seed={s} list of test-safe codes ``` - type: `ean13`, `upca`, `ean8`, `itf14`, `gs1-128`, `code128`, `code39` (aliases: ean, upc, gtin13, gtin12, gtin14, itf, c128, c39, ean128...). `/barcode/{digits}` guesses by length (8 EAN-8, 12 UPC-A, 13 EAN-13, 14 ITF-14, else Code 128). `/barcode/qr/{text}` = QR. - value: numeric types take the value without its check digit (computed) or with it. A WRONG check digit = 400 error image + `X-Placeholder-Error`; `?check=fix` corrects, `?check=keep` renders it (header `X-Barcode-Warning`). GS1-128: `(01)09521234500001(10)ABC`. Code 39: `?check=mod43`. - No value (or `test`, `random`, `sample`, `demo`) = a test-safe code from GS1 ranges no real product carries: EAN-13 prefix 04 (company RCN, default), 02/20-29 (`prefix=region`; may scan as a priced variable-weight item), 952 (`prefix=demo`); UPC-A number system 4 (or 2); EAN-8 prefix 2 (or 952); ITF-14 and GS1-128 on 952. Code 128/39: `TEST-` + 6 digits. Source: GS1 General Specifications R26.0, Table 1-4/1-5, 2.1.11. Header `X-Barcode-Test` names the range. - Options: `scale` 1..10 px per bar (default 2), `width` (exact width), `height` 10..1000, `hrt=0` hides digits, `margin` (quiet zone, never below the symbology minimum), `bearer=0` (ITF-14), `fg`, `bg`. - Headers: `X-Barcode-Type`, `X-Barcode-Value`. Errors are 400 images cached a day. - Never put real product GTINs in tests; use these. Examples: - https://via.placeholder.com/barcode/ean13 - https://via.placeholder.com/barcode/ean13?seed=7 - https://via.placeholder.com/barcode/ean13/048192616039 - https://via.placeholder.com/barcode/gs1-128/(01)09521234500001(10)ABC - https://via.placeholder.com/barcode/code128/HELLO-123.svg - https://via.placeholder.com/barcode/ean13/test.json?count=10&seed=7 ## Brand images ``` https://via.placeholder.com/brand/{slug}/{asset}.{svg|png|webp|jpg|ico}[?theme=&mono=&bg=&size=&h=&w=] ``` - Fictional brands; the kit (JSON, CSS tokens) is at https://data.placeholder.com/brands/{slug}. Curated slugs: https://data.placeholder.com/brands. Any name-like slug becomes the name (`quillmere-labs` -> "Quillmere Labs"); other slugs (`42`, `test`, real brand names) get a generated fictional name. - assets: `logo` (mark + wordmark; `?h=` 16..1024, default 128, or `?w=`; `?layout=stacked`), `logomark` (`?size=` 16..1024, default 256), `favicon` (`.ico` = 16/32/48; `?size=` 16..512, default 32; `apple-touch-icon.png` = 180), `og` (1200x630 social card, `?theme=brand|light|dark`), `palette` (1200x630 swatch sheet). - common: `theme=light|dark`, `mono=1`, `bg=transparent|white|brand|light|dark|{hex}`. Aliases: wordmark/lockup -> logo; mark/icon/symbol -> logomark; social/opengraph/twitter-card -> og; colors/swatches -> palette; digits in the file name set the size (`android-chrome-192x192.png`). Unknown names -> logo; unknown extensions (avif too) -> png. Never errors. - Fonts: https://via.placeholder.com/brand/_fonts/{file} (SIL OFL). Examples: - https://via.placeholder.com/brand/brightfjord/logo.svg - https://via.placeholder.com/brand/brightfjord/logo.png?h=64&theme=dark - https://via.placeholder.com/brand/brightfjord/favicon.ico - https://via.placeholder.com/brand/brightfjord/og.png - https://via.placeholder.com/brand/quillmere-labs/logomark.svg ## Detectability Every avatar, photo, QR code, barcode and brand image file (except brand `.ico` favicons), and every classic AVIF, embeds the text "Placeholder image from via.placeholder.com - replace before shipping" (PNG tEXt, JPEG COM, GIF comment, WebP/AVIF XMP, SVG comment + `data-placeholder="via.placeholder.com"`). placeholder-check finds these files and any placeholder URL in a build: ``` curl -fsSL https://tools.placeholder.com/check/placeholder-check | python3 - dist ``` ## Docs - [Images](https://tools.placeholder.com/images): full syntax and headers - [Avatars](https://tools.placeholder.com/avatars): styles, aliases, personas - [Photos](https://tools.placeholder.com/photos): subjects, cropping, credits - [QR codes and barcodes](https://tools.placeholder.com/qr): options, test-safe GS1 ranges, check digits - [Brand kits](https://tools.placeholder.com/brands): kit JSON, tokens.css, logos, favicons, social cards - [CI check](https://tools.placeholder.com/placeholder-check): placeholder-check options, GitHub Actions, GitLab, pre-commit - [Placeholder data](https://data.placeholder.com/llms.txt): people, mock REST API, company dataset, brand kits, fixtures with answer keys, text, safe test values - [Everything](https://tools.placeholder.com/llms-full.txt): also dummy files (files.placeholder.com) and HTTP test endpoints (http.placeholder.com)