Docs menu

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.

View as Markdown

@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: waitForGeneration long-polls with Prefer: wait, waitForScreenshotSet polls every 3 seconds; both return the final resource (check status) and give up after 10 minutes unless you set timeoutMs.
  • Uploads and downloads: uploads.create takes a file path, bytes, a Blob, a stream or a url, and checks the 20 MiB limit before sending (Uploads). downloadArchive never leaves a partial file behind.
  • Retries: 429 and busy 503 answers are retried after Retry-After for every request; other server and network errors only where repeating is safe (GET, creates with an Idempotency-Key, quotes). generations.create and screenshotSets.create always send an Idempotency-Key, so a retry never charges twice; pass your own idempotencyKey to make re-running a script safe too.
  • Errors: every failure is a StoreshotError with the API code, message, requestId and details (Errors).
  • Webhooks: constructWebhookEvent and verifyWebhookSignature check the Storeshot-Signature header 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.