/api/shot

Screenshot any URL to PNG.

Real headless Chrome. Three device presets. 5-minute edge cache so popular URLs cost you nothing. Free tier is 100 calls/day, no signup.

Try it now

No signup. Just paste a URL and click.

curl "https://api.sitetrace.it.com/api/shot?url=https://example.com&width=1280&height=720" --output shot.png
Screenshot demo

All the options

ParamDefaultDescription
url requiredFull http(s) URL to screenshot. Protocol is added if missing.
devicedesktopdesktop, mobile, or tablet. Sets viewport + user-agent.
width1280Viewport width in px (clamped 100–3840).
height720Viewport height in px (clamped 100–2160).
fullfalseCapture the full scrollable page, not just the viewport.
wait0Extra ms to wait after page load (max 8000). Use for SPAs that hydrate.
darkfalseEmulate prefers-color-scheme: dark.
formatpngpng or jpeg. JPEG is smaller; PNG is sharper.
quality80JPEG quality (30–100). Ignored for PNG.

Code, in your language

# Free, no key
curl "https://api.sitetrace.it.com/api/shot?url=https://example.com" --output shot.png

# With API key (higher quota, mobile viewport, full page)
curl "https://api.sitetrace.it.com/api/shot?url=https://github.com&device=mobile&full=true" \
  -H "Authorization: Bearer stk_your_key_here" \
  --output github-mobile.png
// Node / browser
const url = 'https://api.sitetrace.it.com/api/shot?url=' + encodeURIComponent('https://example.com');
const res = await fetch(url, { headers: { 'Authorization': 'Bearer ' + API_KEY } });
const blob = await res.blob();
const img = new Image();
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
import requests

r = requests.get(
    'https://api.sitetrace.it.com/api/shot',
    params={'url': 'https://example.com', 'width': 1280, 'height': 720},
    headers={'Authorization': f'Bearer {API_KEY}'},
)
with open('shot.png', 'wb') as f:
    f.write(r.content)
package main

import (
    "io"
    "net/http"
    "os"
)

func main() {
    req, _ := http.NewRequest("GET", "https://api.sitetrace.it.com/api/shot?url=https://example.com", nil)
    req.Header.Set("Authorization", "Bearer "+apiKey)
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    out, _ := os.Create("shot.png")
    defer out.Close()
    io.Copy(out, resp.Body)
}

When to use this vs the URL Preview API

If you need a single image of the page → use /api/shot. If you need just the Open Graph / Twitter Card metadata (title, description, image URL, favicon) for a link preview, use /api/preview — it's faster and doesn't render Chrome. Most apps want both: /api/preview to display a rich link, /api/shot as a fallback for sites without OG tags.