Framejet
Directories and link previews

Website thumbnail API for directory cards and link previews.

Turn any URL into a thumbnail your pages load with an ordinary img tag. Sign the URL on your server, and the key never reaches the browser.

The problem

A directory needs a current image for every listing. Open Graph images are often missing or generic, uploads go stale, and a screenshot API normally needs a header an img tag cannot send.

How Framejet handles it

Sign the capture parameters once on your server with your Framejet signing secret. Browsers load the signed URL directly; the first view captures the page with cookie banners removed, and repeat views are served from cache.

Thumbnails in an img tag, without exposing your key

A directory card or link preview wants a plain image URL. A normal API call needs an X-Api-Key header, which an <img> tag cannot send, and a key in the query string would be visible to every visitor. A signed URL solves both: your server signs the capture parameters once, and the browser loads the result like any other image.

Fetch your key ID and signing secret once and store them as server environment variables:

curl -H "X-Api-Key: YOUR_KEY" https://framejet.dev/v1/signing-key
# { "key_id": "…", "signing_secret": "…" }

Then build the image URL on the server, for example in a Next.js server component:

import { createHmac } from "node:crypto";

// Server-side only: FRAMEJET_SIGNING_SECRET never reaches the browser.
export function thumbnailSrc(pageUrl: string) {
  const q = new URLSearchParams({
    url: pageUrl,
    key_id: process.env.FRAMEJET_KEY_ID!,
    width: "1280",
    height: "800",
    format: "jpeg",
  }).toString();
  const sig = createHmac("sha256", process.env.FRAMEJET_SIGNING_SECRET!).update(q).digest("hex");
  return `https://framejet.dev/v1/take?${q}&sig=${sig}`;
}
<img src={thumbnailSrc(listing.url)} alt={`${listing.name} homepage`}
     width="320" height="200" loading="lazy" />

The signature covers every parameter. Nobody can reuse your URL to capture a different page or change its size, so a published thumbnail URL can only ever return that one image. Signing details and a Python example are in the signed URL reference.

What a directory of thumbnails costs

The first view of a signed URL captures the page and uses one screenshot. After that, browsers and the CDN keep the image for a day, and Framejet serves it from its own cache for seven days without spending quota. A thumbnail that is viewed at least once a week therefore costs at most about one screenshot a week.

ListingsScreenshots per month, at mostPlan
40about 175Free (200)
1,000about 4,330Starter (5,000)
5,000about 21,700Pro (25,000)

Listings nobody opens cost nothing, and failed captures never use a credit. See pricing for the plans.

Size and format

Framejet renders the page at the width and height you set and returns an image of that size; it does not resize it down afterwards. For cards, capture at a desktop layout such as 1280 by 800 and let CSS display it smaller. format=jpeg keeps the file much lighter than PNG for photo-heavy pages. Clean mode removes cookie banners and chat widgets first, so the thumbnail shows the page rather than a consent dialog.

Signed requests always use the cache, so a thumbnail refreshes once its cached copy is seven days old. To stop a URL from working after a date, add expires before signing.

Key stays private

Only the key ID and a signature appear in the URL. The signature covers every parameter, so the URL cannot be reused for another page.

Cached by default

Browsers and the CDN keep each image for a day and Framejet for seven, so a thumbnail costs about one screenshot a week at most.

Clean images

Cookie banners, consent walls and chat widgets are removed before capture, so cards show the page rather than a dialog.

Try it on the page your current script cannot reach. No card, 200 screenshots a month, and failures never spend a credit. Get a key.