shotbot
v2.0.0
Published
CLI for the Shotbot screenshot API
Maintainers
Readme
shotbot-node-cli
A single-file Node.js CLI for the Shotbot screenshot API. Same flag names, exit codes, and config-file layout as the PHP and Python clients | scripts written for one work as-is with the others.
Documentation: https://www.shotbot.net/screenshot-cli-tools/ (English) / https://www.shotbot.fr/outil-cli-capture-ecran/ (French).
Requirements
- Node.js 18+ (built-in
fetch) - No third-party dependencies.
Install
npm (recommended)
npm install -g shotbotOr run without installing:
npx shotbot capture --url=https://example.comcurl (single file, no npm)
curl -fsSL https://api.shotbot.net/cli/node/shotbot -o shotbot \
&& chmod +x shotbot \
&& sudo mv shotbot /usr/local/bin/First run
On first use you'll be prompted for your API key. It is saved to
~/.shotbot-node-cli/config.json (chmod 600). Get a key at
https://www.shotbot.net/screenshot-api-key/.
$ shotbot capture --url=https://example.com
No Shotbot API key configured.
Get one at https://www.shotbot.net/screenshot-api-key/
API key: abc123def456
✓ Saved to /home/you/.shotbot-node-cli/config.json (chmod 600)Usage
shotbot capture --url=https://example.com # saves ./example.com-TOKEN.jpg
shotbot capture --url=https://example.com --output=screenshots/ # into dir, auto-named
shotbot capture --url=https://example.com --output=hero.jpg # exact path
shotbot capture --url=https://example.com --full-page --color-scheme=dark # saves to cwd
shotbot capture --url=https://example.com --cdn # public CDN URL, no file
shotbot capture --url=https://example.com --json | jq . # machine output, no filePrivacy: captures are private by default and saved to the current directory (auto-named
HOST-TOKEN.FMT). They are not published onstatic.shotbot.net: the worker writes the file to a non-public directory on the server, the CLI fetches it fromapi.shotbot.net, and the server-side copy auto-expires after a short retention window. No public URL is ever created, which is useful for sensitive pages (intranet, dashboards, customer data). Pass--cdnfor a permanent public CDN URL instead (no local file is saved).
Capture options
Free tier
| Option | Values | Default |
| ------------------- | --------------------------------------------------------------------------------------------------- | -------- |
| --url | http(s) URL (required) | |
| --preset | og, mobile, youtube_thumbnail, square, reel, pinterest, tablet (fills viewport / output-size / crop-height in one go) | off |
| --frame | rounded, shadow, browser_chrome, browser_chrome_dark, mobile, mobile_light, tablet, tablet_light, laptop, polaroid, gradient, shotbot_brand (free accounts get a shotbot.fr/.net mark; Pro removes it) | off |
| --format | jpg, png, webp, webp_lossless, avif, pdf | jpg |
| --viewport | 360..1920 (px) | 1280 |
| --output-size | 120..1920 (resize the result, px) | viewport |
| --wait | Free 0..5, Pro 0..30 (seconds after page load) | 5 |
| --ratio | 16:9, 4:3, 1:1, 9:16, etc. | 16:9 |
| --full-page | flag | off |
| --nojs | flag (disable JavaScript before navigation) | off |
| --color-scheme | dark | light (sets prefers-color-scheme) | off |
| --hidpi | flag (2x DPR) | off |
Pro
| Option | Values |
| --------------------- | ---------------------------------------------------------- |
| --dismiss-cookies | accept | reject (auto-handle cookie consent banners) |
| --scroll | flag (scroll the page before capture; lazy-load trigger) |
| --block-ads | flag (block ad-network requests) |
| --crop-height | 10..30000 (crops the result, overrides ratio, implies full-page) |
| --selector | CSS selector (capture only the matched DOM element) |
| --render-region | fr-paris (free, default) | ca-montreal | sg-singapore | au-sydney | vn-hanoi — render from a real local IP in that region (see https://www.shotbot.net/geolocated-screenshots/) |
| --http-auth-user | string (HTTP Basic Auth user) |
| --http-auth-pass | string (HTTP Basic Auth password) |
PDF (only when --format=pdf)
| Option | Values | Default |
| --------------------- | --------------------------------------------------- | -------- |
| --pdf-page-size | A4, A3, A5, Letter, Legal, Tabloid | A4 |
| --pdf-margin | 0..50 (page margin in mm) | 10 |
| --pdf-scale | 0.10..2.00 (rendering scale) | 1.00 |
| --pdf-landscape | flag (landscape orientation) | off |
CLI ergonomics
| Option | Values | Default |
| -------------- | ------------------------------------------- | -------- |
| --output | where to save; see below (default: cwd, auto-named) | cwd |
| --cdn | flag (public CDN URL, no local file; default: private + saved) | off |
| --json | print full JSON response, no chrome (no file saved) | off |
| --timeout | max seconds to wait for the capture | 180 |
Captures are private by default and saved to the current directory (see the
privacy note above). --output only changes where the file goes. Pass --cdn
for a permanent public CDN URL, or --json for machine output | neither saves a
local file.
Where the file goes
By default (no flags), the file lands in the current directory, auto-named.
--output only changes the destination:
| Form | Saves to |
| ---------------------------------- | ---------------------------------------------------------- |
| (no flag) / --output | ./<host>-<short_token>.<format> (cwd, auto-named) |
| --output=screenshots/ | screenshots/<host>-<short_token>.<format> (auto-named) |
| --output=path/to/file.jpg | exactly that path |
Auto filename example for https://www.example.com/:
example.com-a1b2c3d4.jpg (www. stripped, first 8 chars of the job id, format extension).
Persistent defaults
Save options once and they apply to every capture. Per-call flags always win.
shotbot set full-page # always full-page
shotbot set output ./shots/ # always save into ./shots/
shotbot set cdn true # always publish to the public CDN
shotbot set viewport 1440 # always render at 1440 px
shotbot set format webp # always webp
shotbot defaults # show what's stored
shotbot defaults --keys # list every settable key + type
shotbot unset full-page # forget that defaultBooleans accept true/false/yes/no/1/0; bare set <key> on a boolean
is shorthand for set <key> true. Defaults live in the same config.json as
the API key, under a defaults object.
Free tier
| Settable key | Type | Notes |
| ------------------ | -------------- | ---------------------------------------- |
| format | string (enum) | jpg / png / webp / webp_lossless / avif / pdf |
| viewport | int | 360..1920 |
| output-size | int | 120..1920 (resize the result) |
| wait | int | Free 0..5, Pro 0..30 |
| ratio | string | 16:9, 4:3, 1:1, etc. |
| color-scheme | string (enum) | dark | light |
| full-page | bool | |
| nojs | bool | disable JavaScript |
| hidpi | bool | |
Pro
| Settable key | Type | Notes |
| ------------------ | -------------- | ---------------------------------------- |
| dismiss-cookies | string (enum) | accept | reject |
| scroll | bool | scroll before capture |
| block-ads | bool | |
| crop-height | int | 10..30000 |
| selector | string | CSS selector |
| render-region | string (enum) | fr-paris / ca-montreal / sg-singapore / au-sydney / vn-hanoi |
| http-auth-user | string | HTTP Basic user |
| http-auth-pass | string | HTTP Basic password |
PDF (only when format=pdf)
| Settable key | Type | Notes |
| ------------------ | -------------- | ---------------------------------------- |
| pdf-page-size | string (enum) | A4/A3/A5/Letter/Legal/Tabloid |
| pdf-margin | int | 0..50 (mm) |
| pdf-scale | float | 0.10..2.00 |
| pdf-landscape | bool | |
CLI
| Settable key | Type | Notes |
| ------------------ | -------------- | ---------------------------------------- |
| output | string | default save location (path or dir); files save to cwd otherwise |
| cdn | bool | publish to the public CDN, no local file (default: private + saved) |
| timeout | int | max polling seconds |
Other commands
| Command | What |
| ------------------------------- | ------------------------------------------------- |
| shotbot status | Show account plan, credits, quota, captures in flight. |
| shotbot set <key> [value] | Persist a default option. |
| shotbot unset <key> | Clear a persisted default. |
| shotbot defaults [--keys] | List your defaults; --keys lists settable keys. |
| shotbot config | Print the path to the config file. |
| shotbot reset | Re-prompt for the API key. |
| shotbot version | Print the version. |
| shotbot help | Show help. |
Environment
| Variable | Effect |
| ------------------ | ----------------------------------------------------- |
| SHOTBOT_API_KEY | Override the stored key (useful in CI). |
| SHOTBOT_API_BASE | Override the API base URL (default https://api.shotbot.net). |
| NO_COLOR | Disable ANSI color output. |
Exit codes
| Code | Meaning |
| ---- | ------------------------------------------------ |
| 0 | Success. |
| 2 | Bad invocation (missing args, bad config, etc.). |
| 3 | Network error. |
| 4 | API returned an error response. |
| 5 | Waitlisted (quota exhausted). |
| 6 | Capture failed on the server side. |
| 7 | Polling timeout. |
CI example
export SHOTBOT_API_KEY=abc123def456
shotbot capture --url=https://staging.example.com --output=before.jpgLicense
MIT. See LICENSE.
