ScreenshotNeo

BlogHow-to

How to Capture Website Screenshots with Browshot in PHP

Capture and save website screenshots with Browshot in PHP. Compare the Simple and full APIs, handle asynchronous jobs, and troubleshoot common errors.

By the ScreenshotNeo team4 October 20269 min read

To capture a website screenshot with Browshot in PHP, install its PHP library, initialize a Browshot client with your API key, then use the Simple API for a direct screenshot or the full API when you need configurable, asynchronous jobs. Check the result before saving it: a request can be processing or fail instead of returning image bytes.

Choose the Browshot API workflow

Workflow Use it when What your PHP code handles
Simple API You need a straightforward screenshot and can wait for the call to finish. A single call; follow redirects while Browshot processes the capture.
Full API You need capture settings or want control over job status and retrieval. Create a job, poll until it finishes or errors, then retrieve the image.

Browshot describes the Simple API as easier but slower. The full API exposes more controls and requires handling asynchronous states. Use the Simple API for a first working capture; use the full API for production workflows that need settings such as full-page capture or a delay for JavaScript-rendered content.

Install the PHP library and configure credentials

Browshot’s PHP documentation describes installation through Composer or by including the library file directly, and states a PHP requirement of 5.1.6 or above. Its documentation shows this Composer command:

composer require browshot-php/browshot=dev-master

The documentation points to Packagist for the latest package version. Confirm the current package and constraint there before pinning a production dependency. Load Composer’s autoloader and keep the API key outside source control, such as in an environment variable:

<?php
require __DIR__ . '/vendor/autoload.php';

$apiKey = getenv('BROWSHOT_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set BROWSHOT_API_KEY before running this script.');
}

$browshot = new Browshot($apiKey);

The library documentation also describes including Browshot.php directly instead of using Composer. Prefer a dependency manager for application projects so the installed version is explicit and repeatable.

Capture a screenshot with the Simple API

The Simple API is the shortest path when you want one screenshot returned to your PHP process. This example saves the PNG bytes only after checking the result:

<?php
require __DIR__ . '/vendor/autoload.php';

$apiKey = getenv('BROWSHOT_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set BROWSHOT_API_KEY before running this script.');
}

$browshot = new Browshot($apiKey);
$url = 'https://example.com';

$result = $browshot->screenshot(
    $url,
    array('instance_id' => 12)
);

if (!is_array($result) || !isset($result['code']) || $result['code'] !== 200) {
    $detail = is_array($result) ? json_encode($result) : var_export($result, true);
    throw new RuntimeException('Browshot did not return a successful screenshot: ' . $detail);
}

$image = isset($result['image']) ? $result['image'] : null;
if (!is_string($image) || $image === '') {
    throw new RuntimeException('The successful response did not contain screenshot bytes.');
}

if (file_put_contents(__DIR__ . '/screenshot.png', $image) === false) {
    throw new RuntimeException('Could not write screenshot.png');
}

echo "Saved screenshot.png\n";

Browshot’s PHP examples show the Simple API returning a result when the screenshot has finished or failed, and provide a file helper as another way to write the result. Confirm the exact return structure against the library version you install; do not assume every response contains an image. The Simple API may redirect while the capture is processing, so the HTTP client must follow 302/307 redirects.

Use the full API for configurable or asynchronous captures

The full API creates a screenshot job from the target URL and an instance ID. A response may report in_process; check its status until it reaches finished or error, then retrieve the screenshot. The following illustrates bounded polling so a slow or stuck job cannot loop forever. Adapt method arguments and returned fields to the version of the Browshot PHP library you use:

<?php
require __DIR__ . '/vendor/autoload.php';

$apiKey = getenv('BROWSHOT_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set BROWSHOT_API_KEY before running this script.');
}

$browshot = new Browshot($apiKey);
$url = 'https://example.com';
$options = array(
    'instance_id' => 12,
    'size' => 'page',
    'cache' => 0,
    'delay' => 3,
    'width' => 1365,
    'height' => 900,
);

$created = $browshot->screenshot_create($url, $options);
if (!is_array($created) || empty($created['id'])) {
    throw new RuntimeException('Could not create screenshot job: ' . json_encode($created));
}
$screenshotId = $created['id'];

$deadline = time() + 150;
$info = null;
do {
    $info = $browshot->screenshot_info($screenshotId);
    if (!is_array($info) || !isset($info['status'])) {
        throw new RuntimeException('Unexpected status response: ' . json_encode($info));
    }
    if ($info['status'] === 'finished' || $info['status'] === 'error') {
        break;
    }
    if ($info['status'] !== 'in_process') {
        throw new RuntimeException('Unexpected Browshot status: ' . $info['status']);
    }
    if (time() >= $deadline) {
        throw new RuntimeException('Screenshot job exceeded the 150-second polling limit.');
    }
    sleep(3);
} while (true);

if ($info['status'] === 'error') {
    throw new RuntimeException('Browshot reported a screenshot error: ' . json_encode($info));
}

// The library also documents helpers for retrieving the image or a thumbnail.
$image = $browshot->screenshot_download($screenshotId);
if (!is_string($image) || $image === '') {
    throw new RuntimeException('Screenshot retrieval returned no image bytes.');
}
if (file_put_contents(__DIR__ . '/screenshot.png', $image) === false) {
    throw new RuntimeException('Could not write screenshot.png');
}
echo "Saved screenshot.png\n";

The full API documentation describes creating a screenshot, looking up job information, and retrieving an image or thumbnail. Method signatures and download helpers can vary by library release; check the installed library documentation if its return shape differs. The ten-second sleep in Browshot’s sample is an example, not a universal polling interval. This example uses a three-second interval and a deadline; choose an interval that fits your latency and request-volume needs.

