Timeout Configuration
This document explains how to configure timeouts for Browserless REST APIs. Proper timeout configuration is essential for reliable browser automation, especially when dealing with slow-loading pages or complex interactions.
Overview
Browserless REST APIs support timeout configuration through two methods:
- Query Parameter Timeout: Global timeout for the entire request
- JSON Body Timeout Parameters: Granular timeout control for specific operations
All timeout values are specified in milliseconds.
Query Parameter Timeout
You can set a global timeout for any REST API request using the timeout
query parameter. This controls the maximum duration for the entire operation.
For detailed information about query parameter timeouts, see the Launch Parameters documentation.
JSON Body Timeout Parameters
REST APIs support several timeout parameters in the JSON request body for fine-grained control over different operations:
Navigation Timeouts (gotoOptions.timeout
)
Controls how long to wait for page navigation to complete. This is part of the gotoOptions
object which mirrors Puppeteer's GoToOptions interface.
- JSON payload
- cURL
- JavaScript
- Python
- Java
- C#
{
"url": "https://example.com/",
"gotoOptions": {
"timeout": 30000,
"waitUntil": "networkidle2"
}
}
curl -X POST \
https://production-sfo.browserless.io/content?token=YOUR_API_TOKEN_HERE \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"gotoOptions": {
"timeout": 30000,
"waitUntil": "networkidle2"
}
}'
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/content?token=${TOKEN}`;
const data = {
url: "https://example.com/",
gotoOptions: {
timeout: 30000,
waitUntil: "networkidle2"
}
};
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const content = await response.text();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/content?token={TOKEN}"
data = {
"url": "https://example.com/",
"gotoOptions": {
"timeout": 30000,
"waitUntil": "networkidle2"
}
}
response = requests.post(url, json=data)
content = response.text
import java.net.URI;
import java.net.http.*;
import com.google.gson.*;
public class NavigationTimeout {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/content?token=" + TOKEN;
String jsonData = new Gson().toJson(Map.of(
"url", "https://example.com/",
"gotoOptions", Map.of(
"timeout", 30000,
"waitUntil", "networkidle2"
)
));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/content?token={TOKEN}";
var payload = new
{
url = "https://example.com/",
gotoOptions = new
{
timeout = 30000,
waitUntil = "networkidle2"
}
};
var jsonContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var client = new HttpClient();
var response = await client.PostAsync(url, jsonContent);
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
}
Selector Timeouts (waitForSelector.timeout
)
Controls how long to wait for a specific element to appear on the page. If the element doesn't appear within the timeout period, the operation will fail (unless bestAttempt
is enabled).
- JSON payload
- cURL
- JavaScript
- Python
- Java
- C#
{
"url": "https://example.com/",
"waitForSelector": {
"selector": "#main-content",
"timeout": 10000,
"visible": true
}
}
curl -X POST \
https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN_HERE \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"waitForSelector": {
"selector": "#main-content",
"timeout": 10000,
"visible": true
}
}' \
--output "screenshot.png"
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/screenshot?token=${TOKEN}`;
const data = {
url: "https://example.com/",
waitForSelector: {
selector: "#main-content",
timeout: 10000,
visible: true
}
};
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const imageBuffer = await response.arrayBuffer();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/screenshot?token={TOKEN}"
data = {
"url": "https://example.com/",
"waitForSelector": {
"selector": "#main-content",
"timeout": 10000,
"visible": True
}
}
response = requests.post(url, json=data)
with open("screenshot.png", "wb") as f:
f.write(response.content)
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
import com.google.gson.*;
public class SelectorTimeout {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/screenshot?token=" + TOKEN;
String jsonData = new Gson().toJson(Map.of(
"url", "https://example.com/",
"waitForSelector", Map.of(
"selector", "#main-content",
"timeout", 10000,
"visible", true
)
));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
Files.copy(response.body(), Paths.get("screenshot.png"), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/screenshot?token={TOKEN}";
var payload = new
{
url = "https://example.com/",
waitForSelector = new
{
selector = "#main-content",
timeout = 10000,
visible = true
}
};
var jsonContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var client = new HttpClient();
var response = await client.PostAsync(url, jsonContent);
var imageBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("screenshot.png", imageBytes);
}
}
Function Timeouts (waitForFunction.timeout
)
Controls how long to wait for a custom JavaScript function to return a truthy value. Useful for waiting on complex conditions or asynchronous operations.
- JSON payload
- cURL
- JavaScript
- Python
- Java
- C#
{
"url": "https://example.com/",
"waitForFunction": {
"fn": "() => document.querySelector('#dynamic-content').textContent.includes('loaded')",
"timeout": 15000
}
}
curl -X POST \
https://production-sfo.browserless.io/content?token=YOUR_API_TOKEN_HERE \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"waitForFunction": {
"fn": "() => document.querySelector(\"#dynamic-content\").textContent.includes(\"loaded\")",
"timeout": 15000
}
}'
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/content?token=${TOKEN}`;
const data = {
url: "https://example.com/",
waitForFunction: {
fn: "() => document.querySelector('#dynamic-content').textContent.includes('loaded')",
timeout: 15000
}
};
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const content = await response.text();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/content?token={TOKEN}"
data = {
"url": "https://example.com/",
"waitForFunction": {
"fn": "() => document.querySelector('#dynamic-content').textContent.includes('loaded')",
"timeout": 15000
}
}
response = requests.post(url, json=data)
content = response.text
import java.net.URI;
import java.net.http.*;
import com.google.gson.*;
public class FunctionTimeout {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/content?token=" + TOKEN;
String jsonData = new Gson().toJson(Map.of(
"url", "https://example.com/",
"waitForFunction", Map.of(
"fn", "() => document.querySelector('#dynamic-content').textContent.includes('loaded')",
"timeout", 15000
)
));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/content?token={TOKEN}";
var payload = new
{
url = "https://example.com/",
waitForFunction = new
{
fn = "() => document.querySelector('#dynamic-content').textContent.includes('loaded')",
timeout = 15000
}
};
var jsonContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var client = new HttpClient();
var response = await client.PostAsync(url, jsonContent);
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
}
Event Timeouts (waitForEvent.timeout
)
Controls how long to wait for a specific DOM event to fire before proceeding with the operation.
- JSON payload
- cURL
- JavaScript
- Python
- Java
- C#
{
"url": "https://example.com/",
"waitForEvent": {
"event": "load",
"timeout": 8000
}
}
curl -X POST \
https://production-sfo.browserless.io/pdf?token=YOUR_API_TOKEN_HERE \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"waitForEvent": {
"event": "load",
"timeout": 8000
}
}'
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/pdf?token=${TOKEN}`;
const data = {
url: "https://example.com/",
waitForEvent: {
event: "load",
timeout: 8000
}
};
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const pdfBuffer = await response.arrayBuffer();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/pdf?token={TOKEN}"
data = {
"url": "https://example.com/",
"waitForEvent": {
"event": "load",
"timeout": 8000
}
}
response = requests.post(url, json=data)
with open("output.pdf", "wb") as f:
f.write(response.content)
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
import com.google.gson.*;
public class EventTimeout {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/pdf?token=" + TOKEN;
String jsonData = new Gson().toJson(Map.of(
"url", "https://example.com/",
"waitForEvent", Map.of(
"event", "load",
"timeout", 8000
)
));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
Files.copy(response.body(), Paths.get("output.pdf"), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/pdf?token={TOKEN}";
var payload = new
{
url = "https://example.com/",
waitForEvent = new
{
@event = "load",
timeout = 8000
}
};
var jsonContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var client = new HttpClient();
var response = await client.PostAsync(url, jsonContent);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("output.pdf", pdfBytes);
}
}
Fixed Delay Timeout (waitForTimeout
)
Waits for a specified number of milliseconds before proceeding. Useful when you need to wait for animations, transitions, or other time-based operations to complete.
- JSON payload
- cURL
- JavaScript
- Python
- Java
- C#
{
"url": "https://example.com/",
"waitForTimeout": 3000
}
curl -X POST \
https://production-sfo.browserless.io/scrape?token=YOUR_API_TOKEN_HERE \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"elements": [
{ "selector": "h1" }
],
"waitForTimeout": 3000
}'
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/scrape?token=${TOKEN}`;
const data = {
url: "https://example.com/",
elements: [
{ selector: "h1" }
],
waitForTimeout: 3000
};
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const scrapedData = await response.json();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/scrape?token={TOKEN}"
data = {
"url": "https://example.com/",
"elements": [
{ "selector": "h1" }
],
"waitForTimeout": 3000
}
response = requests.post(url, json=data)
scraped_data = response.json()
import java.net.URI;
import java.net.http.*;
import com.google.gson.*;
public class FixedTimeout {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/scrape?token=" + TOKEN;
String jsonData = new Gson().toJson(Map.of(
"url", "https://example.com/",
"elements", List.of(Map.of("selector", "h1")),
"waitForTimeout", 3000
));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/scrape?token={TOKEN}";
var payload = new
{
url = "https://example.com/",
elements = new[] { new { selector = "h1" } },
waitForTimeout = 3000
};
var jsonContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
using var client = new HttpClient();
var response = await client.PostAsync(url, jsonContent);
var scrapedData = await response.Content.ReadAsStringAsync();
Console.WriteLine(scrapedData);
}
}
Combining Multiple Timeout Parameters
You can combine multiple timeout parameters in a single request for comprehensive control over the browser automation process:
- JSON payload
- cURL
{
"url": "https://example.com/",
"gotoOptions": {
"timeout": 30000,
"waitUntil": "networkidle2"
},
"waitForSelector": {
"selector": "#content",
"timeout": 10000,
"visible": true
},
"waitForTimeout": 2000
}
curl -X POST \
https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN_HERE&timeout=60000 \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"gotoOptions": {
"timeout": 30000,
"waitUntil": "networkidle2"
},
"waitForSelector": {
"selector": "#content",
"timeout": 10000,
"visible": true
},
"waitForTimeout": 2000
}' \
--output "screenshot.png"
Error Handling with bestAttempt
When using timeout parameters, you can enable the bestAttempt
option to make Browserless continue processing even if timeout operations fail:
{
"url": "https://example.com/",
"bestAttempt": true,
"waitForSelector": {
"selector": "#might-not-exist",
"timeout": 5000
}
}
With bestAttempt: true
, the request will continue even if the selector timeout fails, allowing you to capture partial results.
Best Practices
-
Set Realistic Timeouts: Don't set timeouts too low for slow-loading content, but avoid unnecessarily high values that could delay error detection.
-
Use Appropriate
waitUntil
Options: Choose the right navigation completion criteria:load
: Wait for the load event (fastest)domcontentloaded
: Wait for DOM to be readynetworkidle0
: Wait until no network requests for 500msnetworkidle2
: Wait until ≤2 network requests for 500ms
-
Combine Timeouts Strategically: Use navigation timeouts for page loading, selector timeouts for dynamic content, and fixed delays sparingly.
-
Monitor Total Request Time: Remember that the query parameter timeout applies to the entire request, including all wait operations.
-
Handle Timeout Errors: Always implement proper error handling for timeout scenarios in your application code.
Supported APIs
These timeout parameters are supported across all major Browserless REST APIs:
- /content - Extract page content
- /screenshot - Capture screenshots
- /pdf - Generate PDFs
- /scrape - Scrape structured data
- /export - Export page resources
- /function - Execute custom functions
For API-specific timeout examples and use cases, refer to the individual API documentation pages.