← StoreShots · Get a key / buy credits
StoreShots API
Base URL: https://storeshots.qaimos.co.uk/api.php. Every endpoint is ?action=<name>, and JSON responses use {"error": "…"} on failure.
Authentication
Send your key as X-API-Key: ss_… or Authorization: Bearer ss_…. Get a free key on the account page or via the API:
curl -X POST -d email=you@example.com "https://storeshots.qaimos.co.uk/api.php?action=signup"
# → 201 {"apiKey":"ss_…","keyPrefix":"ss_AbCdEfG","freeGenerationsPerMonth":3,"note":"Store this key now…"}
The key is shown once, and only its SHA-256 hash is stored. Each email address can hold one key.
Credits, free tier & limits
- 1 generate call = 1 set = 1 credit, no matter how many target sizes it includes (1–5 screenshots, up to 4 sizes).
- Free tier: 3 sets per calendar month (UTC), with a small "Made with StoreShots" watermark.
- Paid credits are used first and remove the watermark. They don't expire.
- Requests that fail validation (bad style, too many files, …) are rejected before any charge, and a failed render is refunded.
- Rate limits (per key): 30 requests/minute and 20 generate calls/hour.
429responses includeRetry-After.
Generate screenshots
POST?action=generate (multipart/form-data)
| Field | Description |
|---|---|
screenshots[] | Required. 1–5 image files (PNG/JPEG/WebP, ≤10 MB each). One slide per file. |
style | glow (default), midnight, sunset, mint, trailing |
device | iphone, iphone-duo, android, ipad. Omit to use each target's default. |
targets | Comma list or JSON array: ios-6.9 (1320×2868), ios-6.5 (1242×2688), android-phone (1080×1920), ipad-13 (2064×2752). Default: ios-6.9,ios-6.5,android-phone |
headline[], caption[] | Text per slide, in the same order as the screenshots |
appName | Used in file names |
gradFrom, gradTo, bgColor, bgMode, headlineColor, captionColor, frameColor, textAlign, screenFit | Optional theme overrides (hex colours; bgMode gradient|solid; screenFit auto|cover|contain) |
payload | Alternatively, all of the above as one JSON string: {"style":"mint","targets":["android-phone"],"slides":[{"headline":"…","caption":"…"}],"theme":{…}} |
curl -H "X-API-Key: $STORESHOTS_API_KEY" \ -F style=midnight -F device=iphone -F targets=ios-6.9,ios-6.5 -F appName="Habit Loop" \ -F "headline[]=Build habits that stick" -F "caption[]=One-tap daily check-ins" \ -F "headline[]=See your progress" -F "caption[]=Clear weekly insights" \ -F "screenshots[]=@home.png" -F "screenshots[]=@stats.png" \ "https://storeshots.qaimos.co.uk/api.php?action=generate"
Response 201:
{
"jobId": "20260929-a1b2c3d4e5", "style": "midnight", "device": "iphone", "watermark": false, "billing": "credit",
"targets": [{ "id": "ios-6.9", "size": "1320x2868", "device": "iphone",
"files": [{ "path": "ios-6.9/habit-loop-01-1320x2868.png", "url": "…?action=file&id=…&path=…" }] }],
"zip": "habit-loop-storeshots.zip",
"links": { "self": "…?action=job&id=…", "zip": "…?action=zip&id=…" },
"balance": { "credits": 41, "free": { "limit": 3, "used": 1, "remaining": 2 } },
"warnings": []
}
Outputs are private to your key and are deleted after 24 hours. Download them with zip / file (send the same API key).
All endpoints
| Endpoint | Auth | Description |
|---|---|---|
GEThealth | no | Server status and capabilities |
POSTsignup | no | email (form or JSON) → new API key (shown once). 5 signups/hour per IP |
GETpacks | no | Credit packs, prices and free-tier size |
GETbalance | key | Credits, free sets left, reset date and what the next call will cost |
GETusage | key | Last 50 events (signup, generate, purchase) |
POSTcheckout | key | pack (starter = 10 sets $3, pro = 20 sets $5) → {"checkoutUrl": "https://buy.stripe.com/…?client_reference_id=…"}. Open the Stripe payment link to pay; credits are added automatically by webhook |
GETstyles | key | Styles with colours/layouts |
GETdevices | key | Devices and output targets |
POSTgenerate | key | See above |
GETjob&id= | key | Job manifest |
GETzip&id= | key | ZIP of all PNGs |
GETfile&id=&path= | key | A single PNG |
POSTstripe-webhook | Stripe signature | Internal: Stripe calls this after payment |
MCP server (Cursor, Claude, …)
{
"mcpServers": {
"storeshots": {
"command": "npx",
"args": ["-y", "storeshots-api-mcp"],
"env": { "STORESHOTS_API_KEY": "ss_your_key" }
}
}
}
Tools: list_styles, list_devices, generate_screenshots (local paths or URLs, with optional auto-download), get_output, get_balance, buy_credits. Set STORESHOTS_API_URL to point at a self-hosted api.php.
Self-hosting
api.php runs on ordinary PHP 8.1+ hosting with GD/FreeType (php-zip for ZIPs). Credit packs use Stripe Payment Links plus a signed webhook, so no Stripe secret key or curl is needed. Deploy is flat: every file sits next to index.php, no folders. Accounts are kept in one JSON file (storeshots-data.json, auto-created, locked with flock(), written atomically), so no database or pdo_sqlite is needed. Job outputs go to the PHP temp dir (storeshots-jobs, auto-created) and are deleted after 24 hours. See DEPLOY.md for the exact upload list.
Errors
| Status | Meaning |
|---|---|
| 400 | Invalid input (message says which field) |
| 401 | Missing, invalid or revoked API key |
| 402 | Free tier used up and no credits left. Buy a pack |
| 404 | Unknown action, or the job doesn't exist, has expired or isn't yours |
| 409 | Email already registered |
| 413 | File or request too large |
| 429 | Rate limited. See Retry-After |
| 503 | Feature not configured on this server (e.g. payments) |