ScreenshotNeo

BlogHow-to

Abstract Screenshot API Example for a Website Screenshot in PHP

Learn how to request a website screenshot from Abstract’s API in PHP, validate the image response, save it safely, and handle common errors.

By the ScreenshotNeo team4 October 20268 min read

To take a website screenshot in PHP with Abstract, send an HTTPS GET request to https://screenshot.abstractapi.com/v1/ with your API key and the target URL, then save the successful response body as image bytes. Abstract documents URL and raw HTML input and image output including JPEG, PNG, and GIF. Its reviewed official material does not provide a PHP-specific sample, so the cURL example below implements the documented HTTP request rather than reproducing an official PHP SDK example. Abstract’s product page documents the endpoint and service. Abstract API documentation index.

1. Prepare PHP and your API key

Use PHP with the cURL extension enabled. Create an API key in your Abstract account, then store it in an environment variable such as ABSTRACT_API_KEY. Keep the key on the server: the documented request puts api_key in the query string, so do not place it in browser JavaScript, commit it, or log the complete request URL.

export ABSTRACT_API_KEY="YOUR_API_KEY"
php -v
php -m | grep -i curl

If cURL is absent, enable or install the PHP cURL extension for your environment before running the example.

2. Complete PHP cURL example

Save as screenshot.php. Pass the target URL as the first command-line argument. The code encodes both query parameters, sets connection and total timeouts, checks the HTTP status and content type, and writes the response only when it is a successful image response.

<?php
declare(strict_types=1);

$apiKey = getenv('ABSTRACT_API_KEY');
if ($apiKey === false || $apiKey === '') {
    fwrite(STDERR, "Set ABSTRACT_API_KEY in the environment.\n");
    exit(1);
}

$targetUrl = $argv[1] ?? '';
if ($targetUrl === '' || !filter_var($targetUrl, FILTER_VALIDATE_URL)) {
    fwrite(STDERR, "Usage: ABSTRACT_API_KEY=... php screenshot.php https://example.com\n");
    exit(1);
}
$scheme = strtolower((string) parse_url($targetUrl, PHP_URL_SCHEME));
if (!in_array($scheme, ['http', 'https'], true)) {
    fwrite(STDERR, "Target URL must use http or https.\n");
    exit(1);
}

$query = http_build_query(
    ['api_key' => $apiKey, 'url' => $targetUrl],
    '',
    '&',
    PHP_QUERY_RFC3986
);
$endpoint = 'https://screenshot.abstractapi.com/v1/?' . $query;

$ch = curl_init($endpoint);
if ($ch === false) {
    fwrite(STDERR, "Could not initialize cURL.\n");
    exit(1);
}
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT => 90,
    CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
    CURLOPT_HTTPHEADER => ['Accept: image/*'],
]);
$body = curl_exec($ch);
$curlError = curl_error($ch);
$status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = (string) curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
curl_close($ch);

if ($body === false) {
    fwrite(STDERR, "Request failed: {$curlError}\n");
    exit(1);
}
if ($status < 200 || $status >= 300) {
    // Do not print the request URL: it contains the API key.
    fwrite(STDERR, "Abstract returned HTTP {$status}. Response: " . substr((string) $body, 0, 1000) . "\n");
    exit(1);
}
if (stripos($contentType, 'image/') !== 0) {
    fwrite(STDERR, "Expected an image response; received Content-Type: {$contentType}\n");
    exit(1);
}

$output = 'website-screenshot.' . match (strtolower(trim(explode(';', $contentType)[0]))) {
    'image/png' => 'png',
    'image/jpeg' => 'jpg',
    'image/gif' => 'gif',
    default => 'img',
};
if (file_put_contents($output, $body, LOCK_EX) === false) {
    fwrite(STDERR, "Could not write {$output}; check the directory permissions and free space.\n");
    exit(1);
}
printf("Saved %s (%d bytes)\n", $output, strlen($body));

Run it with a URL you are allowed to capture:

ABSTRACT_API_KEY="YOUR_API_KEY" php screenshot.php "https://example.com"

The destination URL is encoded as a query parameter, including any ampersands or other reserved characters in its own query string. Keep the target URL quoted in the shell. This example validates the response’s HTTP status and image content type before saving; it does not claim that the returned image content has been visually checked.

3. What the request does and what you can configure

The documented endpoint is a hosted REST API, not a PHP screenshot library. The basic request sends api_key and url as query parameters over HTTPS. Abstract describes taking screenshots from either a URL or submitted raw HTML and returning image formats such as JPEG, PNG, and GIF.

Need What the reviewed product material says Implementation guidance
Image format Format selection is a described capability; JPEG, PNG, and GIF are named outputs. Check the live API reference for the exact parameter name and accepted values before adding it to the request.
Viewport or dimensions Viewport and dimension controls are described. Confirm exact width, height, and viewport syntax in the current reference; do not assume names from another screenshot API.
CSS styling Custom CSS is described. Use only documented parameter names and account for URL encoding when supplying CSS.
Capture timing Delayed capture or custom timing is described. Use the documented delay control for pages that populate content after initial load; a delay cannot fix a page that never loads.
Input A URL or raw HTML can be used. The runnable sample covers URL input. Consult the live reference for the exact raw-HTML request format.

