Readiness

Wait for the element that means the page is ready

Network silence is a guess about readiness. An element you chose is a statement about it.

wait_for_selectorwait_for_selector_algorithmwait_untildelaytimeout
curl --fail-with-body "https://api.pagecapture.dev/v1/take" \
  -H "X-Access-Key: $PAGECAPTURE_KEY" \
  -H "Content-Type: application/json" \
  --data '{"url":"https://example.com","format":"jpg","wait_for_selector":"main","wait_until":"load"}' \
  -o capture.jpg

Verified 2026-08-13 by running the published code against a fixture.

Configure it in the playground
What you are seeing

Captures come back with skeletons, spinners or half a list — or they never come back at all and hit the timeout.

Why the page does that

`networkidle0` waits for zero in-flight requests. A page with a websocket, an analytics beacon or a polling loop never reaches zero, and one with fast HTML reaches it before the data arrives.

What it does

  • Holds the capture until the CSS selector you name is present and visible, then continues with the rest of the action order.
  • Offers two counting strategies through `wait_for_selector_algorithm`: the first visible match, or every match the page is still rendering.
  • Shares the job's `timeout` budget, so an element that never appears ends as `timeout_error` — and a failed capture is never billed.

What it does not do

  • Does not accept XPath. The selector is always CSS; the algorithm parameter controls how many nodes satisfy the wait, not the selector language.
  • Does not replace `wait_until`. The navigation state still has to be reached first — this waits on top of it, not instead of it.
  • Does not see into a closed shadow root unless `include_shadow_dom` is set.
The contract

Every limit on this page is the one the API enforces

These rows are read from the same parameter table that validates your request. Nothing here is transcribed, so a number cannot drift from the behaviour it describes.

ParameterTypeDefaultRangeEndpointsCache key
wait_for_selector

Wait until this CSS selector appears.

string/v1/take, /v1/animateIn
wait_for_selector_algorithm

How many nodes satisfy the wait: the first visible match, or every match currently rendering. The selector is always CSS.

enumat_least_one/v1/take, /v1/animateIn
wait_until

Navigation state to wait for. `networkidle0` waits for zero in-flight requests, `networkidle2` for at most two.

enumload/v1/take, /v1/animateIn
delay

Extra seconds to wait after the navigation state.

integer00 – 30/v1/take, /v1/animateIn
timeout

Total budget for the capture, in seconds.

integer601 – 90/v1/take, /v1/animateIn
Group: Navigation and waitingValues outside a documented range are rejected before a browser opens.

How it behaves next to the rest of the request

wait_for_selector_algorithm

How many nodes satisfy the wait: the first visible match, or every match currently rendering. The selector is always CSS.

`at_least_one` ends the wait as soon as the first match is visible. `at_least_by_count` keeps counting matches until the count repeats across two consecutive reads — which is what a list filled by XHR actually needs, because the first row appearing does not mean the last one has.

wait_until

Navigation state to wait for. `networkidle0` waits for zero in-flight requests, `networkidle2` for at most two.

For pages with a permanent connection, pair a readiness selector with `wait_until=load` rather than `networkidle0`. Idle will not arrive, and waiting for it converts a working page into a timeout.

delay

Extra seconds to wait after the navigation state.

Extra seconds after the navigation state, capped at 30. It is the blunt instrument: use it when there is genuinely no element that marks readiness, not as a first attempt.

Questions this raises

What do I pay when the element never appears?

Nothing. `timeout_error` is a failure, and no error code in the catalog is billable — including failures that are ours.

Selector or delay?

Selector, whenever one exists. A delay is a bet on a duration that will be wrong on both ends: too short on a slow day, wasted budget on a fast one.

How much time do I have?

`timeout` is the whole capture budget in seconds, default 60 and capped at 90; `navigation_timeout` covers navigation alone, default 30 and capped at 30. The wait draws from the first.