> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenrows.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Wait Parameter

> Add a fixed millisecond delay during headless browser rendering to ensure slow-loading dynamic content is fully captured before HTML extraction.

The Wait parameter introduces a fixed delay during JavaScript rendering, allowing web pages additional time to load dynamic content before ZenRows fully captures the HTML. Many websites load content progressively through JavaScript, AJAX calls, or other asynchronous processes that occur after the initial page has been rendered.

When you add the `wait` parameter to your request, ZenRows pauses for the specified duration (in milliseconds) after the page initially loads, ensuring that slow-loading elements, animations, and dynamically generated content have time to appear before the HTML is extracted. The maximum `wait` value acceptable is 30 seconds (30,000 milliseconds).

<Note>The Wait parameter requires `js_render=true` to function, as it operates within the browser environment during JavaScript rendering.</Note>

## How the Wait parameter works

The Wait parameter creates a pause in the scraping process after the initial page load completes. During this waiting period, the headless browser remains active, allowing JavaScript to continue executing, AJAX requests to complete, and dynamic content to render.

This process ensures you capture:

* Content loaded through delayed AJAX calls
* Elements that appear after animations complete
* Data populated by slow third-party APIs
* Progressive loading sequences
* Time-sensitive dynamic updates

The wait occurs after the initial DOM load but before the final HTML extraction, giving websites the necessary time to complete their loading processes.

## Basic usage

Add the `wait` parameter with a value in milliseconds to your JavaScript rendering request:

<CodeGroup>
  ```python Python theme={null}
  # pip install requests
  import requests

  url = 'https://httpbin.io/anything'
  apikey = 'YOUR_ZENROWS_API_KEY'
  params = {
      'url': url,
      'apikey': apikey,
      'js_render': 'true',
      'wait': '5000',
  }
  response = requests.get('https://api.zenrows.com/v1/', params=params)
  print(response.text)
  ```

  ```javascript Node.js theme={null}
  // npm install axios
  const axios = require('axios');

  const url = 'https://httpbin.io/anything';
  const apikey = 'YOUR_ZENROWS_API_KEY';
  axios({
      url: 'https://api.zenrows.com/v1/',
      method: 'GET',
      params: {
          'url': url,
          'apikey': apikey,
          'js_render': 'true',
          'wait': '5000',
      },
  })
      .then(response => console.log(response.data))
      .catch(error => console.log(error));
  ```

  ```java Java theme={null}
  import org.apache.hc.client5.http.fluent.Request;

  public class APIRequest {
      public static void main(final String... args) throws Exception {
          String apiUrl = "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fhttpbin.io%2Fanything&js_render=true&wait=5000";
          String response = Request.get(apiUrl)
                  .execute().returnContent().asString();

          System.out.println(response);
      }
  }
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fhttpbin.io%2Fanything&js_render=true&wait=5000');
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $response = curl_exec($ch);
  echo $response . PHP_EOL;
  curl_close($ch);
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "io"
      "log"
      "net/http"
  )

  func main() {
      client := &http.Client{}
      req, err := http.NewRequest("GET", "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fhttpbin.io%2Fanything&js_render=true&wait=5000", nil)
      if err != nil {
          log.Fatalln(err)
      }
      resp, err := client.Do(req)
      if err != nil {
          log.Fatalln(err)
      }
      defer resp.Body.Close()

      body, err := io.ReadAll(resp.Body)
      if err != nil {
          log.Fatalln(err)
      }

      log.Println(string(body))
  }
  ```

  ```ruby Ruby theme={null}
  # gem install faraday
  require 'faraday'

  url = URI.parse('https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fhttpbin.io%2Fanything&js_render=true&wait=5000')
  conn = Faraday.new()
  conn.options.timeout = 180
  res = conn.get(url, nil, nil)
  print(res.body)
  ```

  ```bash cURL theme={null}
  curl "https://api.zenrows.com/v1/?apikey=YOUR_ZENROWS_API_KEY&url=https%3A%2F%2Fhttpbin.io%2Fanything&js_render=true&wait=5000"
  ```
</CodeGroup>

This example waits 5 seconds (5000 milliseconds) after the page loads before capturing the HTML content. During this time, any JavaScript-driven content loading processes can complete.

## When to use the Wait parameter

The Wait parameter is essential in these scenarios:

### Content loading delays:

* **Slow API responses** - Pages that fetch data from slow external APIs
* **Progressive content loading** - Sites that load content in multiple stages
* **Heavy JavaScript processing** - Pages with complex calculations or data processing
* **Third-party widgets** - External content like maps, charts, or embedded media
* **Animation sequences** - Content that appears after CSS or JavaScript animations

### Timing-dependent content:

* **Real-time data** - Stock prices, live scores, or updating counters
* **Lazy loading** - Images or content that loads as needed
* **Scroll preparation** - Initial content that loads before scroll triggers
* **Form validation** - Dynamic form elements that appear based on user input simulation

## Best practices

### Start with reasonable defaults

Begin with moderate wait times and adjust based on results:

```python Python theme={null}
def smart_wait_scraping(url, target_indicators):
    # Use progressive wait times to find the minimum necessary delay

    wait_times = [2000, 4000, 6000, 8000]  # Progressive wait times
    
    for wait_time in wait_times:
        response = requests.get('https://api.zenrows.com/v1/', params={
            'url': url,
            'apikey': 'YOUR_ZENROWS_API_KEY',
            'js_render': 'true',
            'wait': str(wait_time),
        })
        
        # Check if all target content is present
        content_found = all(indicator in response.text for indicator in target_indicators)
        
        if content_found:
            print(f"Optimal wait time found: {wait_time}ms")
            return response, wait_time
    
    print("Content not found even with maximum wait time")
    return None, None

# Usage
indicators = ['product-price', 'customer-reviews', 'stock-status']
result, optimal_wait = smart_wait_scraping('https://httpbin.io/anything', indicators)
```

