← pixsum.dev

Pixsum docs

URL-based photography. Drop a prompt in, get a hyper-realistic image back — permanently cached at the edge, production ready.

Base URL: https://pixsum.dev

Overview#

Pixsum generates photorealistic AI images on demand. The first request for any unique prompt takes 5–10 seconds to generate. Every subsequent request is served from cache — either from Cloudflare's edge (~10ms) or the origin disk cache (~50ms).

Images are referenced by URL and cached permanently. The same prompt+params always returns the same image. This makes Pixsum safe to use in <img> tags, CSS backgrounds, and anywhere else you'd use a static image URL.

Pricing#

Credits are consumed per generation. Cache hits are free — you only spend a credit when a new image is generated. Credits never expire.

PackPriceCreditsPer imageUnlocks
Starter Buy — $9 → 150 $0.06 Single image, 6 photographic styles, webp/jpg, ar=
Growth Buy — $29 → 500 $0.058 Everything in Starter + POST /batch, fp=, comp=, custom presets, master image caching — resize to any dimension for free
Studio Buy — $99 → 2,000 $0.05 Everything in Growth + image adjustments (blur, brightness, contrast, saturation), negative prompts, camera/lens/film/grade/style_ph photography controls, watermarking, master image caching — resize to any dimension for free, custom domain (coming soon), priority generation, higher resolution

Authentication#

All image requests require an API key. Two key types are available:

TypeHow to passUse for
Secret keyAuthorization: Bearer KEY headerServer-side integrations, CI, scripts
Public key?key=KEY query paramClient-side, demos, img tags — rate limited to 30 req/min per IP

The /health endpoint is unauthenticated.

Quickstart#

img tag (simplest)

<!-- Prompt + photographic style preset -->
<img src="https://pixsum.dev?prompt=a+barista+pouring+latte+art&preset=documentary&w=1200&h=800&key=YOUR_KEY" />

<!-- Preset with default aspect ratio (cinematic = 21:9) -->
<img src="https://pixsum.dev?prompt=a+lone+figure+on+a+rain+soaked+rooftop&preset=cinematic&key=YOUR_KEY" />

fetch API

const res = await fetch(`https://pixsum.dev?prompt=${encodeURIComponent(prompt)}&preset=documentary&w=1200&h=800`, {
  headers: { 'Authorization': 'Bearer YOUR_SECRET_KEY' }
});
const blob = await res.blob();
img.src = URL.createObjectURL(blob);

Changelog#

v0.10 March 2026
  • Native aspect ratio — ar= is now passed directly to the model via image_config. Images are generated at the correct shape instead of being resized after the fact. Supported: 1:1, 3:2, 2:3, 4:3, 3:4, 4:5, 5:4, 16:9, 9:16, 21:9
  • Resolution tiers — Pixsum auto-selects 0.5K, 1K, 2K, or 4K native generation based on requested dimensions
  • Preset default aspect ratios — presets now define a default ar (e.g. cinematic = 21:9, social-story = 9:16). No need to pass w/h when using a preset
  • Realism improvements — rewritten quality anchors for more realistic colour saturation and dynamic range. Reduced AI contrast/HDR artifacts
  • B&W enforcement — film=tri-x and film=ilford-hp5 now produce fully monochrome output with zero colour bleed
  • New domain presets — product, social, realestate, food for batch API
v0.9 March 2026 Growth
  • Structured context — POST /batch now accepts context as a string or a structured object (title, story, people, places, themes, period, etc.). Pixsum handles the LLM reasoning — no prompt engineering required
  • Domain presets — pass domain: "memoir" to steer the expansion LLM toward the right photographic register. More domains coming
  • Caller-controlled cache key — pass cache_key: "story-123" to lock prompt expansion cache to a stable ID. Minor content edits no longer bust the cache
v0.8 March 2026 Growth
  • Alt text fallback — use alt attribute as prompt when no data-pixsum-prompt is set, via data-alt-fallback="true" or Pixsum.init({ altFallback: true })
  • Graceful placeholder — no prompt returns a clean SVG aperture mark instead of a broken image
  • enhance=1 — auto-expand short prompts into full photographic briefs via LLM (Growth+), cached permanently