Exact parameter names and values for these controls are not exposed by the reviewed product page or documentation index. Verify them in the current API reference before extending the sample; do not infer parameter syntax from examples for other vendors.

4. Use the response safely in an application

  • Choose a controlled output path. The command-line sample uses a fixed name. In a web app, generate a server-side identifier and prevent user input from choosing arbitrary filesystem paths.
  • Set request limits. The example uses a 10-second connection timeout and a 90-second total timeout. Adjust those to the latency budget of your application and the API’s current behavior.
  • Do not expose credentials. Keep the request on your backend, restrict access to saved screenshots, and redact API keys from logs and error reports.
  • Handle image bytes as binary. Do not run the response through text encoding or JSON decoding when the endpoint returns an image.
  • Validate the target URL. If users provide URLs, allow only the schemes and destinations your product needs. Apply your own outbound-request controls to reduce server-side request forgery risk.
  • Clean up stored files. Define retention and access rules for screenshots, which can contain personal or confidential page content.

5. Troubleshooting

Symptom Likely cause What to do
“Set ABSTRACT_API_KEY” The process cannot see the environment variable. Export it in the same shell or configure it in the PHP process manager or deployment secret store.
cURL initialization or extension error PHP cURL is not enabled in the runtime being used. Enable the cURL extension for that PHP installation, then confirm with php -m.
cURL timeout or connection failure Network connectivity, DNS, TLS, or a slow capture may be responsible. Check outbound HTTPS access and DNS from the server; distinguish connection timeout from total timeout and set an application-appropriate limit.
Non-2xx HTTP status The API rejected the request, credentials, target, or account usage. Inspect the short response body printed by the sample, without logging the key-bearing URL. Check the key and current API documentation/account status.
Unexpected non-image content type The response may be an API error body, or the endpoint behavior or request may differ from expectation. Do not save it with an image extension. Inspect a safely redacted response and verify the endpoint and parameters against the current reference.
Image is blank or content is missing The target may render content late, require interaction, or block automated access. Try the documented timing controls where appropriate, verify the page is publicly reachable, and check the service’s current capture options. The reviewed source does not establish a universal fix for bot checks or protected pages.
Image file cannot be written The output directory may not be writable, or disk space may be exhausted. Choose an application-controlled writable directory and check permissions and available space.
Target URL with query parameters behaves incorrectly The target URL was not encoded as a single query parameter. Build the query with http_build_query as shown; do not concatenate a raw URL into the endpoint string.

6. Performance, reliability, and cost

A hosted screenshot request includes remote page loading and rendering, so the target page’s response and rendering behavior affect completion time. Set a total timeout that fits your user-facing flow. For recurring snapshots, queue work outside the web request, record status and retry transient failures with a capped retry policy, and avoid retrying permanent credential or input errors.

Abstract’s product page lists a Free plan at $0 with 100 requests and a 1 request-per-second limit. Its Standard plan display is inconsistent: the monthly billing view shows 60,000 requests per month at $99/month paid annually, while the yearly billing view shows 60,000 requests per year. Check the live plan display before budgeting or stating a quota. The page lists custom Enterprise pricing and a 99.99% uptime SLA; these are vendor-published figures, not independent performance measurements. The reviewed material does not provide a PHP latency benchmark.

For cost control, cache screenshots when the same URL and capture settings are requested repeatedly, deduplicate concurrent requests for identical inputs, and track request volume against the plan’s current allowance and rate limit. The product page gives vendor use cases including device QA, recurring snapshots, embedded previews, monitoring placements, and security previews.

7. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. Use its one-call API instead of managing screenshot browser infrastructure; see the ScreenshotNeo API documentation.

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 and consent prompts are accepted, and 60+ known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off.
  • Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Responses say which outcome occurred through X-Page-Verdict and X-Billed headers.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 shots.

Sign up free for 1,000 ScreenshotNeo screenshots a month, with no card required.

8. FAQ

Is there an official PHP SDK example for Abstract?

The official material reviewed for this guide documents the REST endpoint but does not provide a PHP-specific sample. The cURL code here is an implementation of the documented GET request.

Can I screenshot HTML that is not hosted at a public URL?

Abstract describes raw HTML input as supported. Check the current API reference for its exact request format before adapting the URL-based example.

Can Abstract render a screenshot from a particular geographic location?

The reviewed product FAQ says captures from different locations are not currently supported and describes that capability as planned. This may change, so verify the current product documentation if location matters.

Can I use this PHP example from a browser page?

Run it on a server. A server-side request keeps the API key out of browser code and lets your application control storage, access, and request limits.