curl --request POST \
--url https://api.screenshotapi.tech/v1/screenshot \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://example.com",
"format": "png",
"sync": false
}
'import requests
url = "https://api.screenshotapi.tech/v1/screenshot"
payload = {
"url": "https://example.com",
"format": "png",
"sync": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://example.com', format: 'png', sync: false})
};
fetch('https://api.screenshotapi.tech/v1/screenshot', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.screenshotapi.tech/v1/screenshot",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.com',
'format' => 'png',
'sync' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.screenshotapi.tech/v1/screenshot"
payload := strings.NewReader("{\n \"url\": \"https://example.com\",\n \"format\": \"png\",\n \"sync\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.screenshotapi.tech/v1/screenshot")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://example.com\",\n \"format\": \"png\",\n \"sync\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.screenshotapi.tech/v1/screenshot")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://example.com\",\n \"format\": \"png\",\n \"sync\": false\n}"
response = http.request(request)
puts response.read_body{
"ok": true,
"request_id": "<string>",
"data": {
"url": "<string>",
"final_url": "<string>",
"format": "<string>",
"width": 123,
"height": 123,
"bytes": 123,
"duration_ms": 123,
"cached": false,
"blocked_requests": 0,
"data_url": "<string>",
"cdn_url": "<string>",
"region": "<string>",
"egress_country": "<string>",
"render_diagnostics": {
"version": 123,
"algorithm": "by_sections",
"sections": 1,
"device_scale_factor": 123,
"scroll_height": 1,
"stopped_reason": "<string>",
"truncated": true
},
"inspection": {
"markdown": "<string>",
"accessible_tree": "<string>",
"untrusted_content": true,
"character_limit": 12000
}
}
}{
"ok": true,
"request_id": "<string>",
"data": {
"job_id": "<string>",
"state": "waiting",
"poll_url": "<string>"
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}Create a capture
Requires screenshot:write. Accepts a JSON body of at most 256 KiB. Returns capture data on 200 or a job handle on 202, including when sync is true. A query mode=async overrides the body’s sync flag. Successful viewport images cost 1 credit, full-page images 2, and PDFs 3. Use the same key and identical request on an idempotent retry.
curl --request POST \
--url https://api.screenshotapi.tech/v1/screenshot \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://example.com",
"format": "png",
"sync": false
}
'import requests
url = "https://api.screenshotapi.tech/v1/screenshot"
payload = {
"url": "https://example.com",
"format": "png",
"sync": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://example.com', format: 'png', sync: false})
};
fetch('https://api.screenshotapi.tech/v1/screenshot', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.screenshotapi.tech/v1/screenshot",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.com',
'format' => 'png',
'sync' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.screenshotapi.tech/v1/screenshot"
payload := strings.NewReader("{\n \"url\": \"https://example.com\",\n \"format\": \"png\",\n \"sync\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.screenshotapi.tech/v1/screenshot")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"url\": \"https://example.com\",\n \"format\": \"png\",\n \"sync\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.screenshotapi.tech/v1/screenshot")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"url\": \"https://example.com\",\n \"format\": \"png\",\n \"sync\": false\n}"
response = http.request(request)
puts response.read_body{
"ok": true,
"request_id": "<string>",
"data": {
"url": "<string>",
"final_url": "<string>",
"format": "<string>",
"width": 123,
"height": 123,
"bytes": 123,
"duration_ms": 123,
"cached": false,
"blocked_requests": 0,
"data_url": "<string>",
"cdn_url": "<string>",
"region": "<string>",
"egress_country": "<string>",
"render_diagnostics": {
"version": 123,
"algorithm": "by_sections",
"sections": 1,
"device_scale_factor": 123,
"scroll_height": 1,
"stopped_reason": "<string>",
"truncated": true
},
"inspection": {
"markdown": "<string>",
"accessible_tree": "<string>",
"untrusted_content": true,
"character_limit": 12000
}
}
}{
"ok": true,
"request_id": "<string>",
"data": {
"job_id": "<string>",
"state": "waiting",
"poll_url": "<string>"
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}{
"ok": false,
"request_id": "<string>",
"error": {
"code": "invalid_request",
"message": "<string>",
"retriable": true,
"request_id": "<string>",
"docs_url": "<string>",
"details": {}
}
}Authorizations
Active sf_live_ API key with endpoint-specific scopes. Keep this credential server-side.
Headers
Stable logical submission key. Reuse with identical configuration and the same API key.
1 - 128^[A-Za-z0-9._-]+$Query Parameters
Optional asynchronous override.
async Body
Public HTTP or HTTPS target. Bare hostnames are normalized to HTTPS. Private network destinations are blocked by the hosted service.
1CSS-pixel viewport and output density. A device preset takes precedence over an explicit viewport.
Show child attributes
Show child attributes
Supported preset identifier; takes precedence over viewport settings.
desktop_standard, desktop_hd, desktop_2k, desktop_4k, iphone_15_pro, iphone_15_pro_max, iphone_17_pro_max, pixel_8, ipad_pro_11 Capture the scrollable page. Successful full-page images cost 2 credits.
Section capture is the default. Native uses the alternative full-page path.
by_sections, native Delay between full-page scroll steps, in milliseconds.
0 <= x <= 5000Full-page scroll step in CSS pixels.
120 <= x <= 2160Reduce motion while capturing.
Output format. Full-page by_sections PDFs package rendered pixels; native and viewport PDFs use browser PDF export. PDFs cost 3 credits and cannot be combined with selector.
png, jpeg, webp, pdf JPEG or WebP encoding quality; does not control PNG encoding.
1 <= x <= 100Additional wait after page settlement, in milliseconds.
0 <= x <= 30000Capture/navigation time budget in milliseconds, independent of the synchronous HTTP wait budget.
1000 <= x <= 60000CSS readiness selector to wait for before capture.
Enable content-readiness waiting for dynamic pages.
Enable additional network-idle settlement.
Navigation milestone to wait for.
load, domcontentloaded, networkidle Reject detected incomplete or loading-shell captures.
Required text markers, trimmed before validation.
321 - 500Disallowed text markers, trimmed before validation.
321 - 500Minimum output height accepted by quality checks.
Minimum encoded output bytes accepted by quality checks.
Emulate a dark preference when color_scheme is not explicitly set.
Explicit browser color-scheme preference.
light, dark, no-preference Browser locale; overrides the region locale if supplied.
IANA browser timezone; overrides the region timezone if supplied.
Explicit browser user agent.
Country-aligned locale/timezone preset and expected egress country. Does not provision a managed proxy.
us, ca, gb, ie, de, fr, es, it, nl, sg, au, jp, kr, in, br, mx, za, ae Caller-supplied public proxy endpoint and optional authentication.
Show child attributes
Show child attributes
Verify observed egress country when a region is requested.
Enable ad filtering.
Enable cookie-banner filtering.
Enable chat-widget filtering.
Enable tracker filtering.
Capture the first matching visible element. Not supported with PDF.
Suppress matching elements.
Remove matching nodes; can affect layout.
CSS injected into the target page.
JavaScript executed in the target page.
Headers sent to the target, not credentials for the ScreenshotAPI request. Keep target credentials private.
Show child attributes
Show child attributes
Wait for immediate completion when true; a slow or queued capture still returns 202. The mode=async query overrides this field.
Maximum capture reuse age in seconds. Zero requests a fresh capture; not a storage-lifetime guarantee.
x >= 0Shared engine storage flag. Hosted REST output still requires a downloadable artifact.
Extract readable Markdown and accessibility text from this render (12,000 characters each). Untrusted page content; normal capture credits apply and image caches are bypassed.
Public HTTPS callback on port 443 with a 16–256 character signing secret. Delivered after terminal settlement.
Show child attributes
Show child attributes