v0.7 March 2026 Studio
  • Image adjustments — blur, brightness, contrast, saturation via Sharp post-processing
  • Negative prompts — no=people,faces,text excludes elements from generation entirely
  • Watermarking — watermark=, watermark_pos=, watermark_opacity= (coming soon)
  • Custom domain CDN — images.yourbrand.com via CNAME (coming soon)
v0.6 February 2026 Growth
  • Batch API — POST /batch generates a coherent set of images from a single context brief
  • Visual reference consistency — hero image passed as visual anchor to each thumbnail generation
  • Focal point control — fp=center|thirds|leading|foreground|negative
  • Composition control — comp=closeup|wide|portrait|overhead|environmental|cinematic
  • Custom presets — define your own photographic style recipes, locked to your key
v0.5 January 2026
  • 6 photographic styles — documentary, editorial, cinematic, product, street, social-story
  • Preset as style recipe — ?prompt=subject&preset=documentary applies photographic style to any subject
  • Permanent Cloudflare edge cache — identical params always served from the nearest PoP
v0.4 December 2025
  • WebP support — fmt=webp for better compression on web
  • Aspect ratio shorthand — ar=16:9 computes missing dimension automatically
  • Alt text generation — auto-generated descriptive alt text returned in API response
  • POST /v1/generate — JSON response with URL, alt text, dimensions, and cache status
  • Referrer locking — restrict a key to specific domains
v0.3 November 2025
  • Multi-model support — swap the underlying image model with a single config change
  • Disk cache layer — generated images persisted to disk, never regenerated for same params
  • GET /stats — cache hit rate, total generations, bandwidth served
  • Rate limiting — per-IP limits on public key requests
v0.1 — v0.2 October 2025
  • Initial release — GET /?prompt=&w=&h= returns an AI-generated image
  • OpenRouter integration — Gemini as default image model
  • Public key + private key authentication
  • 3KB zero-dependency JavaScript SDK with data-attribute support

GET / GET#

Generate or retrieve a single image. Returns raw image bytes with the appropriate Content-Type header.

Parameters

ParamTypeDescription
STANDARD — all plans
promptstringNatural language image description. Required if preset not provided.
presetstringNamed preset. Required if prompt not provided. See presets.
wintegerWidth in pixels. Default: 800.
hintegerHeight in pixels. Default: 800. Can be omitted if ar is set.
arstringAspect ratio shorthand — e.g. 16:9, 3:2, 1:1, 9:16. Computes missing dimension from w or h. Supported ratios are passed natively to the model for correct generation at the right shape. See Formats & sizing.
fmtstringjpg (default) or webp.
keystringPublic API key (alternative to Authorization header).
qualitystringQuality tier. Default: high quality (Gemini 3.1, 5 credits). Set quality=low for budget mode (Gemini 2.5, 1 credit) — good for prototypes and placeholders.
GROWTH — Growth & Studio plans
w / hintegerGrowth Master image cached — resize to any dimension for free after first generation. No extra credit cost.
fpstringGrowth Focal point. center, thirds, leading, foreground, negative.
compstringGrowth Composition framing. closeup, wide, portrait, overhead, environmental, cinematic.
enhanceflagGrowth Set to 1 to auto-expand your prompt into a full photographic brief before generation. Short prompts like coffee cup become rich art-directed descriptions. Result is cached — same prompt always expands the same way.
STUDIO — Studio plan only
blurnumberStudio Gaussian blur, 0–100.
brightnessnumberStudio Brightness multiplier, 0.5–2.0. Default 1.
contrastnumberStudio Contrast multiplier, 0.5–2.0. Default 1.
saturationnumberStudio Saturation multiplier, 0–2.0. Set to 0 for greyscale. Default 1.
nostringStudio Comma-separated exclusions. e.g. no=people,faces,text.
watermarkstringStudio Text to overlay (e.g. © Acme Co).
watermark_posstringStudio Position: bottomright (default), bottomleft, center, tile.
watermark_opacitynumberStudio Opacity 0–1. Default 0.3.
camerastringStudio Camera body. leica, sony, hasselblad, arri, phase-one, canon.
lensstringStudio Lens choice. 35mm, 50mm, 85mm, 100mm-macro, anamorphic, tilt-shift, wide.
filmstringStudio Film stock emulation. portra-400, fuji-400h, velvia-50, vision3, ilford-hp5, tri-x, ektar.
gradestringStudio Colour grade. teal-orange, matte, crushed-blacks, bleach-bypass, bw, fuji.
style_phstringStudio Photographer style. mccurry, leibovitz, lindbergh, crewdson, tillmans, cartier-bresson.
How caching works
Public & Starter: each unique prompt + dimension combination = 1 credit. Requesting the same prompt at a different size calls Gemini again.
Growth & Studio: the first generation of a prompt costs 1 credit and saves a full-resolution master. Subsequent requests for the same prompt at different dimensions are served via a free Sharp resize — no Gemini call, no credit deducted.
Quality-based billing: Credits consumed depend on quality tier — default = 5 credits (high quality, Gemini 3.1), quality=low = 1 credit (budget, Gemini 2.5). Cache hits on previously generated images consume 0 credits.

