Automation

App Store Screenshot API: Render Localized Release Assets

Sep 18, 20269 min readYannickYannick
A saved design becomes a localized screenshot package through the AppLaunchFlow API
A saved design becomes a localized screenshot package through the AppLaunchFlow API

An App Store screenshot API turns saved designs and real app captures into images your release pipeline can use. With AppLaunchFlow, you choose a project, its saved languages, and the device formats; the API returns an asynchronous render job and a validated Fastlane package.

This guide starts with an existing screenshot design and finishes with files ready for review. It uses the public v1 API and the published JavaScript client. It does not assume the API can run your app, translate its interface, or submit it to a store.

Your release workflow
  1. 01

    Capture

    Your UI tests produce real app screens.

  2. 02

    Design

    Save layouts and localized copy in AppLaunchFlow.

  3. 03

    Render

    The API builds a validated screenshot package.

  4. 04

    Release

    Review the images, then upload through Fastlane.

1. Prepare a real project and a restricted API key

Upload real screenshots, choose a design, and save the layout in the AppLaunchFlow editor. Review the phone and tablet compositions separately if you plan to export both. A phone layout is not a substitute for a missing tablet layout.

Open the project's Developer API section as its owner. Create a key restricted to that project. For rendering and download, grant exports:write and exports:read. Add project, asset, or design scopes only if your script reads or edits those resources. Store the secret in an environment variable or your CI secret store.

Screenshot editor showing saved layouts and the variant that an API render uses
Prepare the layouts in the editor before requesting a render. Each requested language and device layout must exist in the selected variant.

The API requires an active Unlimited subscription (€15/month or €99/year) and includes 5 API export jobs per monthly allowance period, shared across projects and keys. Automation adds unlimited API exports for €19/month on top of Unlimited. Rate limits, job-size limits, and AI generation credits still apply. Free and Launch Pass do not include API access. Before starting a batch, read GET /api/v1/account/usage to inspect remaining exports and the renewal time. One job covers its requested language and format matrix; it is not one charge per image.

2. Describe the output in a small configuration file

Save the following as release.json. Replace the example UUID with your project ID. Use the language codes saved in the selected screenshot variant; in this example the project has en and de. Query GET /api/v1/formats to inspect the supported device formats and store locale mappings.

release.json
{
  "projectId": "11111111-1111-4111-8111-111111111111",
  "languages": [
    "en",
    "de"
  ],
  "formats": [
    "ios.phone.6.9",
    "android.phone"
  ],
  "package": "fastlane"
}

Without a variant ID, rendering uses the active screenshot variant. If a workflow also changes designs, resolve the intended variant once and pass that existing variantId to its edits and render request. This avoids an active-variant switch between calls. It does not freeze the underlying source images.

Set APPLAUNCHFLOW_API_KEY privately. Set APPLAUNCHFLOW_RELEASE_ID to a stable identifier of 8–128 characters for this operation, such as a release tag plus the job purpose. Then submit the request:

Submit the render request
curl --fail-with-body \
  https://dashboard.applaunchflow.com/api/v1/renders \
  -H "Authorization: Bearer $APPLAUNCHFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $APPLAUNCHFLOW_RELEASE_ID" \
  --data @release.json

A successful submission returns HTTP 202. Raw REST responses wrap the result in data, with a request ID in meta. Save data.id and data.statusUrl. The request has been accepted; the images are not necessarily ready yet.

3. Poll the job and verify the package

The job lifecycle helps you decide whether to wait, inspect output, or investigate. A successful HTTP response when submitting a job is not the same as a successful render.

Job statusMeaning for your clientNext action
queued, dispatching, renderingThe job has not reached a final resultKeep polling the same job with bounded retries and a deadline
succeededThe package is readyRead the manifest, obtain a download descriptor, and verify the ZIP
failed, cancelledThe operation ended without a usable successful resultInspect the returned error and retain job/request IDs before choosing a new operation
indeterminateDispatch outcome is uncertainInvestigate the existing operation; do not automatically create a new paid job

Request the returned status URL with the same bearer key. Wait for succeeded, respecting rate limits and any Retry-After response. Stop and investigate terminal failed, cancelled, or indeterminate states. A CI timeout alone does not cancel a render.