### Combine with other parameters for maximum effectiveness

Use Wait with Premium Proxy for protected sites:

```python Python theme={null}
params = {
    'url': 'https://httpbin.io/anything',
    'apikey': 'YOUR_ZENROWS_API_KEY',
    'js_render': 'true',
    'premium_proxy': 'true',
    'wait': '6000',
}
```

## Troubleshooting

### Common issues and solutions

| Issue                 | Cause                                                                   | Solution                                                       |
| --------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------- |
| Content still missing | Wait time too short                                                     | Increase wait duration incrementally                           |
| Inconsistent results  | Variable loading times                                                  | Use longer wait time, use `wait_for`, or implement retry logic |
| REQS004               | Invalid value provided for `wait` parameter; value is too big (REQS004) | Keep wait under 30 seconds total or use `wait_for`             |
| Unnecessary delays    | Fixed wait for fast-loading content                                     | Use `wait_for` parameter for dynamic waiting                   |

### Debugging missing content with Wait

When content is still missing despite using the Wait parameter:

<Steps>
  <Step title="Check browser behavior manually">
    * Compare with manual browser testing
    * Open the page in a browser and time how long content takes to appear
    * Use that timing as your baseline wait duration
  </Step>

  <Step title="Increase wait time gradually">
    ```python Python theme={null}
    # Try progressively longer wait times
    for wait_time in [3000, 6000, 9000, 12000]:
        response = requests.get('https://api.zenrows.com/v1/', params={
            'url': url,
            'apikey': 'YOUR_ZENROWS_API_KEY',
            'js_render': 'true',
            'wait': str(wait_time),
        })
        
        if 'expected-content' in response.text:
            print(f"Content found with {wait_time}ms wait")
            break
    ```
  </Step>

  <Step title="Switch to the element-specific waiting (`wait_for`)">
    ```python Python theme={null}
    params = {
        'js_render': 'true',
        'wait_for': '.content',   # Wait for specific element
    }
    ```

    <Tip>
      See more on [Wait\_for](/universal-scraper-api/features/wait-for) documentation page
    </Tip>
  </Step>
</Steps>

## Understanding wait time limits

ZenRows has built-in limits for wait times to ensure service stability:

* **Maximum total wait time**: 30 seconds (30,000 milliseconds)
* **Recommended range**: 2,000 - 10,000 milliseconds (2-10 seconds)
* **Minimum practical wait**: 1,000 milliseconds (1 second). Values below that are acceptable but impractical

## Pricing

The `wait` parameter doesn't increase the request cost. You pay the JavaScript Render (5 times the standard price) regardless of the wait value you choose.

<Tip>
  You can monitor your ZenRows usage in multiple ways to stay informed about your account activity and prevent unexpected overages.

  **Dashboard monitoring**: View real-time usage statistics, remaining requests, success rates, and request history on your [Analytics Page](https://app.zenrows.com/analytics/scraper-api). You can also set up usage alerts in your [notification settings](https://app.zenrows.com/account/notifications) to receive notifications when you approach your limits.

  **Programmatic monitoring**: For automated monitoring in your applications, call the `/v1/subscriptions/self/details` endpoint with your API key in the `X-API-Key` header. This returns real-time usage data that you can integrate into your monitoring systems. [Learn more about the usage endpoint](https://docs.zenrows.com/universal-scraper-api/features/other#plan-usage).

  **Response header monitoring**: Track your concurrency usage through response headers included with each request:

  * `Concurrency-Limit`: Your maximum concurrent requests
  * `Concurrency-Remaining`: Available concurrent request slots
  * `X-Request-Cost`: Cost of the current request
</Tip>

## Frequently Asked Questions (FAQ)

<Accordion title="What's the difference between wait and wait_for parameters?">
  The `wait` parameter introduces a fixed delay in milliseconds, while `wait_for` waits for a specific element to appear on the page. Use `wait` when you know content takes a particular amount of time to load, and `wait_for` when you want to wait for specific elements to appear.
</Accordion>

<Accordion title="Can I use wait without js_render=true?">
  No, the `wait` parameter only works with JavaScript rendering enabled. Without `js_render=true`, the wait parameter will be ignored since there's no browser environment to pause within.
</Accordion>

<Accordion title="How do I know if my wait time is too short or too long?">
  Test different wait times and monitor content length, as well as the presence of target elements. If content is missing, increase the wait time. If you're getting complete content with shorter waits, you can reduce the time to improve efficiency.
</Accordion>

<Accordion title="Should I use the same wait time for all pages on a website?">
  Not necessarily. Different pages may have different loading characteristics. Product pages may require longer wait times than category pages. Consider implementing adaptive wait times based on page type or previous successful timings.
</Accordion>

<Accordion title="Can I use wait with other features?">
  Yes, the `wait` parameter works perfectly with any other feature.
</Accordion>

<Accordion title="What happens if I use both wait and wait_for?">
  When using both `wait` and `wait_for`, the `wait_for` parameter takes precedence and overrides the `wait` parameter.
</Accordion>