Examples

# Preset avatar, 200×200
curl "https://pixsum.dev?preset=corporate-portrait&w=400&h=400&key=YOUR_KEY"

# Custom prompt, 16:9, webp
curl "https://pixsum.dev?prompt=tokyo+street+at+night&w=1280&ar=16:9&fmt=webp&key=YOUR_KEY"

# With secret key in header
curl -H "Authorization: Bearer YOUR_SECRET_KEY" \
  "https://pixsum.dev?prompt=cozy+cafe+interior&w=800&h=600"

# Budget mode — 1 credit instead of 4, good for prototypes
curl "https://pixsum.dev?prompt=placeholder+hero&w=1200&h=600&quality=low&key=YOUR_KEY"

Enhance example Growth

Before enhance=1
prompt=coffee cup
After enhance=1 — what Gemini actually receives
A professional food photograph of a steaming artisan flat white in a handmade ceramic cup, placed on a weathered oak surface. Shot from a 45-degree angle, soft diffused window light from the left at 5400K. Shallow depth of field, sharp on the cup, soft bokeh background. Warm, inviting atmosphere.
# Short prompt — auto art-directed into a full photographic brief
curl "https://pixsum.dev?prompt=coffee+cup&enhance=1&w=800&h=600&key=YOUR_GROWTH_KEY"

# Confirm expansion ran — look for X-Enhanced: true in response headers
curl -I "https://pixsum.dev?prompt=coffee+cup&enhance=1&w=800&h=600&key=YOUR_GROWTH_KEY"
# X-Enhanced: true

POST /batch POST Growth#

Growth & Studio. Available on Growth ($29) and Studio ($99) credit packs. Each image generated consumes one credit — cache hits are free.

Generate a coherent set of images from a single context brief. The API uses an LLM to expand your brief into individual prompts — same people, same lighting, same story across all images. Results are cached: identical requests are instant.

Context can be a string or a structured object. Pass whatever data you have — Pixsum handles the reasoning. See examples below.

Request body

FieldTypeDescription
contextstring or objectRequired. Either a natural language brief ("Two friends at a ramen bar...") or a structured object with any fields you have — title, story, people, places, themes, period, etc. Pixsum serializes the object and applies LLM reasoning to extract the visual story. Blank/null fields are ignored.
imagesarrayRequired. Array of image slot objects (see below).
qualitystringOptional. Quality tier — default: high quality (Gemini 3.1, 5 credits per image). Set "low" for budget mode (Gemini 2.5, 1 credit per image).
domainstringOptional. Steers the expansion LLM toward the right photographic register for your use case. "memoir": candid, warm, intimate — Kodak Portra tones, natural light, personal memory aesthetic. Omit for generic photorealistic output.
cache_keystringOptional. Caller-controlled cache identity for prompt expansion. When set, the prompt cache is keyed on this string + slot layout rather than hashing the context content — so minor edits to context (story updated, person linked, date changed) don't trigger regeneration. Use a stable ID like "story-123" and bump to "story-123-v2" only when you genuinely want new images.
seedstringOptional. Pass a stable string for fully deterministic results. Same seed + same context = same cached images on every call.

