Platform

Examples

Submit-and-poll in the two most common stacks. Both run server-side — never expose your key to browsers.

Prefer not to write code? Submit a URL from the dashboard instead. It submits the same job, polls it every five seconds, and hands back the same hosted image URL.

Node / Next.js server action

screenshot.ts
const BASE = "https://previewapi.dev/api/v1";
const KEY = process.env.PREVIEWAPI_KEY;

export async function capture(url) {
  const job = await fetch(`${BASE}/screenshots`, {
    method: "POST",
    headers: { "Content-Type": "application/json",
               Authorization: `Bearer ${KEY}` },
    body: JSON.stringify({ url, mode: "viewport", format: "png" })
  }).then(r => r.json());

  const deadline = Date.now() + 120_000;

  while (Date.now() < deadline) {
    await new Promise(r => setTimeout(r, 5000));
    const s = await fetch(`${BASE}/screenshots/${job.job_uuid}`, {
      headers: { Authorization: `Bearer ${KEY}` }
    }).then(r => r.json());
    if (s.status === "completed") return s.image_url;
    if (s.status === "failed") throw new Error(s.error);
  }

  throw new Error("Capture did not finish within 2 minutes");
}

Python

screenshot.py
import os, time, requests

BASE = "https://previewapi.dev/api/v1"
H = {"Authorization": f"Bearer {os.environ['PREVIEWAPI_KEY']}"}

def capture(url):
    job = requests.post(f"{BASE}/screenshots", headers=H,
        json={"url": url, "mode": "viewport", "format": "png"}).json()

    deadline = time.monotonic() + 120
    while time.monotonic() < deadline:
        time.sleep(5)
        s = requests.get(f"{BASE}/screenshots/{job['job_uuid']}", headers=H).json()
        if s["status"] == "completed":
            return s["image_url"]
        if s["status"] == "failed":
            raise Exception(s["error"])

    raise Exception("Capture did not finish within 2 minutes")

Both loops stop after two minutes rather than polling forever, which is also what the dashboard does — a job that has said nothing for that long is settled by the service, not by the client.