After success, fetch the manifest and download descriptor. The descriptor contains a short-lived URL, the ZIP's SHA-256 checksum, and its byte size. Download the URL without forwarding the API key to the storage host. Verify both size and checksum before extraction.

The official release examples implement this sequence. Copy release.mjs and unpack-release.py into an examples directory in your integration repository. Review them, install the published client, and commit your dependency lockfile:

Node 24 · official release and extraction helpers
npm install --save-exact applaunchflow@0.7.0
node examples/release.mjs release.json release.zip
python3 examples/unpack-release.py release.zip output

The helper also needs APPLAUNCHFLOW_API_KEY and APPLAUNCHFLOW_RELEASE_ID. It writes a receipt beside the ZIP before waiting. Keep that receipt if the process stops. Use a fresh output path and extraction directory; the helpers intentionally avoid overwriting an existing release package.

4. Know what validation proves

Checked by the package workflowStill checked by your team
Expected files and exact dimensionsThe right app screen is shown in each slot
PNG integrity and opaque pixelsText readability, clipping, and device composition
File limits and checksumsTranslation quality and destination-store policies
Fastlane paths and locale mappingCorrect app, version, and store credentials for upload

Inspect the manifest together with the actual images. Package validation is valuable because it catches mechanical errors before upload, but it cannot decide whether a German headline reads naturally or whether the first image communicates your app's main benefit.

5. Keep translated copy and captured app UI aligned

There are two localization inputs: the marketing text in the design and the app UI inside the capture. Translating a headline does not change an English screen image. Capture localized app states where appropriate, then save each localized composition before requesting the export.

A missing requested translation or device layout fails validation instead of silently reducing the output set. Avoid asking for two language aliases that map to the same store directory. For example, a base language and a regional code can refer to the same destination; use the format catalog to plan one unambiguous output per locale.

Batch within the documented limits: up to 40 languages and 800 files, with no more than 10 screenshots per iOS format and 8 per Android format. As a planning example, six screens × ten languages × three formats produces 180 files. This arithmetic helps estimate a batch; it is not a render-speed promise. The localization workflow covers the creative review.

6. Retry the operation, not the bill

Reuse the same idempotency key and unchanged body when a request or network connection is interrupted. A repeated operation can recover its existing render. A changed body with the old key produces a conflict. To export a genuinely new set of edits, create a new release identity.

Do not turn every failure into a new POST with a random key. Save request IDs and render IDs, check the current state, and distinguish rejected input from a render whose dispatch outcome is uncertain. The latter needs investigation before a new paid operation.

Layout changes are visible in the editor. Accepted jobs retain the submitted layouts, but source files remain in project storage and their bytes are mutable. Sequence writes before rendering and keep source assets stable until the export finishes. Use the GitHub Actions guide to retain receipts and serialize release jobs.

7. Hand reviewed assets to the upload tool

The ZIP contains iOS assets under fastlane/screenshots/LOCALE and Android assets under fastlane/metadata/android/LOCALE/images. Use the Fastlane integration workflow to send approved output to the stores. Apple's upload API is a separate system with separate credentials; see the App Store Connect screenshot API guide for that boundary.

Frequently asked questions

Can I render screenshots with a single API request?

One POST /api/v1/renders request starts a job for the selected saved languages and formats. Rendering is asynchronous: poll the job and download the validated package after it succeeds. The request does not capture your app or create missing translations.

What happens if a saved translation is missing?

The validated render workflow rejects missing requested languages or device layouts before dispatch. Save the required translation and layout, then submit the corrected request using a new operation key.

How are API exports billed?

The API requires an active Unlimited subscription (€15/month or €99/year) and includes 5 API export jobs per monthly allowance period, shared across projects and keys. Automation adds unlimited API exports for €19/month on top of Unlimited. Rate limits, job-size limits, and AI generation credits still apply. Free and Launch Pass do not include API access.

Reference and next steps

Related Articles

Render saved designs into localized Fastlane packages. Unlimited includes 5 API export jobs per monthly period.

Connect screenshot production to your release