Image slot object

FieldTypeDescription
rolestringhero, thumbnail, or any label. Hero = wide/cinematic. Thumbnails follow a curated mix: detail, candid action, atmospheric wide, intimate close-up.
wintegerWidth in pixels. Default: 512.
hintegerHeight in pixels. Default: 512. Can be omitted if ar is set.
arstringAspect ratio shorthand, e.g. 16:9, 1:1, 2:1. Computes the missing dimension from w or h.
countintegerGenerate N images for this slot. Default: 1. Useful for multiple thumbnails of the same role.

Example — string context

curl -X POST https://pixsum.dev/batch \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -d '{
    "context": "Two friends at a Tokyo ramen bar, late evening. Warm lantern light. Candid, documentary, 35mm film grain.",
    "images": [
      { "role": "hero",      "w": 1200, "h": 630 },
      { "role": "thumbnail", "w": 400,  "h": 400, "count": 4 }
    ]
  }'

Example — structured context object

Pass whatever structured data your app has. Pixsum's LLM extracts the visual story — no prompt engineering required on your side.

Response

URLs in the response are relative to https://pixsum.dev — prepend the base URL to get a fully qualified image URL.
{
  "images": [
    { "role": "hero",      "url": "/cache/abc123.jpg", "alt": "Two friends laughing over steaming ramen bowls, warm lantern light", "cached": false },
    { "role": "thumbnail", "url": "/cache/def456.jpg", "alt": "Close-up of chopsticks lifting noodles from steaming bowl",     "cached": false },
    { "role": "thumbnail", "url": "/cache/ghi789.jpg", "alt": "Candid moment mid-laugh, looking away from camera",             "cached": false },
    { "role": "thumbnail", "url": "/cache/jkl012.jpg", "alt": "Wide shot of glowing ramen bar, figures small in the space",    "cached": false },
    { "role": "thumbnail", "url": "/cache/mno345.jpg", "alt": "Two ceramic cups of tea on worn wooden counter",               "cached": false }
  ],
  "context": { /* echoed back */ },
  "count": 5
}

GET /v1/generate GET#

Same as GET / but returns JSON instead of raw image bytes. Useful for integrations where you need the URL, alt text, and cache status before rendering.

curl "https://pixsum.dev/v1/generate?preset=documentary&w=800&h=800&key=YOUR_KEY"

Response

{
  "url":    "https://pixsum.dev/cache/abc123.jpg",
  "alt":    "Artisan bowl of ramen with soft-boiled egg and bamboo shoots",
  "prompt": "Gourmet restaurant dish photography...",
  "cached": true,
  "w":      800,
  "h":      800,
  "fmt":    "jpg",
  "model":  "google/gemini-3.1-flash-image-preview"
}

SDK — Installation#

The Pixsum SDK is a 3KB, zero-dependency script. Drop it in any HTML page — it scans for data-pixsum-* attributes and handles shimmer loading + fade-in automatically.

<script src="https://pixsum.dev/pixsum.js" data-key="YOUR_PUBLIC_KEY"></script>

SDK — Single images#

<!-- Preset standalone -->
<img data-pixsum-preset="corporate-portrait" data-w="400" data-h="400" />

<!-- Prompt + style preset -->
<img data-pixsum-prompt="a barista pouring latte art in a sunlit cafe"
     data-pixsum-preset="documentary" data-w="1200" data-h="800" />

Alt text fallback

Enable globally via the script tag or per-container to use the image's alt attribute as the prompt when no data-pixsum-prompt is set:

<!-- Enable globally -->
<script src="https://pixsum.dev/pixsum.js"
  data-key="YOUR_KEY"
  data-alt-fallback="true"></script>

