HTML and URLs become framed shots and clips.

Same request, same content_hash. Every asset on this page was rendered by the live API in the last 24 hours.

POST /v1/render

{
  "html": "<main><h1>Launch day.</h1></main>",
  "preset": "chrome-light-v1",
  "canvas": "hero",
  "background": "paper",
  "format": "png"
}
A dashboard rendered inside the chrome-dark-v1 browser frame
chrome-dark-v1 · hero · 1600×1000

Render a product shot before you create an account.

Paste self-contained HTML or terminal output, choose a frame, and get a watermarked PNG from the production renderer. No API key is accepted by this page.

Command/Ctrl + Enter to render

Paste self-contained HTML; remote resources are blocked by the renderer.

Shadow
Address

Watermarked · rate limited · HTML or terminal text

Rendered output

Ready

Edit the starter HTML or render it as-is.

One request. The right frame for every surface.

Browser, device, terminal, and laptop presets turn the same source into finished assets without a mockup editor or a design cleanup pass.

Turn a page into a focused product tour.

Four bounded motion recipes produce MP4, WebP, or GIF output using the same frames and presentation controls as stills.

scroll-tour-v1 · chrome-dark-v1 · MP4
Eight evenly spaced frames from the scroll-tour-v1 clip

Frame-stream proof

Inspect the whole clip at a glance.

Each clip reports whether capture stayed deterministic and returns a content_hash over the composed frame stream.

Recipe
scroll-tour-v1
Deterministic
Yes
content_hash
Loading manifest…
Download the MP4

Make visual changes verifiable in CI.

Add an idempotency key, poll the job, and compare content_hash before you publish a changed asset.

Same request
Stable frame-stream hash
Failed render
Credits refunded
Stored output
Public URL by render ID

CI · poll and assert content_hash

response=$(curl --silent --fail-with-body \
  "$SHOTCURATOR_API_URL/v1/render" \
  -H "Authorization: Bearer $SHOTCURATOR_API_KEY" \
  -H "Idempotency-Key: $GITHUB_SHA" \
  -H "Content-Type: application/json" \
  --data @render.json)

job_id=$(jq -r '.id' <<< "$response")
job=$(curl --silent --fail-with-body \
  "$SHOTCURATOR_API_URL/v1/jobs/$job_id" \
  -H "Authorization: Bearer $SHOTCURATOR_API_KEY")

test "$(jq -r '.content_hash' <<< "$job")" = \
  "$(cat .shotcurator-hash)"

Use HTTP directly or connect your tools with MCP.

Start with curl, then give an MCP-compatible client the same render, recipe, and credit tools.

curl · render a framed still

curl "$SHOTCURATOR_API_URL/v1/render" \
  -H "Authorization: Bearer $SHOTCURATOR_API_KEY" \
  -H "Content-Type: application/json" \
  --data @request.json \
  --output product-shot.png

MCP · connect the render tools

SNAPHTML_BASE_URL="$SHOTCURATOR_API_URL" \
SNAPHTML_API_KEY="$SHOTCURATOR_API_KEY" \
pnpm mcp

# Tools include:
# render_product_shot
# render_terminal
# render_clip
# list_recipes

Plans for prototypes through production.

One still costs one credit. Clips cost five credits per second of output.

Free

$0/ month

Explore the API and build a first integration.

  • 100 credits each month
  • All still and clip recipes
  • 24-hour output retention
  • Watermarked framed renders
Try the playground

Starter

$29/ month

For regular product shots and release assets.

  • 3,000 credits each month
  • No render watermark
  • Permanent paid output retention
  • $9 per 1,000 extra credits
View the API

Scale

$299/ month

For high-volume rendering across a product portfolio.

  • 45,000 credits each month
  • No render watermark
  • Permanent paid output retention
  • $9 per 1,000 extra credits
View the API
How do motion clips use credits?

Clips reserve five credits per requested second, then settle at their measured duration. Unused reserved credits are released.

What happens when a render fails?

Validation, security blocks, missing selectors, timeouts, and browser failures cost zero. Any job hold is refunded.

Make the output part of your workflow.