Skip to content
Launch offer: Mac Manager £9.99 first year

Shotlist guide

Configuration

Every key in Shotlist/shotlist.json with its type, default and an example, the slot table with simulators, sizes and App Store Connect display types, and the locale mapping.

Configuration

A project is configured in Shotlist/shotlist.json. shotlist init writes one to start from. Shotlist reads it at the start of every command and refuses to run if it isn’t valid, naming the problem.

Shotlist ignores keys it doesn’t know, so a misspelt key is silently left out. If a setting seems to have no effect, check its spelling against this page.

A complete example

{
  "version": 1,
  "app": {
    "project": "MyApp.xcodeproj",
    "scheme": "MyApp",
    "bundleID": "com.example.myapp",
    "ascAppID": "1234567890"
  },
  "slots": ["iphone-6.9", "iphone-6.3", "ipad-13", "iphone-duo-outer", "iphone-duo-inner"],
  "locales": ["en-GB", "en-US", "de-DE", "fr-FR"],
  "appearances": ["light"],
  "fixedDate": "2026-06-14T10:30:00Z",
  "timeZone": "Europe/London",
  "statusBar": { "time": "9:41", "battery": 100 },
  "sequence": [
    { "scene": "library", "template": "caption-top" },
    { "scene": "book", "template": "caption-top" },
    { "scene": "stats", "template": "full-bleed", "appearance": "dark" },
    { "scene": "planner", "template": "split", "with": "library" }
  ],
  "capture": { "concurrency": 2, "sceneTimeout": 20, "duoInnerOrientation": "landscape" },
  "creative": {
    "header": { "template": "header-brand", "localised": true },
    "search": { "scene": "library", "template": "search-hero" },
    "universal": true
  }
}

Top-level keys

Key Type Required Default Meaning
version number yes The file format. Must be 1.
app object yes The app to build and where it lives in App Store Connect. See app.
slots array of strings yes The screenshot sizes to capture. See Slots.
locales array of strings yes The locales to capture, such as "en-GB" and "de-DE". The app must declare each one.
appearances array of strings yes "light", "dark" or both.
fixedDate string no "2026-06-14T10:30:00Z" The run’s “now”, as an ISO 8601 date with a time zone. Reaches scenes as context.now and the app as Shotlist.now.
timeZone string no your Mac’s time zone The app’s time zone, as an IANA identifier such as "Europe/London". Set it, so dates render the same on any Mac.
statusBar object no { "time": "9:41", "battery": 100 } The status bar to show. If you give it, give both keys.
sequence array of objects yes The scenes to capture, in product-page order. 1 to 10 entries. See sequence.
capture object no Capture settings. See capture.
creative object no Product page header and search results art. Leave it out to make none. See creative.

How the keys multiply

A run captures every combination of slot, locale and scene, in every appearance unless a sequence entry names its own:

cells = slots × locales × (scenes in each appearance)

Two slots, four locales and five scenes in one appearance make 40 cells. Adding "dark" to appearances doubles that, except for entries that name an appearance.

app

Key Type Required Default Meaning
project string one of these two The .xcodeproj, relative to the folder that holds Shotlist/.
workspace string one of these two The .xcworkspace, relative to the same folder. Used instead of project when both are given.
scheme string yes The scheme to build. It must build the app for the iOS Simulator.
bundleID string yes The app’s bundle identifier. Shotlist finds the built app by it, and finds the app in App Store Connect by it when there’s no ascAppID.
ascAppID string no looked up by bundleID The app’s Apple ID in App Store Connect (App Information › Apple ID). "0000000000" counts as unset.
configuration string no "Debug" The build configuration. It must define DEBUG, or ShotlistKit compiles to nothing.
derivedData string no .shotlist/DerivedData A DerivedData folder to build into, relative to the folder that holds Shotlist/ or absolute. Point it at one that already holds a compiled SDK to save build time.
ascLocales object no the built-in mapping Shotlist locale to App Store Connect locale, where the default mapping doesn’t fit.

Paths are relative to the folder that holds Shotlist/ (the --project-dir), and may climb out of it: "project": "../MyApp.xcodeproj" works.

sequence

Each entry is one screenshot position on the product page, in order.

Key Type Required Default Meaning
scene string yes A scene id from your Screenshots.swift.
template string no "caption-top" The template that composes it. A built-in or one in Shotlist/Templates/. See Captions and composing.
appearance string no every appearance in appearances Captures this entry in one appearance only, "light" or "dark", and composes it in that appearance.
with string no For the split template: the second scene shown beside this one. It must also be in sequence, so it’s captured.

App Store Connect takes 1 to 10 screenshots per size and locale, so sequence has 1 to 10 entries.

Each entry’s position sets the NN in file names: the third entry is 03-<scene>-<appearance>.png in raw captures.

Which appearance is composed. Compose makes one screenshot per entry. For an entry with its own appearance, that’s the appearance it uses. For the others, it uses the first in appearances. Capturing both appearances is useful for review; to publish a dark screenshot, give that entry "appearance": "dark".

capture

