Ultimate Screenshot avatar

Ultimate Screenshot

Pricing

$13.00/month + usage

Go to Apify Store
Ultimate Screenshot

Ultimate Screenshot

🚀 Capture ANY website as HD screenshots, videos, or PDFs! 📸 100+ device presets (iPhone, Android, tablets). Perfect for web scraping, monitoring, testing & marketing. Export as PNG/JPEG/PDF/MP4/GIF. Fast, reliable, proxy-ready. Try FREE now!

Pricing

$13.00/month + usage

Rating

5.0

(7)

Developer

FlowExtract API

FlowExtract API

Maintained by Community

Actor stats

23

Bookmarked

256

Total users

6

Monthly active users

3 days ago

Last modified

Share

📸 Ultimate Screenshot — capture any web page as an image, PDF, video or GIF

Ultimate Screenshot turns a list of web addresses into finished files: JPEG and PNG screenshots, printable PDFs, and short MP4 or GIF recordings of the page. It drives a real browser, so pages that need JavaScript, web fonts, lazy-loaded images or a signed-in session come out looking the way a person would see them — on a desktop window, or on any of 131 phone and tablet presets.

Ultimate Screenshot

Perfect for agencies archiving client sites, QA and product teams building visual checks, and marketers who need a scroll-through clip of a landing page without opening a screen recorder.


What it produces

FormatWhat you getTypical use
JPEGCompressed image, quality you chooseBulk archiving, thumbnails, previews
PNGLossless imageDesign review, pixel comparisons
PDFPrintable document — paper size, margins, orientationReports, invoices, compliance records
MP4Up to a 30-second recordingLanding-page walkthroughs, demos
GIFUp to a 10-second looping animationSocial posts, docs, changelog entries

Every format can be captured as the visible window or as the whole page, top to bottom.


⚙️ How to use it

The one setting you need

{
"linkUrls": ["https://example.com", "https://apify.com"]
}

That captures each page as a JPEG at 1920 × 1080. Everything below is optional.

Addresses go in one per line. A bare domain is fine — example.com becomes https://example.com. The field checks that each line looks like a web address, so a stray number or word is caught in the form rather than producing an empty result.

Full-page screenshot

{
"linkUrls": ["https://example.com"],
"outputFormat": "png",
"fullPage": true,
"scrollToBottom": true,
"maxScrollSeconds": 15
}

scrollToBottom walks down the page first so lazy-loaded images actually load. maxScrollSeconds is the limit that ends the scroll — on an endless feed it is the only thing that ends it, and it decides how much of the feed you capture.

Phone or tablet

{
"linkUrls": ["https://example.com"],
"device": "iPhone 15 Pro",
"outputFormat": "jpeg",
"fullPage": true
}

131 presets, each with the right screen size, pixel density and browser identity. A preset replaces the window width and height below it.

A scroll-through video

{
"linkUrls": ["https://example.com"],
"outputFormat": "mp4",
"recordingMode": "scroll",
"recordSeconds": 10,
"fps": 15
}

The clip is exactly recordSeconds × fps frames and plays for exactly recordSeconds. In scroll mode the step between frames is worked out from the real page height, so the last frame lands at the bottom of the page. In static mode the window stays put, which suits carousels, animations and players.

A signed-in page

{
"linkUrls": ["https://example.com/account"],
"cookies": [
{ "name": "session_id", "value": "abc123", "domain": "example.com" }
]
}

Export cookies with a browser extension such as Cookie Editor. Each cookie needs at least a name and a value; the address being captured supplies the domain when it is missing.

Cleaning up the page first

{
"linkUrls": ["https://example.com"],
"waitForSelector": "#main-content",
"hideSelectors": ["#cookie-banner", ".chat-widget", ".sticky-header"],
"delayBeforeScreenshot": 2000
}

Finding the right selector

Right-click the banner, choose Inspect, then read the id or class off the highlighted element

  1. Right-click the banner you want gone and choose Inspect (bottom of the menu).

  2. The developer tools open with that element highlighted. Click upwards through the boxes until the highlight covers the whole banner, not just its text — you can see the size readout, 340 × 122, confirming the right box is selected.

  3. Read the id or class off that line and type it with the right prefix:

    In the HTMLYou typeBecause
    <div id="onetrust-consent-sdk">#onetrust-consent-sdkan id takes a #
    <div class="cookie-bar">.cookie-bara class takes a .

    Prefer the id when the element has one — it is shorter and changes less often.

The screenshot is Chrome, but this works the same in Edge, Firefox and Safari: you are reading an attribute out of the page's own HTML, not using a browser feature.

Chrome and Edge also offer Copy → Copy selector (Firefox: Copy → CSS Selector), visible on the right of the screenshot. It works, but it usually produces a long path like #onetrust-consent-sdk > div:nth-child(2) > div that breaks the next time the site changes its layout — the plain id above keeps working.

