Skip to main content
Instructions mode gives you full control over the sequence of actions performed in the browser, ensuring predictable and repeatable results. You manually specify each step like click, scroll, wait, or type. Common uses:
  • Load more content: Click “Show more” buttons or scroll to reveal additional items.
  • Set filters: Select dropdowns, checkboxes, or date ranges to refine displayed data.
  • Submit searches: Enter search terms and submit forms to access results pages.
  • Trigger lazy-loaded data: Scroll to load images, products, or infinite feeds.

When to use

Use Instructions mode when you need:
  • Low cost: Pay per driver usage and API calls, not token consumption
  • Predictable execution: Same steps run every time
  • Full control: Specify exact actions and sequences
  • Fast performance: No LLM inference overhead
Instructions flows may break when page structure or selectors change. Monitor and update your flows as needed.

Supported parameters

Available in - Extract.
ParameterTypeDescriptionDefault
renderBooleanEnable or disable JS rendering (required to be true)false
browser_actionsList (Objects)List of sequenced page interactions to be executed on the page-

Available actions

ActionDescription
waitAdd a delay between actions (milliseconds)
wait_forWait until a selector appears on the page
wait_and_clickWait for an element and click it
wait_and_typeWait for an input field and type text
pastePaste text into an input field quickly
scrollScroll to specific X/Y coordinates
scroll_toScroll to bring a selector into view
infinite_scrollHandle lazy-loading pages with infinite scroll
screenshotCapture a screenshot of the page
get_cookiesCollect cookies from the page
http_requestExecute additional HTTP requests
Browser Actions require page rendering to be enabled (render: true). All operations execute sequentially within a global 240-second timeout.

Usage

Wait (delay)

Add a delay between actions to simulate human behavior or allow elements to load. Parameters:
  • delay (required) - Time to pause in milliseconds
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "wait": {
                "delay": 500
            }
        }
    ]
})

print(result)

Wait for selector

Wait until a specific element appears on the page before continuing. Parameters:
  • selectors (required) - Array of CSS selectors to wait for
  • timeout (optional) - Maximum time to wait in milliseconds
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "wait_for": {
                "selectors": ["body", "#content"],
                "timeout": 2000
            }
        }
    ]
})

print(result)

Wait and click

Wait for an element to appear and click it. Parameters:
  • selector (required) - CSS selector of the element to click
  • timeout (optional) - Maximum time to wait for the click action in milliseconds
  • delay (optional) - Time to pause before executing the click in milliseconds
  • scroll (optional) - Scroll element into view if hidden (boolean)
  • visible (optional) - Wait for element to be visible, not just present in DOM (boolean)
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "wait_and_click": {
                "selector": "button.load-more",
                "timeout": 20000,
                "delay": 500,
                "scroll": True,
                "visible": False
            }
        }
    ]
})

print(result)

Wait and type

Wait for an input field and type text into it. Parameters:
  • selector (required) - CSS selector of the input element
  • value (required) - Text to type into the element
  • timeout (optional) - Maximum time to wait for the action in milliseconds
  • delay (optional) - Time to pause before typing in milliseconds
  • click_on_element (optional) - Click the element before typing (boolean)
  • visible (optional) - Wait for element to be visible (boolean)
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "wait_and_type": {
                "selector": "input[type='search']",
                "value": "eggplant",
                "timeout": 20000,
                "delay": 500,
                "click_on_element": True,
                "visible": False
            }
        }
    ]
})

print(result)

Paste

Quickly paste text into an input field. Parameters:
  • selector (required) - CSS selector of the input element
  • value (required) - Text to paste into the element
  • timeout (optional) - Maximum time to wait for the action in milliseconds
  • delay (optional) - Time to pause before pasting in milliseconds
  • click_on_element (optional) - Click the element before pasting (boolean)
  • visible (optional) - Wait for element to be visible (boolean)
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "paste": {
                "selector": "input[type='search']",
                "value": "eggplant",
                "timeout": 20000,
                "delay": 500,
                "click_on_element": True,
                "visible": False
            }
        }
    ]
})

print(result)

Scroll to coordinates

Scroll to specific X/Y coordinates on the page. Parameters:
  • x (required) - Horizontal scroll position
  • y (required) - Vertical scroll position
  • timeout (optional) - Maximum time for scroll action in milliseconds
  • scroll_in_element (optional) - CSS selector of container to scroll within (for scrolling inside sidebars, modals, etc.)
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "scroll": {
                "x": 0,
                "y": 1000,
                "timeout": 20000
            }
        }
    ]
})

print(result)

Scroll to selector

Scroll to bring a specific element into view. Parameters:
  • selector (required) - CSS selector of the element to scroll to
  • visible (optional) - Wait for element to be visible before scrolling (boolean)
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "scroll_to": {
                "selector": "#footer",
                "visible": False
            }
        }
    ]
})

print(result)

Infinite scroll

Handle lazy-loading pages that reveal content as you scroll, like social media feeds. Parameters:
  • duration (required) - Time interval for continuous scrolling in milliseconds
  • loading_selector (optional) - CSS selector for loading/spinner indicators
  • delay_after_scroll (optional) - Time to wait between scrolls in milliseconds
  • click_on_selector (optional) - CSS selector to click after each scroll (e.g., “Load more” button)
  • idle_timeout (optional) - Wait time after scroll; terminates if no page height change in milliseconds
  • scroll_in_element (optional) - CSS selector of container to scroll within
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "infinite_scroll": {
                "loading_selector": ".spinner",
                "delay_after_scroll": 2000,
                "duration": 15000,
                "idle_timeout": 5000
            }
        }
    ]
})

print(result)
Use loading_selector to track loading indicators for reliable scrolling. Alternatively, use delay_after_scroll and duration for time-based scrolling.

