Screenshot API for PHP

Capture screenshots and PDFs from PHP with Guzzle or the built-in cURL extension. No SDK required.

There is no official PHP SDK. None is needed - the API is a single JSON POST, so Guzzle or the bundled cURL extension is enough. Both are shown below.

Install

composer require guzzlehttp/guzzle

Your first screenshot in PHP

One POST, one JSON body, one URL back. The response is a CDN link to the finished image.

Guzzle

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

$client = new GuzzleHttp\Client();

$response = $client->post('https://api.getsnap.dev/v1/screenshot', [
    'headers' => ['X-API-Key' => 'sk_live_YOUR_KEY'],
    'json'    => ['url' => 'https://github.com', 'format' => 'png'],
    'timeout' => 60,
]);

$data = json_decode((string) $response->getBody(), true);
echo $data['url'];   // CDN URL to your screenshot

cURL extension (no dependencies)

<?php
$ch = curl_init('https://api.getsnap.dev/v1/screenshot');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 60,
    CURLOPT_HTTPHEADER     => [
        'X-API-Key: sk_live_YOUR_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'url'    => 'https://github.com',
        'format' => 'png',
    ]),
]);

$body = curl_exec($ch);
curl_close($ch);

echo json_decode($body, true)['url'];

Full-page captures and other options

Every option is a field in the same JSON body. The common ones are full-page capture, popup and ad removal, viewport size, and lazy-load scrolling.

$response = $client->post('https://api.getsnap.dev/v1/screenshot', [
    'headers' => ['X-API-Key' => 'sk_live_YOUR_KEY'],
    'json' => [
        'url'             => 'https://example.com',
        'format'          => 'png',
        'full_page'       => true,
        'remove_popups'   => true,
        'block_ads'       => true,
        'viewport_width'  => 1280,
        'viewport_height' => 720,
    ],
]);

Saving the image to disk

By default you get a CDN URL. Ask for a binary response instead and you get the bytes directly, which saves a round-trip when you are storing the file yourself.

<?php
// response_type "binary" returns the image bytes instead of a JSON URL
$response = $client->post('https://api.getsnap.dev/v1/screenshot', [
    'headers' => ['X-API-Key' => 'sk_live_YOUR_KEY'],
    'json'    => [
        'url'           => 'https://example.com',
        'format'        => 'webp',
        'quality'       => 90,
        'response_type' => 'binary',
    ],
]);

file_put_contents('screenshot.webp', (string) $response->getBody());

Handling errors

Every failure returns JSON with an error code and a human-readable message. These are the ones worth branching on:

StatuserrorWhat it means
400validation_errorA field is missing or out of range. The body names the field.
401unauthorizedMissing or unknown API key.
402quota_exceededMonthly capture limit reached.
429rate_limit_exceededToo many requests this minute. Back off and retry.
500capture_failedThe page could not be rendered - usually a timeout on a page that never settles.
<?php
use GuzzleHttp\Exception\ClientException;

try {
    $response = $client->post('https://api.getsnap.dev/v1/screenshot', [
        'headers' => ['X-API-Key' => 'sk_live_YOUR_KEY'],
        'json'    => ['url' => 'https://example.com'],
    ]);
    echo json_decode((string) $response->getBody(), true)['url'];
} catch (ClientException $e) {
    $status = $e->getResponse()->getStatusCode();
    $body   = json_decode((string) $e->getResponse()->getBody(), true);
    // e.g. 402 quota_exceeded
    echo "$status {$body['error']}: {$body['message']}";
}

Rate limits and quotas

PlanCaptures / monthRequests / minute
Free1005
Starter5,00030
Pro25,00060
Business100,000120

Exceeding the per-minute limit returns 429; exceeding the monthly quota returns 402. See pricing for the full breakdown.

Frequently asked questions

Is there an official PHP SDK for taking screenshots?

No, and you do not need one. The API is a single JSON POST to one endpoint, so PHP's standard HTTP client is enough. Everything on this page uses it.

Do I need to run or manage a headless browser?

No. getSnap.dev runs Chromium server-side and returns a finished image, PDF or video. You never install Playwright or Puppeteer, and you never maintain a browser pool.

Is there a free tier?

Yes - 100 captures a month at 5 requests a minute, with no credit card required. Paid plans start at $9/month for 5,000 captures at 30 requests a minute.

How do I capture a page that requires login from PHP?

Pass your own cookies or HTTP headers in the request body and the capture runs authenticated. Use a dedicated least-privilege account rather than your own session.

Next steps

Related reading

Start capturing from PHP

100 screenshots a month on the free tier. No credit card required.

Get Free API Key