<!-- Or per-container -->
<img data-pixsum-prompt=""
     data-pixsum-alt-fallback="true"
     alt="barista pouring latte art in a sunlit cafe"
     data-pixsum-preset="documentary" />

<!-- Or via JS -->
<script>Pixsum.init({ altFallback: true });</script>

Alt text that looks like a filename (IMG_4382, DSC_0001) is ignored and returns a clean placeholder instead.

SDK — Batch groups#

<div data-pixsum-batch>
  <!-- Context brief (not rendered) -->
  <data value="Team offsite in Kyoto. Candid, warm, documentary style. Film grain."></data>

  <!-- Image slots -->
  <img data-pixsum-role="hero"      data-w="700" data-h="400" />
  <img data-pixsum-role="thumbnail" data-w="160" data-h="100" />
  <img data-pixsum-role="thumbnail" data-w="160" data-h="100" />
</div>
<!-- Shimmer + fade-in handled automatically ✨ -->

Using presets#

Presets are photographic style recipes that encode lighting, mood, and composition quality. Each preset also includes default equipment (camera, lens, film) — Studio plan users can override any of these with URL params. Browse the full preset gallery to see them live.

6 core photographic style presets are available:

PresetDefault equipmentStyle
documentaryleica · 35mm · tri-xCandid decisive moment, available light, Magnum quality.
editorialhasselblad · 85mm · fuji-400hSoft window light, magazine breathing room, Kinfolk/Vogue quality.
cinematicarri · anamorphic · vision3Teal shadows, oval bokeh, 2.39:1 widescreen composition.
productphase-one · 100mm-macro · ektarThree-point softbox, seamless white, e-commerce hero.
streetleica · 35mm · ilford-hp5Harsh available light, high contrast, Cartier-Bresson quality.
social-storycanon · 35mm · fuji-400hPortrait orientation, warm punchy colour, scroll-stopping composition.

Browse them live on the homepage preset gallery.

Equipment override (Studio): pass camera=, lens=, or film= to override any preset default. For example, ?preset=editorial&camera=leica uses the editorial style but swaps in a Leica body while keeping the 85mm lens and Fuji 400H film from the preset.

Legacy presets (editorial-lifestyle, editorial-travel, studio-product, fine-dining, architectural, and more) remain supported for backward compatibility.

Studio Photography Controls Studio#

Studio plan users can specify the camera body, lens, film stock, colour grade, and photographer style as URL parameters. These override the default equipment defined by a preset — so you get the preset's lighting and mood with your chosen gear.

Studio. All photography control params require a Studio API key. Without params, presets fall back to their built-in equipment defaults.
ParamValuesDescription
camera
leicasonyhasselbladarriphase-onecanon
Camera body — affects rendering character, colour science and dynamic range.
lens
35mm50mm85mm100mm-macroanamorphictilt-shiftwide
Lens character — determines focal length, bokeh shape and depth of field.
film
portra-400fuji-400hvelvia-50vision3ilford-hp5tri-xektar
Film stock emulation — shapes colour science, grain character and tonal response.
grade
teal-orangemattecrushed-blacksbleach-bypassbwfuji
Post-processing colour grade applied on top of the film stock.
style_ph
mccurryleibovitzlindberghcrewdsontillmanscartier-bresson
Photographer reference — compositional framing, tonal approach and mood.
# Street documentary shot — Leica, 35mm, Tri-X, Cartier-Bresson style
curl "https://pixsum.dev?prompt=commuters+in+the+rain&preset=street&camera=leica&lens=35mm&film=tri-x&style_ph=cartier-bresson&key=YOUR_STUDIO_KEY"

# Editorial portrait — Hasselblad, 85mm, Portra 400, warm grade
curl "https://pixsum.dev?prompt=chef+plating+a+dish&preset=documentary&camera=hasselblad&lens=85mm&film=portra-400&grade=matte&key=YOUR_STUDIO_KEY"

Custom domain Studio Coming soon#

Serve Pixsum images from your own domain — images.yourbrand.com — via a simple CNAME. No pixsum.dev URLs in your production code.