Capture screenshot

Take a screenshot of the page in PNG, JPEG, or WebP format. Parameters:
  • full_page (optional) - Capture entire page or just visible viewport (boolean, default: false)
  • format (optional) - Image format: png, jpeg, or webp (default: png)
  • timeout (optional) - Maximum time for screenshot processing in milliseconds (default: 30000)
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "screenshot": {
                "full_page": True,
                "format": "jpeg",
                "timeout": 30000
            }
        }
    ]
})

print(result)

Collect cookies

Capture and store cookies from the page. Parameters:
  • timeout (optional) - Time to wait for new cookies before storage in milliseconds (default: 1000)
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "get_cookies": {
                "timeout": 1000
            }
        }
    ]
})

print(result)

Execute HTTP requests

Perform additional HTTP GET/POST requests to internal APIs. Parameters:
  • url (required) - Target URL for the HTTP request
  • method (optional) - HTTP method: GET or POST (default: GET)
  • headers (optional) - Additional headers as JSON object
  • timeout (optional) - Request timeout in milliseconds
  • required (optional) - Set to false to make this step optional and continue execution on failure (boolean, default: true)
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "http_request": {
                "url": "https://api.example.com/data",
                "method": "POST",
                "headers": {
                    "Content-Type": "application/json"
                },
                "timeout": 5000
            }
        }
    ]
})

print(result)
The first http_request in a browser_actions is free. Starting from the second request, each additional http_request is billed as a VX6 request.

Chaining actions

You can chain multiple actions together in the browser_actions array. They execute sequentially.
from nimble import Nimble

nimble = Nimble(api_key="YOUR-API-KEY")

result = nimble.extract({
    "url": "https://www.example.com",
    "render": True,
    "browser_actions": [
        {
            "wait_and_type": {
                "selector": "input[type='search']",
                "value": "laptop",
                "click_on_element": True
            }
        },
        {
            "wait": {
                "delay": 1000
            }
        },
        {
            "wait_and_click": {
                "selector": "button[type='submit']"
            }
        },
        {
            "wait_for": {
                "selectors": [".results"],
                "timeout": 5000
            }
        }
    ]
})

print(result)

Example response

When browser actions complete successfully, you’ll receive the final page state along with any data captured. The response includes:
  • data: All related extacted data
    • data.html: Final DOM state after all actions
    • data.screenshot: Page screenshot if used
    • data.cookies: Collected cookies if get_cookies was used by order
    • data.http_request: HTTP response if http_request was used by order
  • metadata: Execution details including task id, driver used, execution time and more
    • metadata.browser_actions: The browser actions results per step
{
  "status": "success",
  "data": {
    "html": "<!DOCTYPE html><html>...</html>",
    "screenshot": "base64_encoded_image_data",
    "cookies": [
      {
        "name": "session_id",
        "value": "abc123xyz",
        "domain": ".example.com",
        "path": "/",
        "expires": 1735689600,
        "httpOnly": true,
        "secure": true
      }
    ],
	"http_response":[
	  {
		"status": 200,
		"duration": 235,
		"method":"POST",
		"url":"https://api.example.com/data",
		"headers":{},
		"body":"..."
	  }
	]
  },
  "metadata": {
	"task_id":".....",
	"country":"US",
    "driver": "vx10",
    "execution_time_ms": 3450,
	"browser_actions":[
	  {
		"status":"success",
		"action":"wait",
		"duration":300
  	  },
	  {
		"status":"success",
		"action":"type",
		"duration":300
  	  }
	]
  }
}

Best practices

Use required parameter for optional steps

Make non-critical steps optional:
# ✅ Continue even if optional element isn't found
browser_actions = [
    {
        "wait_and_click": {
            "selector": ".cookie-banner button",
            "required": False  # Don't fail if banner doesn't exist
        }
    },
    {
        "wait_and_click": {
            "selector": ".submit-button",
            "required": True  # This is critical
        }
    }
]

# ❌ Fail entire request if cookie banner isn't found
browser_actions = [
    {
        "wait_and_click": {
            "selector": ".cookie-banner button"
            # required defaults to True
        }
    }
]

Chain actions with appropriate waits

Add delays between actions:
# ✅ Wait for content to load between actions
browser_actions = [
    {
        "wait_and_click": {
            "selector": "button.load-more"
        }
    },
    {
        "wait": {
            "delay": 2000  # Wait for new content
        }
    },
    {
        "wait_for": {
            "selectors": [".new-content"]
        }
    }
]

# ❌ No wait - may act on stale content
browser_actions = [
    {
        "wait_and_click": {
            "selector": "button.load-more"
        }
    },
    {
        "wait_and_click": {
            "selector": ".new-content button"  # May not exist yet
        }
    }
]

Use specific selectors

Be precise with CSS selectors:
# ✅ Specific selector
selector = "button[data-testid='submit-form']"

# ✅ Unique class or ID
selector = "#unique-submit-button"

# ❌ Too generic - may match wrong element
selector = "button"

# ❌ Fragile - breaks with style changes
selector = ".btn.btn-primary.btn-lg.mt-4"

Optimize infinite scroll parameters

Set appropriate scroll limits:
# ✅ Controlled scrolling with limits
infinite_scroll = {
    "duration": 10000,  # 10 seconds max
    "loading_selector": ".spinner",
    "idle_timeout": 3000,  # Stop if no change for 3s
    "delay_after_scroll": 1000  # Wait between scrolls
}

# ❌ Excessive scrolling - slow and costly
infinite_scroll = {
    "duration": 60000,  # 60 seconds - too long
    "delay_after_scroll": 100  # Too fast - may miss content
}