Bring clean captures. Keep the exact order.
Source images are the UI inside your design. Use original captures with measured dimensions, then bind them to the captions and target format you intend to deliver.
Keep a source manifest containing file names, platform and returned IDs so you can match each capture to its screenshot. Store images may already include frames and captions; use clean captures where possible. Upload captures to your App profile before generating the finished images.
Upload and list your captures
Send PNG, JPEG or WebP as a data URL, up to 10 MiB and 16 megapixels. The server sanitizes the image and returns an opaque sourceId with measured dimensions. There are at most 64 sources per App profile. Identical source uploads recover the same source rather than adding another copy.
/developer/apps/{id}/screenshots/developer/apps/{id}/screenshotsimport { readFile } from "node:fs/promises";
const appId = "YOUR_APP_ID";
const bytes = await readFile("./captures/home.png");
const response = await fetch(`https://api.applistinglab.com/api/v1/developer/apps/${appId}/screenshots`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APP_LISTING_LAB_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ platform: "android", dataUrl: "data:image/png;base64," + bytes.toString("base64") }),
});
if (!response.ok) throw new Error(`Source upload HTTP ${response.status}`);
const source = await response.json();
// Persist source.sourceId, width and height with the local file name.Use platform: "ios" for iPhone/iPad captures and "android" for Android. Repeat uploads sequentially; honor Retry-After. Use the returned source IDs to select these captures in your generation requests.
Bind source and copy per frame
Discover a compatible device and design first. Persist the returned design revision, then send frames in display order. Each entry has sourceId, title (up to 100 characters), and optional subtitle (up to 160). Reusing a source across different frames is allowed. The array determines the count; if you also send count, it must match. Do not combine frames with captions.
{
"appId": "665f0a2b9c1e4d0012ab34cd",
"device": "android-phone",
"designId": "bright-bites",
"designVersion": 1,
"frames": [
{
"sourceId": "SOURCE_ID_FROM_UPLOAD",
"title": "Log meals in moments"
},
{
"sourceId": "SECOND_SOURCE_ID",
"title": "See your daily progress"
}
]
}The revision above is illustrative. Obtain the actual current designId/designVersion from GET /developer/screenshots/designs; do not hard-code a template count or guess a revision. The optional prepare route can validate compatibility. Then render and download using the screenshot guide.