Set capture options for the page you need

Option What it controls Practical use
instance_id The browser instance used for the capture; required by the full screenshot API. Use an instance available to your account. Browshot documents instance 12 as the default free Simple API instance when no ID is supplied.
size screen captures the viewport; page requests the full page. Use screen for above-the-fold previews and page for long-page archives.
cache Whether an eligible prior screenshot can be reused within Browshot’s cache window. Use the default for repeat captures when freshness is not essential; set cache=0 to request a fresh capture.
delay Additional wait after page load before capture. Allow client-rendered content or late layout changes time to appear.
Viewport width and height Browser dimensions used to render the page. Match the target desktop or mobile layout when checking responsive behavior.
JavaScript and CSS target settings Optional script execution and CSS-target selection controls. Use these when the page needs an interaction or only a specific element should be captured.
Hide popups Suppresses selected overlays in supported workflows. Use for screenshots where a popup obscures the page content.
Thumbnail retrieval Returns a smaller version of the screenshot. Use for previews or lists where full-resolution files are unnecessary.

Check Browshot’s current API documentation for accepted parameter names and constraints before relying on any setting. The API supports custom POST data for form submissions. Custom referrer and cookie settings are documented for paid screenshots; these and POST data can contain sensitive information, so send them only when authorized and never log credentials.

Understand response codes and job states

Do not treat every response as a PNG. Browshot documents these Simple API outcomes:

Response Meaning Action
200 Successful PNG response. Save or process the image bytes.
302 or 307 The screenshot is still processing and the request is redirected. Follow the redirect; set a suitable client timeout.
400 The request is invalid. Check required parameters, URL encoding, and option values.
404 The screenshot failed. Inspect the response details and verify the target is reachable.

For the full API, handle in_process, finished, and error as distinct job states. Download only after finished; surface the error details for failed jobs.

Reliability, performance, and cost

  • Bound waiting: A page can take up to two minutes according to Browshot’s documentation. Give the HTTP client a timeout that accommodates the capture, follow redirects, and use a bounded retry or polling policy.
  • Prefer asynchronous work for queues: The full API lets your application create a job and check status separately, which avoids holding a web request open while a slow page renders.
  • Use cache deliberately: Reuse cached results when the page need not be fresh; use cache=0 when each capture must reflect current content. Fresh captures can take longer and may consume credits differently; confirm current account terms.
  • Limit output size: Viewport screenshots and thumbnails are smaller than full-page images. Select the smallest output that meets the downstream need.
  • Check the current allowance: Browshot’s reviewed API documentation describes up to 100 free screenshots per month on instance 12, and says private and shared instances require a positive balance. Limits and service terms can change, so verify them in current official documentation and your account before budgeting.

Troubleshooting

Symptom Likely cause Fix
The PHP call returns a redirect or non-image response. The Simple API is still processing, or the client does not follow redirects. Enable 302/307 redirect handling or switch to the full API and poll the job.
The API returns 400. A required parameter is missing, the URL is malformed, or an option is invalid. Validate the URL, include the required instance ID for the full API, and check documented option values.
The API returns 404 or the full job status is error. The target capture failed. Inspect the response or job details, then check whether the URL is reachable and whether it blocks automated browsers.
The screenshot is blank or missing dynamic content. The page renders content after the capture point, or requires JavaScript. Allow JavaScript and add a suitable post-load delay; use the full API options for more control.
The output is only the visible screen. The default size is screen. Request size=page for a full-page capture.
The screenshot shows stale content. A cached screenshot was reused. Request cache=0 when a fresh capture is required.
The file is empty or corrupt. Error data or a status response was written as if it were image bytes. Check the HTTP/API result and content before writing; save only successful image bytes.
The script loops or waits too long. Polling has no deadline or uses an unsuitable interval. Stop at a bounded deadline, handle unexpected states, and adjust the polling interval for your workload.
A paid option fails or is ignored. The account or instance may not support a paid-only setting. Check current account balance and feature eligibility; Browshot documents custom referrer and cookie settings as paid features.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request returns an image or PDF, and its API accepts parameter names used by other screenshot APIs for easier switching. The PHP setup above gives you direct control through Browshot; if you want a hosted capture workflow, this is the ScreenshotNeo request pattern. See the ScreenshotNeo API documentation for options and response details.

<?php
$url = 'https://stripe.com';
$query = http_build_query(array(
    'access_key' => getenv('SCREENSHOTNEO_API_KEY'),
    'url' => $url,
));
$response = file_get_contents('https://api.screenshotneo.com/v1/shot?' . $query);
if ($response === false) {
    throw new RuntimeException('ScreenshotNeo request failed.');
}
file_put_contents(__DIR__ . '/shot.webp', $response);

For reference, the same one-call request is available in cURL, Python, and Node.js:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie banners, popups, and chat widgets are removed before the screenshot; each cleanup step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed; response headers report the page verdict and billing status.
  • An MCP server gives AI agents tools to take screenshots, inspect page information, and capture PDFs.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000 screenshots.

Create a free ScreenshotNeo account to try 1,000 screenshots a month with no card.

FAQ

Can I use Browshot to submit a form before capturing?

Browshot documents custom POST data for form submissions. Confirm the supported request fields in the current API docs and avoid sending credentials unless you are authorized to access the target.

Can I get a smaller image instead of the full screenshot?

Yes. The full API supports retrieving a thumbnail as well as the screenshot image.

Should I use the Simple API in a web request handler?

It is convenient for a small synchronous task, but capture time can be long. For user-facing request paths or batches, create a full API job and handle completion outside the request lifecycle.

Where should I verify Browshot’s current limits?

Check Browshot’s current API and PHP library documentation and your account before relying on a quota, feature, or price.

Primary references