A directory, bookmark manager, "made with" showcase or portfolio looks far better with a preview image of each site. You don't need a headless browser or a job queue for that: one signed <img> URL per site is enough.
GET /v1/account returns its public key_id.https://shotmint.creasework.com/s/KEY_ID.png?url=…&width=1280&height=800&sig=…. The signature locks the parameters, so nobody can reuse your key for other pages.<img>. The first view renders the page in real Chromium (1 credit); repeats within 24h come from cache for free, with Cache-Control: public, max-age=86400.<img src="https://shotmint.creasework.com/s/KEY_ID.png?url=https%3A%2F%2Fexample.com&width=1280&height=800&sig=..."
alt="Screenshot of example.com" width="320" height="200" loading="lazy">
No code at all? The website thumbnail generator makes these snippets one at a time.
You can ask GET /v1/screenshot/url to sign each URL, but the signature is a plain HMAC, so your server can compute it offline: HMAC-SHA256 with your API key over "shot" plus the 11 signed fields in this order, joined by newlines (empty string for unset fields), hex, first 32 characters. Keep the key on the server; only the key_id appears in the URL.
const crypto = require("crypto");
const FIELDS = ["url", "width", "height", "full_page", "mobile", "device_scale_factor",
"block_ads", "dark_mode", "delay", "wait_until", "hide_selectors"];
function thumbUrl(params) {
const p = Object.fromEntries(Object.entries(params).map(([k, v]) => [k, String(v)]));
const canon = "shot\n" + FIELDS.map(f => p[f] ?? "").join("\n");
const sig = crypto.createHmac("sha256", process.env.SHOTMINT_KEY).update(canon).digest("hex").slice(0, 32);
return "https://shotmint.creasework.com/s/" + process.env.SHOTMINT_KEY_ID + ".png?" + new URLSearchParams({ ...p, sig });
}
thumbUrl({ url: "https://example.com", width: 1280, height: 800, block_ads: true });
import hashlib, hmac, os
from urllib.parse import urlencode
FIELDS = ["url", "width", "height", "full_page", "mobile", "device_scale_factor",
"block_ads", "dark_mode", "delay", "wait_until", "hide_selectors"]
def thumb_url(**params):
p = {k: str(v).lower() if isinstance(v, bool) else str(v) for k, v in params.items()}
canon = "shot\n" + "\n".join(p.get(f, "") for f in FIELDS)
sig = hmac.new(os.environ["SHOTMINT_KEY"].encode(), canon.encode(), hashlib.sha256).hexdigest()[:32]
return "https://shotmint.creasework.com/s/" + os.environ["SHOTMINT_KEY_ID"] + ".png?" + urlencode({**p, "sig": sig})
thumb_url(url="https://example.com", width=1280, height=800, block_ads=True)
Pass booleans as true/false and leave out parameters you don't use (an empty value counts as unset). Any change to a signed field after signing returns 403.
width=1280&height=800 and display at 320×200 with CSS. Add device_scale_factor=2 only if thumbnails are shown large.block_ads=true removes most ads and cookie banners; hide_selectors hides anything else (comma-separated CSS selectors); delay (ms) helps sites with intro animations.mobile=true with width=390&height=844 shows the phone layout.loading="lazy" means you only pay for thumbnails visitors actually scroll to.One new render = one credit. €5 buys 2,000 thumbnails and €19 buys 10,000, and credits never expire. A 500-site directory you refresh monthly costs about €1.25 a month, with no subscription. A failed render (site down, timeout) is refunded automatically.
No signup, no card. Get a key in one click, then buy credits only if you need more (from €5 for 2,000, never expire).
Get a free API key Full API reference