Hide the wrapper, not the text inside it, or you will be left with an empty bar.

Most consent banners come from a handful of platforms, so these cover a lot of the web:

PlatformSelector
OneTrust (used by apify.com and many large sites)#onetrust-consent-sdk
Cookiebot#CybotCookiebotDialog
Osano.osano-cm-window
Quantcast / TCF.qc-cmp2-container
Usercentrics#usercentrics-root
CookieYes.cky-consent-container
Generic catch-all[id*="cookie"], [class*="cookie-banner"]

Hiding is applied as a style rule as soon as the page opens, so a banner that appears after the page has loaded is caught too — many consent scripts take several seconds to inject theirs.

If a selector matches nothing, the result row's notes says so rather than leaving you guessing.


🎛️ All settings

Page loading

SettingDefaultWhat it does
waitUntilloadWhen the page counts as ready. load suits most sites and is much the fastest complete option. Move to a Network Idle mode only for pages that keep drawing after everything has loaded — it can add many seconds per page.
timeouT30 sHow long to wait for a page before giving up on that attempt.
maxRetries2Extra attempts when a page fails to load. 0 means a single attempt.
delayBeforeScreenshot1000 msExtra pause after the page is ready, for animations and fonts.
waitForSelectorCSS selector to wait for. If it never appears the page is captured anyway and the row says so.

Scrolling & clean-up

SettingDefaultWhat it does
scrollToBottomfalseScroll through the page before capturing so lazy content loads.
maxScrollSeconds15 sThe longest scrolling may take. Scrolling also stops as soon as the page stops growing.
delayAfterScrolling500 msPause after scrolling, so content loaded on the way down can render.
hideSelectorsCSS selectors to hide — cookie banners, chat bubbles, sticky headers. Applied as a style rule the moment the page opens, so it also catches banners that appear seconds later. Selectors matching nothing are reported in notes.

Video & GIF

SettingDefaultWhat it does
recordingModescrollscroll pans down the page; static holds the window still.
recordSeconds5 sHow long the finished clip plays. GIF max 10, MP4 max 30.
fps10Playback frame rate. GIF max 15, MP4 max 30.

Image, PDF, device and network

SettingDefaultWhat it does
jpegQuality85JPEG only. PNG is always lossless.
printBackgroundtruePDF: keep background colours and images.
formaTA4PDF paper size. Ignored when any margin below is above 0.
landscapefalsePDF orientation.
toP / righT / bottoM / lefT0 mmPDF margins in millimetres.
deviceOne of 131 phone/tablet presets. Replaces the window size.
window_Width / window_Height1920 × 1080Browser window when no device preset is chosen.
userAgentSend a specific browser identity.
cookies[]Cookies applied before the page loads.
proxyConfigApify datacenterRoute the capture through a proxy.
enableSSLtrueTurn off only for a self-signed or expired certificate you trust.

📊 What you get back

One row per address, plus the file itself in the run's storage.

Files are grouped by what they are. Open the run's Storage tab and you get three named collections rather than one flat list:

CollectionHoldsKey prefix
ScreenshotsPNG and JPEG imagesscreenshot-
Videos & GIFsMP4 and GIF recordingsvideo-
PDF documentsPDF renderingsdocument-

A GIF is filed with video, not with the images — it is a recording of the page, made by the same frame capture and described by the same length and frame-rate settings as an MP4. Its file type happens to be image/gif, which is why the video collection accepts that type too.

{
"status": "success",
"format": "jpeg",
"linkUrl": "https://example.com",
"finalUrl": "https://example.com/",
"screenshot_url": "https://api.apify.com/v2/key-value-stores/.../records/capture-001-....jpg",
"screenshot_image": "https://api.apify.com/v2/key-value-stores/.../records/capture-001-....jpg",
"content_Type": "image/jpeg",
"fileName": "capture-001-20260904211602-nyyjjkaa.jpg",
"fileSizeBytes": 24576,
"pageTitle": "Example Domain",
"httpStatus": 200,
"width": 1920,
"height": 1080,
"durationSeconds": null,
"frames": null,
"captureMs": 2388,
"error": null,
"notes": null,
"capturedAt": "2026-09-04T21:16:02.463Z"
}
FieldWhat it tells you
statussuccess when a file was produced, failed when the page returned nothing
screenshot_url / screenshot_imageDirect download link for the file
content_Type, fileName, fileSizeBytesWhat the file is and how big
linkUrl / finalUrlWhat you asked for, and where the page ended up after redirects
pageTitle, httpStatusThe page's own title, and the status code it answered with
frames, durationSecondsRecordings only — how many frames and how long the clip plays
captureMsHow long this page took, from opening it to saving the file
errorOn a failed page, one sentence saying what happened
notesWhere the actor tells you it did something you did not ask for

