The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →To generate a Browserless screenshot from PHP, make a server-side POST request to the /screenshot endpoint with a JSON body containing a page URL and screenshot options. Keep your API token on the server, check the HTTP and cURL errors, and save the response using the encoding you requested. The examples below use Browserless Cloud’s documented sample host; use the base URL for your own region or deployment if it differs.
What you need
- PHP with the cURL extension enabled, or Guzzle if your project already uses it.
- A Browserless API token, stored in a server-side environment variable such as
BROWSERLESS_API_TOKEN. - Your Browserless endpoint. The Cloud example in the documentation is
https://production-sfo.browserless.io; Browserless deployments can use a different region or base URL.
The current Screenshot API uses POST /screenshot, JSON input, and a token query parameter. This is a server-to-server call, so do not put the token in browser JavaScript or send it to visitors.
As an Amazon Associate I earn from qualifying purchases.
Make a screenshot with PHP cURL
This example requests a full-page PNG in base64 encoding, checks for transport and HTTP errors, decodes the response, and writes the image to disk. Set the environment variable before running it.
<?php
$token = getenv('BROWSERLESS_API_TOKEN');
if (!$token) {
throw new RuntimeException('Set BROWSERLESS_API_TOKEN in the server environment.');
}
$endpoint = 'https://production-sfo.browserless.io/screenshot';
$query = http_build_query(['token' => $token]);
$url = $endpoint . '?' . $query;
$payload = [
'url' => 'https://example.com/',
'options' => [
'fullPage' => true,
'type' => 'png',
'encoding' => 'base64',
],
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
CURLOPT_TIMEOUT => 90,
]);
$response = curl_exec($ch);
if ($response === false) {
$message = curl_error($ch);
curl_close($ch);
throw new RuntimeException('Browserless request failed: ' . $message);
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status < 200 || $status >= 300) {
throw new RuntimeException('Browserless returned HTTP ' . $status . ': ' . $response);
}
$image = base64_decode($response, true);
if ($image === false) {
throw new RuntimeException('Browserless response was not valid base64 image data.');
}
if (file_put_contents(__DIR__ . '/screenshot.png', $image) === false) {
throw new RuntimeException('Could not write screenshot.png.');
}
The sample hostname is not universal: substitute your assigned Cloud region or self-hosted endpoint while keeping the /screenshot path. The token is placed in the query string as required by this API; avoid logging the complete request URL because it contains the credential.
#1 Best Overall
Binary response alternative
If you request a raw image response instead of base64, do not call base64_decode(). Save the returned bytes directly. Match the requested image type and file extension, and retain the HTTP-status and transport-error checks either way. The Screenshot API’s image formats include PNG, JPEG, and WebP.
Use Guzzle instead
Guzzle is useful when your application already uses it and you want its response and exception handling. Install it through Composer if it is not already a project dependency. This request follows Browserless’s documented JSON-body and token-query pattern:
Rank #2
<?php
require __DIR__ . '/vendor/autoload.php';
$token = getenv('BROWSERLESS_API_TOKEN');
if (!$token) {
throw new RuntimeException('Set BROWSERLESS_API_TOKEN in the server environment.');
}
$client = new GuzzleHttpClient([
'base_uri' => 'https://production-sfo.browserless.io/',
'timeout' => 90,
]);
try {
$response = $client->post('screenshot', [
'query' => ['token' => $token],
'json' => [
'url' => 'https://example.com/',
'options' => [
'fullPage' => true,
'type' => 'png',
'encoding' => 'base64',
],
],
]);
$status = $response->getStatusCode();
$encoded = (string) $response->getBody();
if ($status < 200 || $status >= 300) {
throw new RuntimeException('Browserless returned HTTP ' . $status . ': ' . $encoded);
}
$image = base64_decode($encoded, true);
if ($image === false) {
throw new RuntimeException('Browserless response was not valid base64 image data.');
}
if (file_put_contents(__DIR__ . '/screenshot.png', $image) === false) {
throw new RuntimeException('Could not write screenshot.png.');
}
} catch (GuzzleHttpExceptionRequestException $e) {
throw new RuntimeException('Browserless request failed: ' . $e->getMessage(), 0, $e);
}
Use your deployment’s actual endpoint here too. Browserless documents Guzzle as an HTTP-client integration; a separate Laravel package mentioned in its documentation is community-supported, maintained by Christopher Miller, and is not officially supported by Browserless.
Choose the right capture options
Whole page, viewport, or one element
- Set
options.fullPagetotruewhen you need the full document rather than only the visible viewport. - Use selector capture when the output should contain one page element, or clip coordinates and viewport settings when you need a fixed region or screen-sized view.
- For pages that reveal images or content as the visitor scrolls, Browserless documents
scrollPage: trueas a way to help trigger lazy-loaded material before a full-page capture.
Format, dimensions, and timing
The Screenshot API supports PNG, JPEG, and WebP image data. Screenshot options also include quality, viewport size, device scale factor, and wait conditions. Choose a wait condition that reflects the page you need: a page can finish its initial navigation before all application content or images are ready. Navigation settings and request or resource blocking are also available when a capture needs different loading behavior.
Capture supplied HTML instead of a URL
For markup you provide directly, send an html field rather than url; do not send both in the same request. The endpoint also supports injecting scripts or styles before capture. This is useful for rendering a supplied HTML fragment or applying capture-specific presentation without hosting that markup as a web page.
Understand the REST endpoint’s limits
Browserless describes REST calls as stateless, single-action requests: each request launches a browser, performs one task, and closes the session. A screenshot call is therefore a good fit for independent captures, not for a flow that must click through several states, fill forms, branch on page content, or preserve login state between actions. For those cases, use Browserless’s session-oriented browser control or BrowserQL rather than trying to chain state through separate screenshot requests.
Rank #4
Do not assume the screenshot endpoint guarantees successful access to every site. A target may require interaction or present bot checks; the documentation does not establish that this screenshot call will bypass such challenges. Where a task depends on interaction or retained state, choose the appropriate browser-control route and handle site access in line with the site’s requirements.
Free tools Windows power users keep installed
One-click scans. No signup required.
Troubleshoot common failures
- cURL reports an error: check that PHP’s cURL extension is installed and enabled, that the server can reach the configured endpoint, and that the timeout is suitable for the page. The code reports
curl_error()before attempting to interpret a response. - The API returns a non-2xx status: inspect the status and response body before decoding or saving it. Confirm the token, endpoint/region, JSON request, and target URL rather than writing an error response as an image.
- The saved file is corrupt or empty: make the requested encoding and file handling agree. Base64 responses must be decoded strictly; raw binary responses must be written as bytes without decoding. Also check that PHP can write to the destination directory.
- The screenshot misses lower-page images or content: confirm that full-page mode is enabled and consider the documented
scrollPageoption to trigger lazy loading. Use an appropriate wait condition if the page populates content asynchronously. - The capture shows the wrong region: check whether you requested a full page, a selector, or a clip, then verify the viewport and clip coordinates against the intended output.
- The task needs a sequence of actions: a single REST screenshot call cannot preserve a multi-step browser session. Switch to Browserless sessions or BrowserQL for interaction and retained state.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. Its one-call endpoint returns a screenshot or PDF; the PHP cURL example below saves a WebP response. See the ScreenshotNeo API documentation for request options and setup.
<?php
$apiKey = getenv('SCREENSHOTNEO_API_KEY');
if (!$apiKey) {
throw new RuntimeException('Set SCREENSHOTNEO_API_KEY in the server environment.');
}
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.screenshotneo.com/v1/shot?' . http_build_query([
'access_key' => $apiKey,
'url' => 'https://example.com/',
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 90,
]);
$image = curl_exec($ch);
if ($image === false) {
$message = curl_error($ch);
curl_close($ch);
throw new RuntimeException('ScreenshotNeo request failed: ' . $message);
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status < 200 || $status >= 300) {
throw new RuntimeException('ScreenshotNeo returned HTTP ' . $status);
}
if (file_put_contents(__DIR__ . '/shot.webp', $image) === false) {
throw new RuntimeException('Could not write shot.webp.');
}
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and the response identifies the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
Frequently Asked Questions
Can I return the screenshot directly to a browser instead of saving a file?
Yes. After validating the response and its content type, PHP can send the matching image content type and output the image bytes instead of writing them to disk. Keep the Browserless token and request on the server.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallIs the old Browserless BaaS v1 screenshot page the right API reference?
No. The older BaaS v1 screenshot page is marked deprecated; use the current Screenshot API request format described here.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