Key Type Default Meaning
concurrency number 2 How many simulators run at once. At least 1. Each simulator works through its locales one after another. --concurrency overrides it for one run.
sceneTimeout number 20 Seconds a scene has to become ready, in whole seconds. See Timeouts.
duoInnerOrientation string "landscape" The iPhone Duo’s inner display: "landscape" (2853 × 2007, how it opens) or "portrait" (2007 × 2853, rotated through Device Hub).

Concurrency is per simulator, not per slot: both iPhone Duo slots share one simulator. With slots iphone-6.9, iphone-6.3 and both Duo displays, there are three simulators, and the default runs two at a time. More simulators at once needs more memory; on a Mac with plenty, 3 or 4 is fine.

creative

Product page header and search results art. Leave creative out to make none. See Captions and composing.

Key Type Default Meaning
header object none Make header art.
header.template string "header-brand" The template.
header.localised boolean true One header per locale. With false, one header from the first locale’s captions, written to creative/shared/ and placed on every localisation.
header.scene string none A scene whose capture appears in the header. Header art has no screenshot by default, because the screenshots sit right below it.
search object none Make search results art.
search.scene string required with search The scene whose capture appears in the art. It must be in sequence.
search.template string "search-hero" The template.
search.slot string the first iphone-6.x slot, else the first slot The slot whose capture is used.
universal boolean true Also render the 5244 × 2950 (16:9) alternative of each.

Slots

A slot is one App Store screenshot size and the simulator that produces it natively, so captures are never scaled.

Slot Simulator Runtime (Xcode 27.1) Captured size Sizes Apple accepts App Store Connect display type
iphone-6.9 iPhone 17 Pro Max iOS 27.0 1320 × 2868 1320 × 2868, 1290 × 2796, 1260 × 2736 APP_IPHONE_67
iphone-6.3 iPhone 17 Pro iOS 27.0 1206 × 2622 1206 × 2622, 1179 × 2556 APP_IPHONE_61
ipad-13 iPad Pro 13-inch (M5) iOS 27.0 2064 × 2752 2064 × 2752, 2048 × 2732 APP_IPAD_PRO_3GEN_129
iphone-duo-outer iPhone Duo, outer display iOS 27.1 1398 × 2034 1398 × 2034 APP_IPHONE_DUO, undocumented: uploaded only with --experimental-duo
iphone-duo-inner iPhone Duo, inner display iOS 27.1 2853 × 2007 (landscape) or 2007 × 2853 (portrait) 2007 × 2853 none: exported for upload by hand

Sizes are portrait; Apple accepts each in landscape too. Sizes were checked against Apple’s screenshot specifications on 31 October 2026.

  • iphone-6.3 is the size Apple currently requires for iPhone (“iPhone with Dynamic Island, medium display”).
  • iphone-6.9 is accepted, not required. Capturing it costs little and gives the large-display class its own screenshots.
  • ipad-13 is required if the app runs on iPad.
  • The iPhone Duo’s two sizes are required from April 2027 for apps built with the iOS 27.1 SDK or later. See iPhone Duo.

When a simulator boots, Shotlist checks its framebuffer against this table. If a future simulator produces a size the slot doesn’t accept, the run fails rather than capturing the wrong size.

Each slot’s simulator runs on the newest installed iOS runtime that supports its device.

App Store Connect locales

Shotlist locales are BCP 47 codes such as en-GB. Most are App Store Connect’s codes too. These are mapped by default:

Shotlist locale App Store Connect locale
nb-NO, nn-NO, or any nb-… or nn-… no
Catalan, Czech, Danish, Greek, Finnish, Hebrew, Hindi, Croatian, Hungarian, Indonesian, Italian, Japanese, Korean, Malay, Polish, Romanian, Russian, Slovak, Swedish, Thai, Turkish, Ukrainian, Vietnamese (ca, cs, da, el, fi, he, hi, hr, hu, id, it, ja, ko, ms, pl, ro, ru, sk, sv, th, tr, uk, vi) with any region The language alone, such as sv-SE → sv
Anything else Unchanged, such as en-GB, de-DE, fr-FR, pt-BR

Where that doesn’t match your listing, map it in app.ascLocales:

"ascLocales": { "zh-CN": "zh-Hans", "zh-TW": "zh-Hant" }

The publish plan shows the App Store Connect locale for every row, so you can check the mapping before uploading.

Validation

Shotlist checks the file before every command. These are the errors it can report:

Error Fix
no …/Shotlist/shotlist.json; run `shotlist init` first Run shotlist init, or pass --project-dir pointing at the folder that holds Shotlist/.
…/shotlist.json isn't valid: … The JSON doesn’t parse, or a required key is missing or has the wrong type. The rest of the message names it.
shotlist.json version 2 isn't supported; this Shotlist reads version 1 Set "version": 1, or update Shotlist.
app needs a "project" or "workspace" Add one.
unknown slot '…'; known slots: … Use a slot id from the table.
unknown appearance '…'; use light or dark In appearances or a sequence entry.
sequence is empty Add at least one entry.
sequence has 11 scenes; App Store Connect takes at most 10 per size Remove entries.
fixedDate '…' isn't an ISO 8601 date such as 2026-06-14T10:30:00Z Include the time and a time zone (Z or an offset).