PHP SDK
The official PHP SDK for RenderScreenshot. For Laravel, Symfony and PHPUnit examples, see the PHP screenshot API guide.
Installation
composer require renderscreenshot/renderscreenshot
Requirements
- PHP 8.0 or higher
Quick Start
use RenderScreenshot\Client; use RenderScreenshot\TakeOptions; $client = new Client('rs_live_xxxxx'); // Take a screenshot $image = $client->take( TakeOptions::url('https://example.com')->preset('og_card') ); // Save to file file_put_contents('screenshot.png', $image);
Client
Constructor
use RenderScreenshot\Client; $client = new Client($apiKey, $baseUrl, $timeout, $httpClient, $signingKey, $publicKeyId); // Typical usage with named arguments: $client = new Client( 'rs_live_xxxxx', signingKey: 'rs_secret_xxxxx', // only needed for generateUrl() publicKeyId: 'rs_pub_xxxxx' // only needed for generateUrl() );
| Parameter | Type | Description |
|---|---|---|
$apiKey |
string | Your secret API key (rs_live_*) |
$baseUrl |
?string | API base URL (default: https://api.renderscreenshot.com) |
$timeout |
?float | Request timeout in seconds (default: 30.0) |
$httpClient |
?GuzzleHttp\Client | Custom Guzzle client, for example in tests (optional) |
$signingKey |
?string | Secret signing key (rs_secret_*) for signed URLs (optional) |
$publicKeyId |
?string | Public key ID (rs_pub_*) for signed URLs (optional) |
Methods
take($options)
Take a screenshot and return binary data. The SDK sends POST /v1/screenshot with a nested JSON body (for example viewport.width, capture.mode, output.format).
$image = $client->take( TakeOptions::url('https://example.com')->preset('og_card') ); // Save to file file_put_contents('screenshot.png', $image);
Returns: string (binary data)
takeJson($options)
Take a screenshot and return JSON metadata. The SDK sends the same request as take() with the Accept: application/json header.
$response = $client->takeJson( TakeOptions::url('https://example.com')->preset('og_card') ); echo $response['id']; // "req_..." echo $response['status']; // "completed" echo $response['image']['url']; // CDN URL echo $response['image']['width']; // 1200 echo $response['image']['height']; // 630 echo $response['image']['size']; // bytes echo $response['image']['format']; // "png" var_dump($response['cache']['hit'] ?? false); // true when served from cache echo $response['cache']['expires_at'] ?? ''; // ISO 8601, optional echo $response['usage']['credits'] ?? 0; // credits used, optional echo $response['usage']['remaining'] ?? 0; // credits left, optional
Returns: array (ScreenshotResponse)
generateUrl($options, $expiresAt, $signingKey = null, $publicKeyId = null)
Generate a signed URL for public embedding. Signed URLs work only with the GET render endpoint (GET /v1/screenshot), so the URL includes only options that the GET endpoint reads. Signing needs your public key ID (rs_pub_*) and your secret signing key (rs_secret_*). Your rs_live_* API key does not sign URLs. Keep the signing key on your server.
use DateTime; use RenderScreenshot\Client; use RenderScreenshot\TakeOptions; $client = new Client( 'rs_live_xxxxx', signingKey: 'rs_secret_xxxxx', publicKeyId: 'rs_pub_xxxxx' ); $signedUrl = $client->generateUrl( TakeOptions::url('https://example.com')->preset('og_card'), new DateTime('+24 hours') // maximum 30 days ); // Use in HTML: <img src="<?= $signedUrl ?>" /> // Or pass the signing credentials per call: $signedUrl = $client->generateUrl( TakeOptions::url('https://example.com')->width(1200)->height(630), new DateTime('+1 hour'), 'rs_secret_xxxxx', 'rs_pub_xxxxx' );
The URL contains key_id, expires, the flat GET parameters, and a signature (hex HMAC-SHA256 of the sorted query string). generateUrl() throws InvalidArgumentException if the signing key or the public key ID is missing.
Returns: string
batch($urls, $options) / batchAdvanced($requests)
Process multiple screenshots in a batch.
// Simple batch $results = $client->batch( ['https://example1.com', 'https://example2.com'], TakeOptions::url('')->preset('og_card') ); // Advanced batch with per-URL options $results = $client->batchAdvanced([ ['url' => 'https://example1.com', 'options' => ['preset' => 'og_card']], ['url' => 'https://example2.com', 'options' => ['width' => 1920]], ]);
Returns: array (BatchResponse)
getBatch($batchId)
Get the status of a batch job.
$status = $client->getBatch('batch_abc123'); echo $status['completed'] . '/' . $status['total'];
Returns: array (BatchResponse)
presets() / preset($id)
Get available presets.
$presets = $client->presets(); $ogCard = $client->preset('og_card');
devices()
Get available device presets.
$devices = $client->devices();
TakeOptions
Fluent builder for screenshot options.
Creating Options
use RenderScreenshot\TakeOptions; // From URL $options = TakeOptions::url('https://example.com'); // From HTML $options = TakeOptions::html('<h1>Hello World</h1>'); // From config array $options = TakeOptions::fromConfig(['url' => '...', 'width' => 1200]);
Viewport Options
TakeOptions::url('...') ->width(1200) // Viewport width ->height(630) // Viewport height ->scale(2) // Device scale factor (1-3) ->mobile(); // Enable mobile emulation
Capture Options
TakeOptions::url('...') ->fullPage() // Capture full scrollable page ->element('.hero') // Capture specific element ->format('png') // png, jpeg, webp, pdf ->quality(90); // JPEG/WebP quality (1-100)
Wait Options
TakeOptions::url('...') ->waitFor('networkidle') // load, networkidle, domcontentloaded ->delay(2000) // Additional delay (ms) ->waitForSelector('.loaded') // Wait for selector ->waitForTimeout(30); // Max wait time (s, 1-60)
Presets & Devices
TakeOptions::url('...') ->preset('og_card') // Use a preset ->device('iphone_14_pro'); // Emulate a device
Content Blocking
TakeOptions::url('...') ->blockAds() // Block ad networks ->blockTrackers() // Block analytics ->blockCookieBanners() // Auto-dismiss cookie popups ->blockChatWidgets() // Block chat widgets ->blockUrls(['*.ads.com/*']) // Block URL patterns ->blockResources(['font']); // Block resource types
Browser Emulation
TakeOptions::url('...') ->darkMode() // Enable dark mode ->reducedMotion() // Prefer reduced motion ->mediaType('print') // screen or print ->userAgent('Custom UA') // Custom user agent ->timezone('America/New_York') ->locale('en-US') ->geolocation(40.7128, -74.006);
Network Options
TakeOptions::url('...') ->headers(['X-Custom' => 'value']) ->cookies([['name' => 'session', 'value' => 'abc', 'domain' => 'example.com']]) ->authBasic('user', 'pass') ->authBearer('token') ->bypassCsp();
Cache Options
TakeOptions::url('...') ->cacheTtl(86400) // Cache TTL in seconds ->cacheAvailable() // Reuse an identical render inside the TTL (0 credits) ->cacheRefresh(); // Force refresh
PDF Options
TakeOptions::url('...') ->format('pdf') ->pdfPaperSize('a4') // a4, letter, legal, etc. ->pdfLandscape() ->pdfMargin('1in') ->pdfPrintBackground() ->pdfHeader('<div>Header</div>') ->pdfFooter('<div>Page <span class="pageNumber"></span></div>');
Storage Options (BYOS)
TakeOptions::url('...') ->storageEnabled() ->storagePath('{year}/{month}/{hash}.{ext}') ->storageAcl('public-read');
Cache Management
// Get cached screenshot $image = $client->cache->get('cache_xyz789'); // Delete single entry $client->cache->delete('cache_xyz789'); // Bulk purge by keys $client->cache->purge(['cache_abc', 'cache_def']); // Purge by URL pattern $client->cache->purgeUrl('https://mysite.com/blog/*'); // Purge by date use DateTime; $client->cache->purgeBefore(new DateTime('2024-01-01'));
Webhook Helpers
use RenderScreenshot\Webhook; // Verify signature $isValid = Webhook::verify($payload, $signature, $timestamp, $secret); // Parse event $event = Webhook::parse($payload); if ($event['type'] === 'screenshot.completed') { echo $event['data']['response']['url']; } elseif ($event['type'] === 'screenshot.failed') { echo $event['data']['error']['code']; // e.g. 'timeout', or null echo $event['data']['error']['message']; } // $event['raw'] holds the unmodified `data` object // Extract headers from $_SERVER [$signature, $timestamp] = Webhook::extractHeaders($_SERVER);
Error Handling
use RenderScreenshot\Client; use RenderScreenshot\TakeOptions; use RenderScreenshot\RenderScreenshotException; try { $client->take(TakeOptions::url('...')); } catch (RenderScreenshotException $e) { echo $e->httpStatus; // 400, 429, etc. echo $e->errorCode; // 'invalid_url', 'rate_limited' echo $e->getMessage(); // Human-readable message echo $e->retryable; // true/false echo $e->retryAfter; // Seconds (for rate limits) }
Error Codes
| Code | HTTP | Retryable | Description |
|---|---|---|---|
invalid_request |
400 | No | Malformed request |
invalid_url |
400 | No | Invalid URL provided |
unauthorized |
401 | No | Invalid API key |
forbidden |
403 | No | Access denied |
not_found |
404 | No | Resource not found |
rate_limited |
429 | Yes | Rate limit exceeded |
timeout |
408 | Yes | Screenshot timed out |
render_failed |
500 | Yes | Browser rendering failed |
internal_error |
500 | Yes | Internal server error |