Options reference
Every option of the screenshot API on one page, with its default, its limits and an example value.
An option is one name=value pair added to the request. This request uses three of them:
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&format=webp&viewport_width=1440&dark_mode=true" \
--output example.webpYou get example.webp: example.com in a 1440 pixel wide window, as a WebP file, in its dark theme.
Options work the same in a GET query string and in a POST JSON body. The screenshot URL explains both, and how to write booleans and lists.
A misspelled option is never silently ignored. You get invalid_options with a hint naming the option you probably meant: fullpage gets "did you mean full_page?".
#All options at a glance
| Option | Group | What it does | Default |
|---|---|---|---|
url | Source | Address of the page to capture. | |
html | Source | HTML to render instead of a URL. | |
markdown | Source | Markdown to render as a styled page instead of a URL. | |
format | Output | File format of the result. mp4, webm and gif record a video of the page. | png |
image_quality | Output | Compression quality for jpeg and webp. | 80 |
image_width | Output | Resize the final image to this width. | |
image_height | Output | Resize the final image to this height. | |
omit_background | Output | Keep the page background transparent (png and webp). | false |
response_type | Output | Return the file itself, or JSON with a link to it. | by_format |
viewport_width | Viewport | Width of the browser window. | 1280 |
viewport_height | Viewport | Height of the browser window. A video uses 720 unless you set it. | 1024 |
device_scale_factor | Viewport | Pixel density; 2 gives a retina image. | 1 |
viewport_device | Viewport | Emulate a phone, tablet or laptop preset. | |
viewport_mobile | Viewport | Render the mobile layout (honours the viewport meta tag). | false |
viewport_landscape | Viewport | Rotate the viewport to landscape. | false |
full_page | Capture | Capture the whole page, not just the first screen. | false |
full_page_scroll | Capture | Scroll through the page first so lazy-loaded images appear. | true |
full_page_max_height | Capture | Cut a full-page capture off at this height. | 20000 |
selector | Capture | Capture only the first element matching this CSS selector. | |
clip_x | Capture | Left edge of the area to capture. | |
clip_y | Capture | Top edge of the area to capture. | |
clip_width | Capture | Width of the area to capture. | |
clip_height | Capture | Height of the area to capture. | |
wait_until | Waiting | Page event that marks the page as loaded. | load |
delay | Waiting | Extra time to wait after the page has loaded. | 0 |
timeout | Waiting | Give up if the page is not ready after this long. | 30 |
wait_for_selector | Waiting | Wait until this element is visible before capturing. | |
dark_mode | Customize | Ask the page for its dark theme. | false |
reduced_motion | Customize | Ask the page to turn animations off. | false |
media_type | Customize | CSS media type to render with. | screen |
hide_selectors | Customize | Hide every element matching these CSS selectors. | |
styles | Customize | CSS to add to the page. | |
scripts | Customize | JavaScript to run on the page before the capture. | |
click | Customize | Click the first element matching this selector before the capture. | |
user_agent | Request | User-Agent header the browser sends. | |
headers | Request | Extra HTTP headers, as "Name: value". | |
cookies | Request | Cookies to set, as "name=value; Domain=example.com". | |
authorization | Request | Authorization header sent to the target site only. | |
time_zone | Request | IANA time zone the page sees. | |
block_ads | Blocking | Block requests to ad networks. | false |
block_trackers | Blocking | Block analytics and tracking scripts. | false |
block_cookie_banners | Blocking | Hide cookie consent banners. | false |
block_chats | Blocking | Block live-chat widgets. | false |
block_resources | Blocking | Block whole kinds of resources. | |
block_requests | Blocking | Block requests whose URL matches these patterns (* is a wildcard). | |
pdf_paper_format | Paper size of the PDF. | a4 | |
pdf_landscape | Use landscape pages. | false | |
pdf_print_background | Print background colors and images. | true | |
pdf_margin | Margin on all four sides. | ||
pdf_margin_top | Top margin; overrides pdf_margin. | ||
pdf_margin_right | Right margin; overrides pdf_margin. | ||
pdf_margin_bottom | Bottom margin; overrides pdf_margin. | ||
pdf_margin_left | Left margin; overrides pdf_margin. | ||
pdf_fit_one_page | Put the whole page on a single tall PDF page. | false | |
video_duration | Video | Length of the video. Left out, it follows the height of the page. | |
video_max_duration | Video | Longest the video may get when its length follows the page. A taller page then scrolls faster. | 30 |
video_fps | Video | Frames per second. A gif takes at most 15. | 24 |
video_scroll | Video | Scroll from the top of the page to the bottom while recording. | true |
video_scroll_back | Video | Scroll back to the top at the end, so the video loops cleanly. | false |
video_scroll_easing | Video | How the scroll moves: a soft start and stop, or one even speed. | ease_in_out |
cache | Cache | Serve a stored copy when the same request was made before. | false |
cache_ttl | Cache | How long a cached copy stays valid. | 14400 |
cache_key | Cache | Change this value to force a fresh render. | |
async | Async and webhooks | Return at once and render in the background. | false |
webhook_url | Async and webhooks | Address that receives the result when the render is done. | |
webhook_sign | Async and webhooks | Sign the webhook body so you can verify it came from us. | true |
access_key | Authentication | Your API access key. | |
signature | Authentication | HMAC-SHA256 signature of the query string, for signed links. | |
expires | Authentication | Unix time in seconds after which the request is refused. Put it in a signed link to give the link a lifetime. |
#Source
These options say what to render. You always need exactly one of them. Use url for a page that is already online. Use html or markdown when you have the content yourself, such as an invoice or a social card.
A url must be a full http:// or https:// address on the public internet. The screenshot URL lists the rules, including which ports are accepted.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com" --output example.png#url
Address of the page to capture.
There is no default; leave it out and it is not applied.
Type: text.
Example: url=https://example.com
#html
HTML to render instead of a URL.
There is no default; leave it out and it is not applied.
Type: text.
Example: html=%3Ch1%3EHello%3C/h1%3E
#markdown
Markdown to render as a styled page instead of a URL.
There is no default; leave it out and it is not applied.
Type: text.
Example: markdown=%23%20Hello
Read more: The screenshot URL, HTML and Markdown input.
#Output
Reach for these when the file itself needs to change: a smaller JPEG for a thumbnail, a transparent PNG, or a JSON answer with a link in place of the bytes. The page is drawn the same way. Only what you receive is different.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&format=jpeg&image_quality=70&image_width=640" --output thumb.jpg#format
File format of the result. mp4, webm and gif record a video of the page.
The default is png.
Type: one of a fixed list. Allowed values: png, jpeg, webp, pdf, mp4, webm, gif.
Example: format=png
#image_quality
Compression quality for jpeg and webp.
The default is 80.
Type: whole number. From 1 to 100.
Example: image_quality=80
#image_width
Resize the final image to this width.
There is no default; leave it out and it is not applied.
Type: whole number. From 1 to 8000 pixels.
Example: image_width=640
#image_height
Resize the final image to this height.
There is no default; leave it out and it is not applied.
Type: whole number. From 1 to 8000 pixels.
Example: image_height=400
#omit_background
Keep the page background transparent (png and webp).
The default is false.
Type: true or false.
Example: omit_background=true
#response_type
Return the file itself, or JSON with a link to it.
The default is by_format.
Type: one of a fixed list. Allowed values: by_format, json.
Example: response_type=json
Read more: The screenshot URL.
#Viewport
The viewport is the browser window the page is drawn in. Its size decides which layout a site shows, so this is the group to use when you want the phone version, a wide desktop version, or a sharper image for high-density screens. A device preset sets several of these at once.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&viewport_device=iphone_15_pro" --output phone.png#viewport_width
Width of the browser window.
The default is 1280 pixels.
Type: whole number. From 100 to 3840 pixels.
Example: viewport_width=1280
#viewport_height
Height of the browser window. A video uses 720 unless you set it.
The default is 1024 pixels.
Type: whole number. From 100 to 4320 pixels.
Example: viewport_height=1024
#device_scale_factor
Pixel density; 2 gives a retina image.
The default is 1.
Type: number. From 1 to 3.
Example: device_scale_factor=2
#viewport_device
Emulate a phone, tablet or laptop preset.
There is no default; leave it out and it is not applied.
Type: one of a fixed list. Allowed values: every name on the Devices page.
Example: viewport_device=iphone_15_pro
#viewport_mobile
Render the mobile layout (honours the viewport meta tag).
The default is false.
Type: true or false.
Example: viewport_mobile=true
#viewport_landscape
Rotate the viewport to landscape.
The default is false.
Type: true or false.
Example: viewport_landscape=true
Read more: Devices.
#Capture
These decide which part of the page ends up in the screenshot. By default you get the first screen. Use this group to capture the page from top to bottom, one element, or a rectangle you choose.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&full_page=true" --output full.png#full_page
Capture the whole page, not just the first screen.
The default is false.
Type: true or false.
Example: full_page=true
#full_page_scroll
Scroll through the page first so lazy-loaded images appear.
The default is true.
Type: true or false.
Example: full_page_scroll=false
#full_page_max_height
Cut a full-page capture off at this height.
The default is 20000 pixels.
Type: whole number. From 100 to 30000 pixels.
Example: full_page_max_height=10000
#selector
Capture only the first element matching this CSS selector.
There is no default; leave it out and it is not applied.
Type: text.
Example: selector=%23pricing
#clip_x
Left edge of the area to capture.
There is no default; leave it out and it is not applied.
Type: whole number. 0 or more pixels.
Example: clip_x=0
#clip_y
Top edge of the area to capture.
There is no default; leave it out and it is not applied.
Type: whole number. 0 or more pixels.
Example: clip_y=0
#clip_width
Width of the area to capture.
There is no default; leave it out and it is not applied.
Type: whole number. From 1 to 8000 pixels.
Example: clip_width=600
#clip_height
Height of the area to capture.
There is no default; leave it out and it is not applied.
Type: whole number. From 1 to 30000 pixels.
Example: clip_height=400
Read more: Full-page screenshots, Capturing an element.
#Waiting
Pages do not appear all at once. These options decide the moment the capture is taken. Use them when a screenshot comes back half-loaded, or when a slow page runs out of time.
delay and timeout are in seconds, not milliseconds: delay=1 waits one second, and timeout can be from 1 to 90.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&wait_until=networkidle&delay=1" --output ready.png#wait_until
Page event that marks the page as loaded.
The default is load.
Type: one of a fixed list. Allowed values: load, domcontentloaded, networkidle, commit.
Example: wait_until=networkidle
#delay
Extra time to wait after the page has loaded.
The default is 0 seconds.
Type: number. From 0 to 30 seconds.
Example: delay=2
#timeout
Give up if the page is not ready after this long.
The default is 30 seconds.
Type: number. From 1 to 90 seconds.
Example: timeout=60
#wait_for_selector
Wait until this element is visible before capturing.
There is no default; leave it out and it is not applied.
Type: text.
Example: wait_for_selector=.chart-ready
Read more: Waiting and timing.
#Customize
Use these to change how the page looks before the capture. You can ask for the dark theme, hide an element that is in the way, add your own CSS, run a bit of JavaScript, or click a button.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://developer.mozilla.org&dark_mode=true&hide_selectors=.top-banner" --output dark.png#dark_mode
Ask the page for its dark theme.
The default is false.
Type: true or false.
Example: dark_mode=true
#reduced_motion
Ask the page to turn animations off.
The default is false.
Type: true or false.
Example: reduced_motion=true
#media_type
CSS media type to render with.
The default is screen.
Type: one of a fixed list. Allowed values: screen, print.
Example: media_type=print
#hide_selectors
Hide every element matching these CSS selectors.
There is no default; leave it out and it is not applied.
Type: list of text values.
Example: hide_selectors=.cookie-bar,%23chat
#styles
CSS to add to the page.
There is no default; leave it out and it is not applied.
Type: text.
Example: styles=body%7Bbackground:%23fff%7D
#scripts
JavaScript to run on the page before the capture.
There is no default; leave it out and it is not applied.
Type: text.
Example: scripts=document.title%3D'Hi'
#click
Click the first element matching this selector before the capture.
There is no default; leave it out and it is not applied.
Type: text.
Example: click=%23accept
Read more: Dark mode and emulation, Custom CSS, JavaScript and clicks.
#Request
These change what our browser sends to the site. Reach for them when the page needs a login cookie, a special header, a certain time zone, or a different browser name.
Login details stay with the site you capture. authorization, and any entry in headers that carries a credential (Cookie, Authorization, or a name containing words like token or key), is sent only to the origin of your url. The origin is its scheme, host and port together. Other hosts the page loads files from, or redirects to, do not receive them.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&time_zone=Europe/Berlin&headers=Accept-Language:%20de" --output berlin.png#user_agent
User-Agent header the browser sends.
There is no default; leave it out and it is not applied.
Type: text.
Example: user_agent=MyBot/1.0
#headers
Extra HTTP headers, as "Name: value".
There is no default; leave it out and it is not applied.
Type: name and value pairs.
Example: headers=X-Preview:%201
#cookies
Cookies to set, as "name=value; Domain=example.com".
There is no default; leave it out and it is not applied.
Type: list of name and value pairs.
Example: cookies=session%3Dabc123
#authorization
Authorization header sent to the target site only.
There is no default; leave it out and it is not applied.
Type: text.
Example: authorization=Basic%20dXNlcjpwYXNz
#time_zone
IANA time zone the page sees.
There is no default; leave it out and it is not applied.
Type: text.
Example: time_zone=Europe/Berlin
Read more: How to screenshot a page behind a login.
#Blocking
Real pages come with noise: ads, consent pop-ups, chat bubbles. These options remove the common ones so the screenshot shows the content. Blocking is best-effort, so keep hide_selectors in mind for anything that slips through.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&block_ads=true&block_cookie_banners=true" --output clean.png#block_ads
Block requests to ad networks.
The default is false.
Type: true or false.
Example: block_ads=true
#block_trackers
Block analytics and tracking scripts.
The default is false.
Type: true or false.
Example: block_trackers=true
#block_cookie_banners
Hide cookie consent banners.
The default is false.
Type: true or false.
Example: block_cookie_banners=true
#block_chats
Block live-chat widgets.
The default is false.
Type: true or false.
Example: block_chats=true
#block_resources
Block whole kinds of resources.
There is no default; leave it out and it is not applied.
Type: list from a fixed list. Allowed values: document, stylesheet, image, media, font, script, xhr, fetch, websocket, texttrack, eventsource, manifest, other.
Example: block_resources=font,media
#block_requests
Block requests whose URL matches these patterns (* is a wildcard).
There is no default; leave it out and it is not applied.
Type: list of text values.
Example: block_requests=*.example.com/ads/*
Read more: Blocking ads, cookie banners, trackers and chats.
These apply only when format=pdf. Use them to pick the paper size, turn the page sideways, add margins, or put a whole page on one long sheet. With any other format they have no effect.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&format=pdf&pdf_paper_format=letter&pdf_margin=10mm" --output example.pdf#pdf_paper_format
Paper size of the PDF.
The default is a4.
Type: one of a fixed list. Allowed values: a0, a1, a2, a3, a4, a5, a6, letter, legal, tabloid, ledger.
Example: pdf_paper_format=letter
#pdf_landscape
Use landscape pages.
The default is false.
Type: true or false.
Example: pdf_landscape=true
#pdf_print_background
Print background colors and images.
The default is true.
Type: true or false.
Example: pdf_print_background=false
#pdf_margin
Margin on all four sides.
There is no default; leave it out and it is not applied.
Type: text.
Example: pdf_margin=10mm
#pdf_margin_top
Top margin; overrides pdf_margin.
There is no default; leave it out and it is not applied.
Type: text.
Example: pdf_margin_top=20mm
#pdf_margin_right
Right margin; overrides pdf_margin.
There is no default; leave it out and it is not applied.
Type: text.
Example: pdf_margin_right=10mm
#pdf_margin_bottom
Bottom margin; overrides pdf_margin.
There is no default; leave it out and it is not applied.
Type: text.
Example: pdf_margin_bottom=20mm
#pdf_margin_left
Left margin; overrides pdf_margin.
There is no default; leave it out and it is not applied.
Type: text.
Example: pdf_margin_left=10mm
#pdf_fit_one_page
Put the whole page on a single tall PDF page.
The default is false.
Type: true or false.
Example: pdf_fit_one_page=true
Read more: PDF rendering.
#Video
These apply only when format is mp4, webm or gif. The result is then a video of the page scrolling from top to bottom, and these options set how long it is, how smooth it is and how the scroll moves. With any other format they have no effect. The Scrolling videos page shows each one at work.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&format=mp4&video_duration=8" --output example.mp4#video_duration
Length of the video. Left out, it follows the height of the page.
There is no default; leave it out and it is not applied.
Type: number. From 1 to 30 seconds.
Example: video_duration=8
#video_max_duration
Longest the video may get when its length follows the page. A taller page then scrolls faster.
The default is 30 seconds.
Type: number. From 1 to 30 seconds.
Example: video_max_duration=15
#video_fps
Frames per second. A gif takes at most 15.
The default is 24.
Type: whole number. From 5 to 30.
Example: video_fps=30
#video_scroll
Scroll from the top of the page to the bottom while recording.
The default is true.
Type: true or false.
Example: video_scroll=false
#video_scroll_back
Scroll back to the top at the end, so the video loops cleanly.
The default is false.
Type: true or false.
Example: video_scroll_back=true
#video_scroll_easing
How the scroll moves: a soft start and stop, or one even speed.
The default is ease_in_out.
Type: one of a fixed list. Allowed values: ease_in_out, linear.
Example: video_scroll_easing=linear
Read more: Scrolling videos.
#Caching options
Caching stores a result so that the same request can be answered again without a new render. A cached answer is fast and does not use your quota. Turn it on for pages that do not change every minute.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&cache=true&cache_ttl=86400" --output example.png#cache
Serve a stored copy when the same request was made before.
The default is false.
Type: true or false.
Example: cache=true
#cache_ttl
How long a cached copy stays valid.
The default is 14400 seconds.
Type: whole number. From 60 to 2592000 seconds.
Example: cache_ttl=86400
#cache_key
Change this value to force a fresh render.
There is no default; leave it out and it is not applied.
Type: text.
Example: cache_key=v2
Read more: Caching.
#Async and webhooks
Normally you wait for the screenshot. With these options the request returns at once and the render happens in the background. Use them for slow pages, or when your code should not hold a connection open. A webhook is a request we send to your server when the job ends.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&async=true&webhook_url=https://your-app.example/hooks/screenshot"#async
Return at once and render in the background.
The default is false.
Type: true or false.
Example: async=true
#webhook_url
Address that receives the result when the render is done.
There is no default; leave it out and it is not applied.
Type: text.
Example: webhook_url=https://example.com/hook
#webhook_sign
Sign the webhook body so you can verify it came from us.
The default is true.
Type: true or false.
Example: webhook_sign=false
Read more: Async and webhooks, Bulk screenshots.
#Authentication
These say who is making the request. Every request needs access_key, in the query string or in a header.
signature and expires are for signed links, which let you put a screenshot URL in a public page safely. signature proves the link was not changed. expires gives the link an end date: after that moment it answers signature_invalid.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com" --output example.png#access_key
Your API access key.
There is no default; leave it out and it is not applied.
Type: text.
Example: access_key=YOUR_ACCESS_KEY
#signature
HMAC-SHA256 signature of the query string, for signed links.
There is no default; leave it out and it is not applied.
Type: text.
Example: signature=9f86d081...
#expires
Unix time in seconds after which the request is refused. Put it in a signed link to give the link a lifetime.
There is no default; leave it out and it is not applied.
Type: whole number.
Example: expires=1767225600
Read more: Authentication and API keys, Signed links.
#Where to go next
- The screenshot URL: how to write options in GET and POST requests.
- Devices: the full list of values for
viewport_device. - Errors: what
invalid_optionsand the other codes mean. - Code examples: complete scripts that use these options.