Screenshot
Capture a screenshot of the rendered page as a PNG. The image comes back Base64-encoded, ready to store, embed as a data URI, or decode to a file.
This is a web operation — no AI, metered against your web allowance.
POST/screenshot
Capture a screenshot
Body parameters
- Name
url- Type
- string
- Required
- Required
- Description
- The absolute URL of the page to process. Rendered with headless Chrome, so JavaScript runs and redirects are followed. It must not include a username or password (
https://user:pass@example.com).
- Name
report_to- Type
- string
- Description
- Webhook URL — an
httporhttpsaddress URLpipe POSTs the result to when it's ready. Optional: without it we deliver to your project's default endpoint if it has one, and otherwise send no webhook at all — the result still waits for you at GET /result/:token. A value we cannot deliver to returns422. Ignored on async=truerequest. Deliveries can be signed so your endpoint can verify they came from us.
- Name
sync- Type
- boolean
- Description
- Process the request synchronously, returning the result inline in the response. Defaults to
false(async: return a token now, and either receive the result at a webhook or fetch it with GET /result/:token). See Async & sync modes for the full contract.
- Name
max_age- Type
- string | integer
- Description
- How fresh a cached result must be to be accepted. Either an integer number of seconds (
3600) or a duration string of the form"<number> <unit>"— unitss/min/h/d/w(e.g."2 hours","3 days","30m"). Defaults to7 days, clamped to a max of30 days;0always bypasses the cache. See Caching for all accepted units.
Response
Content type text/plain — the body is a Base64-encoded PNG. Decode it to bytes, or prefix it with data:image/png;base64, to use it directly in an <img> tag.
POST/screenshot
curl -X POST https://urlpipe.dev/screenshot \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'import requests
res = requests.post(
"https://urlpipe.dev/screenshot",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"url": "https://example.com"},
)const res = await fetch("https://urlpipe.dev/screenshot", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com" }),
})$ch = curl_init("https://urlpipe.dev/screenshot");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode(["url" => "https://example.com"]),
]);
$response = curl_exec($ch);
curl_close($ch);Response
iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAABb2m…
(Base64-encoded PNG, truncated)Decoding the image
curl -s -X POST https://urlpipe.dev/screenshot \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}' \
| base64 --decode > screenshot.pngimport base64, requests
res = requests.post(
"https://urlpipe.dev/screenshot",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"url": "https://example.com"},
)
with open("screenshot.png", "wb") as f:
f.write(base64.b64decode(res.text))const res = await fetch("https://urlpipe.dev/screenshot", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com" }),
})
const base64 = await res.text()
const dataUri = `data:image/png;base64,${base64}`$ch = curl_init("https://urlpipe.dev/screenshot");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode(["url" => "https://example.com"]),
]);
$base64 = curl_exec($ch);
curl_close($ch);
file_put_contents("screenshot.png", base64_decode($base64));Screenshots can take a few seconds for heavy pages. For batches or slow sites, consider async mode so you're not holding a connection open.
Responses
Whatever the status, the response carries metadata headers: the result token, whether it was served from cache and how old that result is, how long we took, and the quota you have left.
Status
When
Body
200 OKThe request succeeded.
Sync: the result, in this endpoint's format (see Response above). Async: a job token — { "token": "…", "status": "accepted" }.
422 Unprocessable EntityThe analysis failed, or a parameter was invalid (a bad max_age, or a report_to we will not deliver to).
{ "error": "<message>" }
429 Too Many RequestsYou've hit your monthly quota for this operation's category (checked only on a cache miss).
{ "error": "quota_exceeded", "category", "limit", "used", "resets_at" }
504 Gateway TimeoutSync only: the analysis didn't finish within 60s. It keeps running — fetch it via GET /result/:token.
{ "error": "processing_timeout", "token": "…" }
401 UnauthorizedMissing or invalid API key.
—
Try it live — no API key needed
Run this endpoint against any URL right in your browser.