Pixsum docs
URL-based photography. Drop a prompt in, get a hyper-realistic image back — permanently cached at the edge, production ready.
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.
| Pack | Price | Credits | Per image | Unlocks |
|---|---|---|---|---|
| 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:
| Type | How to pass | Use for |
|---|---|---|
| Secret key | Authorization: Bearer KEY header | Server-side integrations, CI, scripts |
| Public key | ?key=KEY query param | Client-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#
- Native aspect ratio —
ar=is now passed directly to the model viaimage_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, or4Knative 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 passw/hwhen 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-xandfilm=ilford-hp5now produce fully monochrome output with zero colour bleed - New domain presets —
product,social,realestate,foodfor batch API
- Structured context —
POST /batchnow acceptscontextas 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
- Alt text fallback — use
altattribute as prompt when nodata-pixsum-promptis set, viadata-alt-fallback="true"orPixsum.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
- Image adjustments —
blur,brightness,contrast,saturationvia Sharp post-processing - Negative prompts —
no=people,faces,textexcludes elements from generation entirely - Watermarking —
watermark=,watermark_pos=,watermark_opacity=(coming soon) - Custom domain CDN —
images.yourbrand.comvia CNAME (coming soon)
- Batch API —
POST /batchgenerates 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
- 6 photographic styles — documentary, editorial, cinematic, product, street, social-story
- Preset as style recipe —
?prompt=subject&preset=documentaryapplies photographic style to any subject - Permanent Cloudflare edge cache — identical params always served from the nearest PoP
- WebP support —
fmt=webpfor better compression on web - Aspect ratio shorthand —
ar=16:9computes 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
- 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
- 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
| Param | Type | Description |
|---|---|---|
| STANDARD — all plans | ||
| prompt | string | Natural language image description. Required if preset not provided. |
| preset | string | Named preset. Required if prompt not provided. See presets. |
| w | integer | Width in pixels. Default: 800. |
| h | integer | Height in pixels. Default: 800. Can be omitted if ar is set. |
| ar | string | Aspect 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. |
| fmt | string | jpg (default) or webp. |
| key | string | Public API key (alternative to Authorization header). |
| quality | string | Quality 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 / h | integer | Growth Master image cached — resize to any dimension for free after first generation. No extra credit cost. |
| fp | string | Growth Focal point. center, thirds, leading, foreground, negative. |
| comp | string | Growth Composition framing. closeup, wide, portrait, overhead, environmental, cinematic. |
| enhance | flag | Growth 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 | ||
| blur | number | Studio Gaussian blur, 0–100. |
| brightness | number | Studio Brightness multiplier, 0.5–2.0. Default 1. |
| contrast | number | Studio Contrast multiplier, 0.5–2.0. Default 1. |
| saturation | number | Studio Saturation multiplier, 0–2.0. Set to 0 for greyscale. Default 1. |
| no | string | Studio Comma-separated exclusions. e.g. no=people,faces,text. |
| watermark | string | Studio Text to overlay (e.g. © Acme Co). |
| watermark_pos | string | Studio Position: bottomright (default), bottomleft, center, tile. |
| watermark_opacity | number | Studio Opacity 0–1. Default 0.3. |
| camera | string | Studio Camera body. leica, sony, hasselblad, arri, phase-one, canon. |
| lens | string | Studio Lens choice. 35mm, 50mm, 85mm, 100mm-macro, anamorphic, tilt-shift, wide. |
| film | string | Studio Film stock emulation. portra-400, fuji-400h, velvia-50, vision3, ilford-hp5, tri-x, ektar. |
| grade | string | Studio Colour grade. teal-orange, matte, crushed-blacks, bleach-bypass, bw, fuji. |
| style_ph | string | Studio Photographer style. mccurry, leibovitz, lindbergh, crewdson, tillmans, cartier-bresson. |
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.
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
prompt=coffee cupA 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#
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
| Field | Type | Description |
|---|---|---|
| context | string or object | Required. 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. |
| images | array | Required. Array of image slot objects (see below). |
| quality | string | Optional. Quality tier — default: high quality (Gemini 3.1, 5 credits per image). Set "low" for budget mode (Gemini 2.5, 1 credit per image). |
| domain | string | Optional. 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_key | string | Optional. 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. |
| seed | string | Optional. Pass a stable string for fully deterministic results. Same seed + same context = same cached images on every call. |
Image slot object
| Field | Type | Description |
|---|---|---|
| role | string | hero, thumbnail, or any label. Hero = wide/cinematic. Thumbnails follow a curated mix: detail, candid action, atmospheric wide, intimate close-up. |
| w | integer | Width in pixels. Default: 512. |
| h | integer | Height in pixels. Default: 512. Can be omitted if ar is set. |
| ar | string | Aspect ratio shorthand, e.g. 16:9, 1:1, 2:1. Computes the missing dimension from w or h. |
| count | integer | Generate 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.
curl -X POST https://pixsum.dev/batch \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_SECRET_KEY" \ -d '{ "context": { "title": "Late night ramen in Tokyo", "story": "Two old friends catching up after years apart. Their first night in the city together.", "people": ["Aiko", "James"], "places": ["Shibuya", "Tokyo"], "themes": ["friendship", "nostalgia"], "period": "Autumn 2024" }, "domain": "memoir", "cache_key": "story-42", "images": [ { "role": "hero", "w": 1200, "h": 630 }, { "role": "thumbnail", "w": 400, "h": 400, "count": 4 } ] }'
Response
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:
| Preset | Default equipment | Style |
|---|---|---|
| documentary | leica · 35mm · tri-x | Candid decisive moment, available light, Magnum quality. |
| editorial | hasselblad · 85mm · fuji-400h | Soft window light, magazine breathing room, Kinfolk/Vogue quality. |
| cinematic | arri · anamorphic · vision3 | Teal shadows, oval bokeh, 2.39:1 widescreen composition. |
| product | phase-one · 100mm-macro · ektar | Three-point softbox, seamless white, e-commerce hero. |
| street | leica · 35mm · ilford-hp5 | Harsh available light, high contrast, Cartier-Bresson quality. |
| social-story | canon · 35mm · fuji-400h | Portrait 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.
| Param | Values | Description |
|---|---|---|
| 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.
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.
| Layer | Speed | How it works |
|---|---|---|
| Cloudflare edge | ~10ms | Responses set Cache-Control: public, max-age=31536000, immutable. CF caches at the nearest PoP for 1 year. |
| Origin disk cache | ~50ms | Generated images saved to disk by cache key. Never regenerated for the same params. |
| OpenRouter / Gemini | 5–10s | Only 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+.
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:
| Ratio | Native resolution | Use case |
|---|---|---|
| 1:1 | 1024 × 1024 | Avatars, product shots, social squares |
| 3:2 | 1248 × 832 | Standard photography, editorial, landscape |
| 2:3 | 832 × 1248 | Portrait orientation, book covers |
| 4:3 | 1184 × 864 | Classic photo, presentations |
| 3:4 | 864 × 1184 | Portrait, print media |
| 4:5 | 896 × 1152 | Instagram portrait, fashion editorial |
| 5:4 | 1152 × 896 | Large format, fine art prints |
| 16:9 | 1344 × 768 | Widescreen, hero images, OG cards |
| 9:16 | 768 × 1344 | Stories, vertical video, mobile |
| 21:9 | 1536 × 672 | Ultra-wide, cinematic stills |
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.
| Tier | Largest dimension | Best for |
|---|---|---|
| 0.5K | ≤ 600px | Thumbnails, previews, small cards |
| 1K | ≤ 1024px | Standard web images, blog posts, avatars |
| 2K | ≤ 1600px | Hero images, high-quality editorial |
| 4K | > 1600px | Print-ready, large format, maximum detail |