Waiting and timing
Decide the moment the capture is taken, with wait_until, delay, wait_for_selector and timeout, and what to do when a page times out.
This request waits until the page has gone quiet, then one more second, before it captures.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://github.com/microsoft/playwright&wait_until=networkidle&delay=1" \
--output playwright.pngYou get the page with its late-loading parts in place: the file list, the avatars, the README.
A page does not appear all at once. First comes the text, then styles, then images, then whatever its scripts fetch afterwards. Capture too early and you get gaps. Wait too long and every request is slow. The four options on this page let you choose.
#The four options at a glance
| Option | What it answers | Default |
|---|---|---|
wait_until | Which loading stage counts as "loaded"? | load |
wait_for_selector | Which element must be visible first? | not set |
delay | How much extra time after that? | 0 seconds |
timeout | When do we give up? | 30 seconds |
#Choose a loading stage
#wait_until
The loading stage at which the page counts as loaded.
The default is load.
The allowed values are load, domcontentloaded, networkidle and commit. Here they are from earliest to latest:
| Value | In plain words | Use it when |
|---|---|---|
commit | The site has started to answer. The page is probably still blank. | You follow it with wait_for_selector and want nothing else to hold things up. |
domcontentloaded | The text and structure have arrived. Images and styles may still be on their way. | The page has one slow image or ad that you do not care about. |
load | The page and the files it lists, such as images and styles, have finished loading. | Most pages. This is the browser's own idea of "done". |
networkidle | The load stage, and then the page has stopped fetching things for a moment. | Pages that build themselves with JavaScript after loading. |
networkidle is the slowest of the four, because it has to watch for a quiet moment.
Some pages never go quiet. They keep polling, which means asking a server for news every few seconds, or they stream data. For those, networkidle waits a limited time and then captures anyway. You still get a screenshot.
#Wait for one element
#wait_for_selector
Wait until an element matching this CSS selector is visible.
There is no default. Leave it out and no element is waited for.
A CSS selector is a short pattern that points at an element, such as .chart for an element with the class chart.
This is the most exact way to wait. You name the thing you need, and the capture happens as soon as it is on screen.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://en.wikipedia.org/wiki/Eiffel_Tower&wait_for_selector=.infobox" \
--output eiffel.pngThe element has to be visible, not only present in the page. A hidden element does not count.
If it has not shown up when the timeout runs out, the request fails with selector_not_found and status 422. Note the code: it is not timeout, because the page itself loaded fine.
#Add a pause
#delay
Extra time to wait after the page has loaded, in seconds.
The default is 0. The largest value is 30. The value is in seconds, not milliseconds. Decimals are allowed, so 0.5 is half a second.
The delay comes after wait_until and wait_for_selector are satisfied.
Use it for things no loading stage can see: an entrance animation, a chart that draws itself, a font that swaps in late.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://developer.mozilla.org&delay=2" \
--output mdn.pngA delay is a fixed cost. Two seconds of delay makes every request two seconds slower, even when the page was ready at once. Prefer wait_for_selector when there is an element you can name.
#Set the limit
#timeout
How long the page may take to get ready, in seconds.
The default is 30. The smallest value is 1 and the largest is 90.
The clock covers loading the page and waiting for wait_for_selector. If the page is not ready in time, the request stops with the timeout error.
Raise it for heavy pages. Lower it when a quick failure is more useful to you than a long wait.
curl "https://curlshot.com/api/v1/screenshot?access_key=YOUR_ACCESS_KEY&url=https://github.com/microsoft/playwright&full_page=true&timeout=60" \
--output playwright-full.pngYour own HTTP client has a timeout too. Make it longer than timeout plus delay, with some seconds to spare for the capture. Otherwise your client hangs up before the answer arrives.
#How to choose
Start with the defaults. They suit most pages. Change something only when a capture comes back wrong.
- Parts are missing, and there is an element you can name. Add
wait_for_selectorfor that element. - Parts are missing, and you cannot name an element. Try
wait_until=networkidle. - Still not right, or something is mid-animation. Add a small
delay, such as1or2. See alsoreduced_motion. - The request times out. Go the other way. Use
wait_until=domcontentloaded, block what is slow with blocking options, or raisetimeout.
#The timeout error
When the page is not ready in time, you get this:
{
"error_code": "timeout",
"error_message": "The page took too long to render. Try a larger `timeout` or a lighter `wait_until`.",
"documentation_url": "https://curlshot.com/docs/errors#timeout"
}A timed-out request is not counted against your quota.
It is safe to retry. Slow moments happen: the site may have been busy for a few seconds. If the same page times out again and again, change the request:
- Raise
timeout, up to90. - Use an earlier stage:
wait_until=loadorwait_until=domcontentloaded. - Cut the weight of the page with
block_ads,block_trackersorblock_resources=media. - Lower
full_page_max_heightfor very long pages.
The full entry is on the errors page.
#Where to go next
- Custom CSS, JavaScript and clicks: change the page once it is ready.
- Async and webhooks: for renders that take a long time.
- Errors: what each error code means and which ones to retry.
- Options reference: the waiting options with their limits.