TypeScript SDK
The official TypeScript and JavaScript SDK, @draggable/storeshot-sdk - a typed client with waits, uploads, archives, safe retries and webhook verification for Node.js, Bun, Deno and edge runtimes.
@draggable/storeshot-sdk is the official client for the StoreShot API. It is typed from the
OpenAPI contract, has no runtime dependencies and runs on Node.js 18 or later, Bun,
Deno and edge runtimes. It is published on
npm under the Apache-2.0 licence, with its
source on GitHub.
Install
npm install @draggable/storeshot-sdk
Set up the client
new Storeshot() reads the API key from the STORESHOT_API_KEY environment variable (or pass
apiKey). Start with a free test key: everything works, but the images are samples of the exact
size and no credits are used (Test mode). Live keys make the real images and
spend 1 credit per image. Call the API from your server or build script, never from a browser:
the SDK refuses to run in one by default, because every visitor could read the key.
On an edge runtime, pass the key explicitly: new Storeshot({ apiKey: env.STORESHOT_API_KEY }).
A tool without a key can get one with its human’s approval: a client created with
new Storeshot({ apiKey: null }) can call only client.auth.*, and auth.linkAccount runs the
device flow described in Authentication.
From one screenshot to a listing
From one raw screenshot (home.png) to an App Store listing in fastlane’s folder layout:
import { Storeshot } from '@draggable/storeshot-sdk';
const storeshot = new Storeshot(); // reads STORESHOT_API_KEY
const upload = await storeshot.uploads.create({ file: './home.png' });
const set = await storeshot.screenshotSets.create({
app: { name: 'Trailmate' },
screens: [{ input: { uploadId: upload.id }, caption: 'Find every trail' }],
stores: [{ store: 'app_store' }],
});
const done = await storeshot.waitForScreenshotSet(set);
console.log(done.status, `${done.counts.succeeded}/${done.images} images`);
await storeshot.screenshotSets.downloadArchive(done.id, 'listing.zip', { layout: 'fastlane' });
Unzip listing.zip in your project root: fastlane deliver reads fastlane/screenshots/. With a
live key, ask for the price first: await storeshot.screenshotSets.quote(body) returns images,
credits and sufficient and creates nothing. For a single image use
storeshot.generations.create() and storeshot.waitForGeneration(); storeshot.devices.list()
lists the output sizes. See Screenshot sets and
Generations for the request fields.
What the client does for you
- Waits:
waitForGenerationlong-polls withPrefer: wait,waitForScreenshotSetpolls every 3 seconds; both return the final resource (checkstatus) and give up after 10 minutes unless you settimeoutMs. - Uploads and downloads:
uploads.createtakes a file path, bytes, aBlob, a stream or aurl, and checks the 20 MiB limit before sending (Uploads).downloadArchivenever leaves a partial file behind. - Retries:
429and busy503answers are retried afterRetry-Afterfor every request; other server and network errors only where repeating is safe (GET, creates with anIdempotency-Key, quotes).generations.createandscreenshotSets.createalways send anIdempotency-Key, so a retry never charges twice; pass your ownidempotencyKeyto make re-running a script safe too. - Errors: every failure is a
StoreshotErrorwith the APIcode,message,requestIdanddetails(Errors). - Webhooks:
constructWebhookEventandverifyWebhookSignaturecheck theStoreshot-Signatureheader against the raw body with Web Crypto (Webhooks). - Keys stay secret: the SDK never logs the key and masks it in
toString(),JSON.stringify()and error messages.
Versions
The package version follows the StoreShot releases; CONTRACT_VERSION is the API contract its
types were generated from. The API changes only additively within a major version, so a newer API
keeps working with an older SDK. The README on npm has the full method reference, one method per
API operation, and the changelog lists what each version added.