Scrolling videos
Record a video of a page scrolling from top to bottom, as MP4, WebM or GIF, and set its length, smoothness and size.
Set format=mp4 and you get a video of the page in place of an image. It starts at the top and scrolls to the bottom.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&format=mp4" \
--output eiffel.mp4You get eiffel.mp4: the article in a 1280 by 720 window, resting on the top for a moment, scrolling down at a steady pace and resting on the last screen. The response has the header Content-Type: video/mp4. The video has no sound.
The page really scrolls while it is recorded. A menu that sticks to the top stays there, and content that appears as you scroll appears in the video too.
A video takes longer to make than it lasts: about twice as long, plus the time the page needs to load. For long videos, render in the background.
#Formats
Three values of format give a video.
| Format | What you get | Good for |
|---|---|---|
mp4 | An H.264 video. Every browser, phone and video editor plays it. | Almost everything. |
webm | A VP9 video. Often a smaller file than MP4. | Web pages. |
gif | An animated image. It needs no player, but the file is much larger. | Emails, chats and READMEs. |
A GIF is recorded at 15 frames per second at most and is scaled down to 640 pixels wide. Set image_width for another width.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&format=gif&video_duration=4" \
--output example.gif#Length
#video_duration
The length of the video, in seconds.
There is no default. Leave it out and the length follows the page.
The smallest value is 1 and the largest is 30.
Without it, a taller page gives a longer video: the scroll moves about three quarters of a screen per second, which is easy to follow. With it, the video has exactly that length and the scroll gets faster or slower to fit.
This request gives an 8 second video, however tall the page is:
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&format=mp4&video_duration=8" \
--output eiffel-8s.mp4#video_max_duration
The longest the video may get when its length follows the page, in seconds.
The default is 30. The smallest value is 1 and the largest is 30.
A page too tall to scroll at the normal pace in this time is scrolled faster, so the video still ends on the bottom of the page. It has no effect when you set video_duration.
#How far the video scrolls
The video scrolls to the bottom of the page, or to full_page_max_height on a page taller than that. The default is 20000 pixels. Set a lower value to show only the top part of a long page:
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&format=mp4&full_page_max_height=4000" \
--output eiffel-top.mp4Before the recording starts, the page is scrolled through once so images that load late are there. full_page_scroll=false turns that off.
#Scrolling
#video_scroll
Scroll from the top of the page to the bottom while recording.
The default is true.
Set it to false to record the first screen without moving. That suits a page with an animation you want to show. The video is then 4 seconds long unless you set video_duration. A page that fits in the window is recorded the same way.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://example.com&format=mp4&video_scroll=false&video_duration=5" \
--output example-still.mp4#video_scroll_back
Scroll back to the top at the end.
The default is false.
The video then ends where it started, so it loops without a jump. This is useful for a GIF, which repeats for ever.
#video_scroll_easing
How the scroll moves.
The default is ease_in_out.
The allowed values are ease_in_out and linear. With ease_in_out the scroll starts and stops softly and keeps one even speed in between. With linear it moves at one speed from the first frame to the last.
#Smoothness
#video_fps
The number of frames per second.
The default is 24. The smallest value is 5 and the largest is 30.
More frames give a smoother scroll and a larger file. With format=gif the largest value is 15, and that is also what a GIF gets when you leave the option out.
#Size
A video is as large as the browser window. For a video the window is 1280 by 720 pixels unless you choose another size, with viewport_width and viewport_height or with a device.
This request records the mobile layout of the page, as a tall phone video:
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&format=mp4&viewport_device=iphone_15_pro" \
--output eiffel-phone.mp4Two options you know from images work for videos as well:
image_widthscales the video down to that width. The height follows. A video is never scaled up: a width larger than the recorded frames is refused.image_qualitysets how hard an MP4 or WebM is compressed. The default of80looks sharp. A lower value gives a smaller file.
One frame can hold at most 2,073,600 pixels, which is 1920 by 1080. The device_scale_factor counts: a 1280 by 720 window at device_scale_factor=2 is over the limit and is refused with invalid_options. A device preset is different. Its pixel density is lowered until the frames fit, so viewport_device=iphone_15_pro gives a sharp 786 by 1704 video.
The sides of an MP4 are always even numbers. An odd side loses one pixel.
#What does not apply to a video
A video always shows the window, scrolling. These options are for still captures, and a request that combines one of them with a video format is refused with invalid_options:
full_page=true. A video already goes through the whole page.selectorand theclip_*options.omit_backgroundandimage_height.
Everything that prepares the page works as usual: blocking, dark mode, waiting, custom CSS and clicks, cookies and headers.
#Long videos
A request for a video stays open until the video is done. For a 30 second video that can be well over a minute. Some HTTP clients and proxies give up before that.
To avoid waiting, add async=true. The answer comes at once with a job id, and the finished video is sent to your webhook or fetched with the job.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&format=mp4&async=true"#Showing a video on a web page
Do not point a <video> tag at a plain request. A player asks for a video in several pieces, and every piece would be a new render.
Add cache=true. The first request records the video and every later one gets the stored copy:
<video src="https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https%3A%2F%2Fexample.com&format=mp4&cache=true" autoplay loop muted playsinline></video>On a public page, use a signed link so your access key cannot be reused for other pages. You can also ask for response_type=json and use the url of the stored file.
#Limits of your plan
A video counts as one screenshot against your quota, however long it is. What a plan limits is the length:
- A plan can have a lower maximum than
30seconds. A largervideo_durationorvideo_max_durationis lowered to the plan's maximum, and you still get a valid video. - A plan can leave video capture out. A request for a video then answers
feature_not_available.
Your own value is video_max_seconds in the answer of GET /usage.
A finished file that is too big answers content_too_large. Use a shorter video_duration, a smaller image_width, a lower image_quality or a lower video_fps.
#Where to go next
- Options reference: every video option in one list.
- Async and webhooks: record long videos in the background.
- Caching: record once, serve many times.
- Devices: phone and tablet presets for vertical videos.
- Full-page screenshots: the whole page as one still image.