screenshot_image, content_Type, linkUrl and screenshot_url keep the exact names and meanings they had in version 1 — existing integrations need no change.

notes is worth reading. It is how the actor reports a clipped tall page, a scroll that stopped at the limit, a recording shortened to stay inside the frame limit, or hideSelectors that matched nothing.


💰 Pricing

$13 / month, with a 1-day free trial. Unlimited runs and unlimited captures for the subscription; you pay the Apify platform usage your runs consume, as with any rented Actor.

The settings that move platform usage most:

  • waitUntil is the big one. load returned a heavy marketing page in about 5 seconds where networkidle0 took 28 — for a screenshot that differed by a few kilobytes.
  • Capture in batches. Starting a run costs a fixed amount of browser time before the first page opens. Ten addresses in one run use roughly half the platform usage of the same ten as ten separate runs.
  • Recordings cost far more than stills, in proportion to recordSeconds × fps. A 5-second GIF at 10 fps is 50 captures of the page; a 10-second MP4 at 30 fps is 300.

🛟 Limits, and why they exist

A browser can be asked to do something that never finishes. These limits mean it does not.

LimitValueWhat happens when it is reached
Scrollingyour maxScrollSeconds, at most 60 sScrolling stops, the page is captured as it stands, and a note says so
Full-page image height16 000 pxThe image is clipped to the top 16 000 px — the tallest a browser can render in one pass
Recording frames300 per pageThe clip is shortened, keeping your frame rate, and a note says so
Recording time2.5 minutes per pageRecording stops and whatever was captured is encoded into a valid clip
Whole page4 minutesThe page is abandoned and reported; the run carries on with the next address
Output file100 MBThe page is reported with a suggestion to record less or use a smaller window

🔄 If a run is interrupted

Progress is saved after every page. If the run is migrated, restarted or aborted, it resumes from the next uncaptured address instead of starting over — so an interruption never re-captures a page you already received.


🚫 When something goes wrong

SituationWhat you seeWhat to do
An address is not a web addressThe run is refused when you submit it, naming the position of the bad lineFix or remove that line
A page will not loadstatus: "failed" and an error sentence for that address onlyRaise timeouT, or check the address in a browser
The site answers with an error codeA capture of the error page, and a note giving the status codeExpected — the page really did answer that way
A page is taller than 16 000 pxA clipped image, and a note with the page's real heightCapture the window instead of the whole page, or a narrower window
A recording came out shortFewer frames than asked, and a note saying whyLower fps or recordSeconds, or record a lighter page
Nothing was captured at allA single row with status: "no_input"Check the addresses in the input

❓ Frequently asked questions

Can it capture pages behind a login? Yes, with the cookies setting. Export the cookies from a signed-in browser session and paste them in.

Why is my full-page screenshot cut off at the bottom? The page is taller than 16 000 pixels. That is a browser limit, not a setting — a browser cannot rasterise an arbitrarily tall page in one image. The row's notes gives the page's real height.

My GIF looks shorter than I asked for. Check frames and notes on the row. A clip is shortened when recordSeconds × fps would pass 300 frames, or when the page was too slow to record the full series in time.

Why is the video not the page's real motion? Frames are captured one at a time, so a recording is a time-lapse rather than a real-time screen capture. In scroll mode that is exactly what you want — a smooth pass down the page. In static mode, fast animations look sped up.

Can I capture an infinite-scroll feed completely? No, and neither can anything else — the feed has no end. Set maxScrollSeconds to how much of it you want; that is the amount you get.

How many pages can I capture per run? As many addresses as you like. Batching is more efficient than separate runs.

What happens if one address fails? Only that address. It appears with status: "failed" and a sentence saying why, and the run continues.

I upgraded from version 1 — do I need to change anything? No. Every setting from version 1 still works, and the four output fields integrations read keep their exact names. The retired video settings (frameCounT, frame, timefullPagE, infiniteScroll) are converted automatically and the run log says what they became. See the changelog for the full list.

Can I use my own proxy? Yes — set your own proxy URLs in the proxy setting. Apify's datacenter proxy is used by default.


This actor captures pages as they are served to a browser — the same content any visitor can see, plus anything your own cookies give you access to.

Please use it responsibly:

  • Only capture pages you are authorised to access, and only use cookies from accounts you own.
  • Respect each site's Terms of Service and applicable data-protection law (GDPR, CCPA and equivalents).
  • Screenshots of pages containing personal data are personal data — store and share them accordingly.
  • Do not use captures to impersonate a site, a person or an organisation.

🤝 Support


Built by FlowExtract API — reliable data extraction actors for the Apify platform.