Custom domain support is coming to Studio plan. Get in touch if this is blocking you — we can set it up manually in the meantime.

Caching#

Pixsum uses a two-layer cache. The cache key is a SHA-256 hash of prompt + w + h + style + theme + fmt — identical params always return the same image.

LayerSpeedHow it works
Cloudflare edge~10msResponses set Cache-Control: public, max-age=31536000, immutable. CF caches at the nearest PoP for 1 year.
Origin disk cache~50msGenerated images saved to disk by cache key. Never regenerated for the same params.
OpenRouter / Gemini5–10sOnly called on first-ever request for a unique prompt+size.

Image consistency in batch#

Pixsum uses a three-layer consistency system to keep characters, lighting, and setting coherent across all images in a batch.

Option A — Prompt anchoring (always on)

When expanding your context brief into individual prompts, the LLM is instructed to extract and lock specific descriptors — exact physical appearance, clothing, location, lighting conditions, camera style — and repeat them verbatim in every prompt. This ensures tonal and stylistic coherence even before any images are generated.

Option B — Visual reference generation (always on)

This is the main consistency driver. Pixsum generates the hero image first, then passes it as a visual input to Gemini when generating each thumbnail. The model literally sees the hero — the characters’ faces, hair, clothing, the lighting, the location — and uses it as a visual anchor.

The thumbnail prompt sent to the model becomes: “Using the people, lighting, and setting in the reference image as a visual anchor, generate: [thumbnail prompt]. Keep the same characters — same faces, hair, clothing. Different moment, same scene.”

This is what makes batch story cards feel like they came from the same shoot rather than independent generations. Visual reference anchoring (Option B) is included in all Batch API plans Growth+.

How it flows: context brief → LLM expands to N prompts with locked descriptors (A) → hero generated → thumbnails generated with hero as visual reference (B) → all cached permanently by prompt hash.

Formats & sizing#

Supported formats: jpg (default, smaller), webp (better compression for web).

Aspect ratio

Use ar= to set the aspect ratio. When a supported ratio is detected, Pixsum passes it natively to the model — the image is generated at the correct shape rather than being cropped or resized after the fact. This produces better compositions since the model composes for the target frame.

Supported native ratios:

RatioNative resolutionUse case
1:11024 × 1024Avatars, product shots, social squares
3:21248 × 832Standard photography, editorial, landscape
2:3832 × 1248Portrait orientation, book covers
4:31184 × 864Classic photo, presentations
3:4864 × 1184Portrait, print media
4:5896 × 1152Instagram portrait, fashion editorial
5:41152 × 896Large format, fine art prints
16:91344 × 768Widescreen, hero images, OG cards
9:16768 × 1344Stories, vertical video, mobile
21:91536 × 672Ultra-wide, cinematic stills
Presets include a default aspect ratio. For example, cinematic defaults to 21:9 and social-story defaults to 9:16. You only need to pass ar= when overriding the preset's default or when using no preset at all.

Unsupported ratios (e.g. 2:1) still work — the model generates at its default size and Pixsum resizes to your requested dimensions.

# 16:9 widescreen — generated natively at correct shape
?w=1280&ar=16:9

# Square — no ar needed, 1:1 is inferred from equal w and h
?w=800&h=800

# Let the preset decide — cinematic defaults to 21:9
?prompt=rain+soaked+rooftop&preset=cinematic

# Override preset aspect ratio
?prompt=rain+soaked+rooftop&preset=cinematic&ar=16:9

Resolution tiers

Pixsum automatically selects the best resolution tier based on your requested dimensions. Higher tiers produce sharper images with more detail — the model generates at a higher native resolution before any resizing.

TierLargest dimensionBest for
0.5K≤ 600pxThumbnails, previews, small cards
1K≤ 1024pxStandard web images, blog posts, avatars
2K≤ 1600pxHero images, high-quality editorial
4K> 1600pxPrint-ready, large format, maximum detail
Resolution affects credit cost. See Pricing for the per-size credit breakdown. Cache hits are always free regardless of resolution.