POST /v1/renders takes one JSON request (a style preset, set-wide theme tokens, and a slide per screenshot) and returns store-ready PNGs plus a compliance lint report in one round trip. Deterministic by design: your real UI is composited pixel-exact and never regenerated by AI.
Sign up (instant).Create an account and open the dashboard. Free accounts start with 3 watermarked screenshots.
Create an API key. Grab a live key (prefix asa_live_) from your dashboard, or a test key (asa_test_) for watermarked renders that never bill credits.
POST your first render. Send one JSON request to /v1/renders with your real screenshots. The call below returns in one round trip.
Get CDN URLs back. The response carries finished PNG URLs, the compliance lint report, and the credit count.
One call does the whole job: describe the set, point at your real screenshots, and get back finished images. The example below renders a three-slide iPhone 6.9" set with the aurora-midnight preset, a brand accent, clay device frames, and a star-rating proof overlay. Set APPSCREENSHOTAPI_KEY to your key and run it as-is (swap the screenshot URLs for your own).
The response returns CDN-hosted images (never base64), the lint report, and the credit count. Renders are synchronous by default within a 25-second budget; rendered images are retained for 30 days at the returned URLs.
Authenticate every request with a Bearer token. Live keys are prefixed asa_live_; test keys are prefixed asa_test_ and render watermarked output without consuming paid credits.
Store keys in CI secrets (recommended env var: APPSCREENSHOTAPI_KEY). Never commit keys or print them in logs, agents included.
Idempotency and retries
Send an Idempotency-Key header (Stripe semantics) to make retries safe: replays of the same key within 24 hours return the original response instead of rendering and billing twice.
Idempotency-Key: release-42-en-us
Every response includes rate-limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. On 429, retry after the window in Retry-After.
The request cascade
Every field is optional. Styling resolves in a cascade: preset → theme → slide. A named preset gives you a complete look from the style gallery; theme overrides lock set-wide tokens on top of it; individual slides override last. An empty request body with two screenshots still renders a clean default set.
Field
Type
Description
preset
enum
One of 17 named looks, e.g. aurora-midnight. Sets background, typography, frame style, and shadows in one token. See the visual gallery and options reference.
canvas.preset
enum
Output canvas. See canvas presets. Defaults to appstore.iphone_6_9.
One entry per output screenshot, in store order. See slides.
async
boolean
Default false (sync render in one round trip). Set true for 202 + polling URL. See async mode.
webhook_url
string (url)
Callback URL for async renders. Poll GET /v1/renders/{id} or receive the signed callback payload on completion.
output.locales
string[]
BCP-47 locale tags to fan the set out across markets. Per-locale headline strings are keyed by locale tag.
output.stores
enum[]
"appstore", "play" to render the same set for multiple stores in one request.
output.format
enum
images (default) or fastlane_zip to also receive a deliver-ready archive URL alongside the images.
Theme tokens
Theme tokens are locked across the whole set, which is what makes the output read as one listing instead of six unrelated images: one background system, one type scale, one device treatment.
Background
Field
Values
Notes
background.style
mesh · image · gradient · duotone-split · solid · flat · paper · dark · minimal
Backgrounds render panoramically as one continuous composition that flows across all slides in the set.
background.color
hex color
Base color for solid/gradient/duotone styles.
background.mesh.points[]
{ color, at, stop, alpha }
Control points for mesh/aurora gradients. at is a position like "top-left" or "30% 60%".
background.image
{ url, treatment }
Photo backgrounds with a legibility treatment: dark-scrim · light-scrim · color-wash · blur-band.
Brand accent used for highlighted headline words, pills, and details. A WCAG auto-contrast guard adjusts the rendered tone when the raw color would be unreadable on the background, and reports the adjustment in lint.
Nine webfont treatments (see the options reference for each). The type scale is computed once for the longest headline in the set, then locked across every slide.
headline.align
left · center · right
Caption block alignment.
device.id
iphone-16-max · pixel-9-pro · ipad
Device body used to frame screenshots.
device.frame
{ style, tint }
real (photoreal bezel) · clay · flat, with an optional hex tint on clay/flat frames.
device.shadow.elevation
none · low · medium · high
Dual-layer shadows, automatically tuned to background luminance.
device.alignTops
boolean
Aligns device tops across the whole set so the row reads as one composition in the store gallery.
captionPosition
top · bottom
Headline above or below the device.
Slides
One slide per output image, in store order. Roles drive the story-flow layout system. A hook opens big, feature slides carry the middle, proof slides emphasize overlays, and a close ends with a call to action.
Field
Values
Notes
role
hook · feature · proof · close
Slot in the set narrative; affects layout emphasis.
headline
{ lines[], accent }
Explicit line breaks via lines; accent names the word or phrase rendered in the brand accent color.
Composite several framed screenshots on one canvas (dual-phone, or phone + iPad ecosystem) instead of a single screenshot. Each entry overrides device, frame, tilt, and geometry. See options reference.
tilt
none · left · right · subtle-left · subtle-right
3D perspective tilt on the framed device.
bridge
left · right
Lets the device straddle adjacent slides. Combined with the panoramic background, this produces the multi-panel “one big image” effect in the store gallery.
overlays[]
see below
Proof elements composited onto the slide.
type, icon, name, tagline
type: "brand"
Brand and close slides render app icon, name, and tagline with no device, typically the first or last panel.
Overlays
Kind
Renders
stars
Star rating with optional review count.
laurel
Award laurel with a caption, e.g. “App of the Day”.
pill
Trust pill for short claims like “No ads · No tracking”.
quote-card
Testimonial card with quote, name, and handle.
press-quote
Publication quote with source attribution.
review-stack
Stacked mini-reviews for proof slides.
Image input
Screenshots are URL-first: pass { "url": "https://…" } and the renderer fetches it server-side through an SSRF-safe pipeline (public hosts only, no internal addresses, redirects validated). Inline base64 via { "b64": "…" } works when assets are not hosted anywhere.
PNG, JPEG, and WebP input; output is always PNG.
Up to 10 MB per image, decoded.
Up to 32 MB total per request.
Captures are scaled and composited pixel-exact, never upscaled by AI, never redrawn.
The response
Successful renders return the render object: an id (prefix rnd_), status, images[] with url, width, and height per export, the lint report, credits_used, and expires_at.
Images are CDN URLs, never base64, retained for 30 days.
credits_used equals the number of final exported images (1 credit = 1 screenshot).
With output.format: "fastlane_zip", the response also includes an archive.url arranged in the folder structure deliver expects.
Re-render any time: the engine is deterministic, so the same request body reproduces the same pixels.
The lint report
Every response, sync or async, includes lint, a machine-readable compliance report. Each finding carries the rule, a pass / warn / fail status, measured values where relevant, and an authority tag: OFFICIAL for written store rules and HEURISTIC for best-practice checks. Agents can read the report and self-correct the request without a human in the loop.
Rule
Authority
Checks
apple_dimensions
OFFICIAL
Exact App Store Connect dimension validation for the requested canvas.
play_text_area
OFFICIAL
Google Play’s rule that text and promo elements stay under 20% of the image area.
banned_phrases
OFFICIAL
Disallowed store claims in captions like “#1”, “best app”, ranking and award claims without attribution.
headline_contrast
HEURISTIC
WCAG contrast ratio of every caption against its rendered background, with measured ratios per slide.
thumbnail_legibility
HEURISTIC
Whether the first slide’s headline survives store-card thumbnail size.
duplicate_keywords
HEURISTIC
Repeated caption keywords across slides that waste gallery space.
accent_contrast_adjusted
HEURISTIC
Reports when the auto-contrast guard shifted your accentColor for readability, and by how much.
Async mode and polling
Small sets render synchronously within a 25-second budget. For large locale or store matrices, send "async": true and the API responds immediately with 202 plus a polling_url:
webhook_url lets automation receive the finished render object as a callback signed with X-ASA-Signature (HMAC-SHA256). CI jobs can also poll the polling_url when a build runner needs to wait inline.
Fetch images and archives
Image URLs in the render object are the simplest way to grab output. You can also fetch a single image or the whole set directly from the render:
GET /v1/renders/{id}/images/{filename} streams one rendered PNG.
GET /v1/renders/{id}/archive returns the full set as a deliver-ready archive (render with output.format: "fastlane_zip").
# Re-fetch a single rendered image during the 30-day window
curl -L https://api.appscreenshotapi.com/v1/renders/rnd_8Fq2yK/images/01.png \
-H "Authorization: Bearer $APPSCREENSHOTAPI_KEY" \
-o 01.png
# Or download the whole set as a deliver-ready archive
# (requires output.format: "fastlane_zip" on the render)
curl -L https://api.appscreenshotapi.com/v1/renders/rnd_8Fq2yK/archive \
-H "Authorization: Bearer $APPSCREENSHOTAPI_KEY" \
-o screenshots.zip
Errors
Errors use Stripe-style bodies with a stable type, code, human-readable message, offending param, and a doc_url:
400/422: invalid request; param points at the field.
401: missing or invalid API key.
402: out of credits. The error includes a Stripe Checkout billing_url; agents should show it to a human and wait for explicit approval.
429: rate limited; respect Retry-After.
Canvas presets
Canvases map to the exact dimensions App Store Connect and Google Play accept. Every export is validated against the store rule before it counts against your balance.
Preset
Store target
Output
Also accepted
appstore.iphone_6_9
iPhone 6.9" (required iPhone size)
1290 × 2796
1260 × 2736 · 1320 × 2868
appstore.iphone_6_5
iPhone 6.5" (legacy size)
1284 × 2778
1242 × 2688
appstore.ipad_13
iPad 13" (required iPad size)
2064 × 2752
2048 × 2732
play.phone
Google Play phone, portrait
1080 × 1920
n/a
play.phone_landscape
Google Play phone, landscape
1920 × 1080
n/a
Slides can mix device bodies on one canvas. Dual-phone and phone + iPad compositions are layout options, not extra requests. Pass a fixed canvas.width / canvas.height instead of a preset for custom marketing sizes.
Locales and stores
output.locales fans the set out across markets in the same request. Per-locale headline strings are keyed by BCP-47 tag, RTL locales mirror automatically, and text fitting keeps long translations inside the locked type scale. output.stores renders the same design for appstore and play canvases at once.
POST /v1/briefs is the one optional AI surface: it turns a one-sentence brief into an editable /v1/renders request body: a full design spec with preset, theme tokens, and slide copy. Review or edit the spec, then render it deterministically. AI proposes the design; it never touches your pixels.
It is bring-your-own-key: pass an llm object with your provider (openai, anthropic, gemini, or openrouter), model, and key. You pay your own LLM provider for the call; appscreenshotapi never bills render credits for it. The key is used once for the upstream request and is never stored, cached, or logged. The drafted spec is validated against the exact /v1/renders schema before it is returned, so it always renders.
curl -X POST https://api.appscreenshotapi.com/v1/briefs \
-H "Authorization: Bearer $APPSCREENSHOTAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"brief": "A calm, dark, premium look for a habit tracker aimed at indie builders",
"screenshots": [
{ "url": "https://acme.app/shots/home.png" },
{ "url": "https://acme.app/shots/streaks.png" }
],
"llm": {
"provider": "openai",
"model": "gpt-4o-mini",
"key": "$YOUR_OWN_LLM_KEY"
}
}'
# Bring your own LLM key: you pay your provider, never render credits.
# Providers: openai, anthropic, gemini, openrouter (vendor/model strings).
# The key is used once for the upstream call and is never stored or logged.
# → returns an editable /v1/renders request body (a design spec),
# which the deterministic engine renders. AI never touches pixels.
Credits and limits
One credit equals one final exported screenshot image, matching pricing: a 6-slide set rendered to 2 canvases in 2 locales uses 24 credits. Free accounts start with 3 watermarked screenshots; packs are $18 for 1,000 and $48 for 3,500.
When a key runs out, the API returns 402 with a Stripe Checkout billing URL. Payments and store uploads always remain explicit human approval steps.
Agents and MCP
The API is built to be operated by coding agents: one tool call renders a full set, the request schema is published at /openapi.json (every style enum included), and the lint report is machine-readable so an agent can adjust the request and re-render until checks pass. To discover every available value, scrape the flat options reference or browse the visual gallery.
The agent contract exposes render_set and draft_brief style operations over the same API. Point your agent at the REST endpoints above and use the discovery files: /llms.txt and /.well-known/api-catalog. Agents can also create accounts through the standard form at /register.
SDKs, CLI, and CI
The API is plain REST plus JSON, so every language works today with its built-in HTTP client: the curl examples above translate directly to fetch, requests, or any client. See the Node and Python guides for ready-to-run raw-HTTP snippets.
The SDK guides show direct HTTP integrations for renders and briefs in Node and Python. CI helpers, GitHub Actions, and Fastlane lanes can take a render.json request file and write the finished set into deliver-ready folders are also planned. See CI/CD for current pipeline examples.