How to screenshot a website from the command line

Five ways, from "I need it once" to "I need 10,000 a day". Each has trade-offs. Pick the one that matches what you're actually doing.

Updated January 2026.

1. The one-liner (no install, no signup)

If you have curl and an internet connection, you can do this right now:

curl "https://api.sitetrace.it.com/api/shot?url=https://example.com" --output shot.png

That's it. The image lands in shot.png. You can open it, attach it to an email, post it on Slack — whatever you need.

This uses our free, no-signup tier. 100 calls/day per IP. Good for "I need to take a screenshot once in a while" and "I want to test what an API can do before I commit".

Trade-off: Goes through our servers, so don't use it for sensitive URLs.

2. With an API key (higher quota, faster)

Sign up at /signup to get a free key (1,000 calls/day). Then:

curl "https://api.sitetrace.it.com/api/shot?url=https://example.com" \
  -H "Authorization: Bearer stk_your_key_here" \
  --output shot.png

Same call, higher quota. If you're doing this 50 times a day, the free tier without a key runs out; this is what you switch to.

3. Headless Chrome on your own machine (free, more control)

If you have node and npm:

npm install puppeteer
node -e "
  const puppeteer = require('puppeteer');
  (async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.setViewport({ width: 1280, height: 720 });
    await page.goto('https://example.com', { waitUntil: 'networkidle0' });
    await page.screenshot({ path: 'shot.png' });
    await browser.close();
  })();
"

You get the full power of headless Chrome: any viewport, full-page capture, dark mode emulation, executing JS before the shot, etc.

Trade-off: Requires ~300 MB of Chrome download, plus the runtime cost of keeping a browser around. Doesn't scale to "screenshot 10,000 URLs in an hour" without infrastructure work.

4. Chrome itself, from the command line (one-off, no install)

Modern Chrome supports a --screenshot flag:

google-chrome --headless --disable-gpu --screenshot=shot.png --window-size=1280,720 https://example.com

(On Windows, it's "C:\Program Files\Google\Chrome\Application\chrome.exe" with the same flags. Or use Edge.)

Only captures the viewport, not the full page. No JS hooks, no waiting, no dark mode. But it works with the Chrome you already have, no install.

5. A screenshot API (the right answer for "I need 10,000 a day")

If you're doing this at scale — link previews for a chat app, OG images for a newsletter tool, screenshots for a marketplace listing — the right answer is an API:

async function getShot(url) {
  const r = await fetch('https://api.sitetrace.it.com/api/shot?url=' + encodeURIComponent(url), {
    headers: { 'Authorization': 'Bearer ' + API_KEY }
  });
  return Buffer.from(await r.arrayBuffer());
}

No Chrome to install, no memory leaks to debug, no bot-detection arms race. The API runs in the vendor's cloud; you just call it. The cost is real (~$0.01–0.05 per shot at scale) but the ops savings are larger.

Our full comparison of screenshot APIs is in the best screenshot APIs 2026 guide.

Which one is right for you

SituationUse this
One-off, no install, right nowOption 1 (curl + no-signup API)
Few per day, want a free quotaOption 2 (curl + free key)
Local script, want control, low volumeOption 3 (Puppeteer)
One screenshot, want the actual installed ChromeOption 4 (chrome --screenshot)
1000+ per day, want someone else to deal with itOption 5 (screenshot API)