← Browser Run / browser-run / quick-actions
/screenshot - Capture screenshot
The /screenshot endpoint renders the webpage by processing its HTML and JavaScript, then captures a screenshot of the fully rendered page.
You can use this endpoint in two ways:
- REST API: Create a custom API Token with
Browser Rendering - Editpermission. - Workers Bindings: Call the endpoint directly from a Cloudflare Worker using the Workers Bindings. No API token is needed.
For more information, refer to Quick Actions: Before you begin.
Endpoint
https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshotRequired fields
You must provide either url or html:
url(string)html(string)
Common use cases
- Generate previews for websites, dashboards, or reports
- Capture screenshots for automated testing, QA, or visual regression
Basic usage
Take a screenshot from custom HTML
Sets the HTML content of the page to Hello World! and then takes a screenshot. The option omitBackground hides the default white background and allows capturing screenshots with transparency.
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"html": "Hello World!",
"screenshotOptions": {
"omitBackground": true
}
}' \
--output "screenshot.png"import Cloudflare from "cloudflare";
const client = new Cloudflare({
apiToken: process.env["CLOUDFLARE_API_TOKEN"],
});
const screenshot = await client.browserRendering.screenshot.create({
account_id: process.env["CLOUDFLARE_ACCOUNT_ID"],
html: "Hello World!",
screenshotOptions: {
omitBackground: true,
},
});
console.log(screenshot.status);interface Env {
BROWSER: BrowserRun;
}
export default {
async fetch(request, env): Promise<Response> {
return await env.BROWSER.quickAction("screenshot", {
html: "Hello World!",
screenshotOptions: {
omitBackground: true,
},
});
},
} satisfies ExportedHandler<Env>;Take a screenshot from a URL
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com"
}' \
--output "screenshot.png"For more options to control the final screenshot, like clip, captureBeyondViewport, fullPage and others, check the endpoint reference.
Advanced usage
Capture a screenshot of an authenticated page
Some webpages require authentication before you can view their content. Browser Run supports three authentication methods, which work across all Quick Actions endpoints. For a quick reference of all methods, refer to How do I render authenticated pages using Quick Actions?.
Cookie-based authentication
Provide valid session cookies to access pages that require login:
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/protected-page",
"cookies": [
{
"name": "session_id",
"value": "your-session-cookie-value",
"domain": "example.com",
"path": "/"
}
]
}' \
--output "authenticated-screenshot.png"HTTP Basic Auth
Use the authenticate parameter for pages behind HTTP Basic Authentication:
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/protected-page",
"authenticate": {
"username": "user",
"password": "pass"
}
}' \
--output "authenticated-screenshot.png"Token-based authentication
Add custom authorization headers using setExtraHTTPHeaders:
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/protected-page",
"setExtraHTTPHeaders": {
"Authorization": "Bearer your-token"
}
}' \
--output "authenticated-screenshot.png"Navigate and capture a full-page screenshot
Navigate to https://cloudflare.com/, change the page size (viewport) and wait until there are no active network connections (waitUntil) or up to a maximum of 4500ms (timeout) before capturing a fullPage screenshot.
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://cloudflare.com/",
"screenshotOptions": {
"fullPage": true
},
"viewport": {
"width": 1280,
"height": 720
},
"gotoOptions": {
"waitUntil": "networkidle0",
"timeout": 45000
}
}' \
--output "advanced-screenshot.png"Improve blurry screenshot resolution
If you set a large viewport width and height, your screenshot may appear blurry or pixelated. This can happen if your browser's default deviceScaleFactor (which defaults to 1) is not high enough for the viewport.
To fix this, increase the value of the deviceScaleFactor.
{
"url": "https://cloudflare.com/",
"viewport": {
"width": 3600,
"height": 2400,
"deviceScaleFactor": 2
}
}Customize CSS and embed custom JavaScript
Instruct the browser to go to https://example.com, embed custom JavaScript (addScriptTag) and add extra styles (addStyleTag), both inline (addStyleTag.content) and by loading an external stylesheet (addStyleTag.url).
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"addScriptTag": [
{ "content": "document.querySelector(`h1`).innerText = `Hello World!!!`" }
],
"addStyleTag": [
{
"content": "div { background: linear-gradient(45deg, #2980b9 , #82e0aa ); }"
},
{
"url": "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
}
]
}' \
--output "screenshot.png"Capture a specific element using the selector option
To capture a screenshot of a specific element on a webpage, use the selector option with a valid CSS selector. You can also configure the viewport to control the page dimensions during rendering.
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<accountId>/browser-rendering/screenshot' \
-H 'Authorization: Bearer <apiToken>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com",
"selector": "#example_element_name",
"viewport": {
"width": 1200,
"height": 1600
}
}' \
--output "screenshot.png"Many more options exist, like setting HTTP credentials using authenticate, setting cookies, and using gotoOptions to control page load behaviour - check the endpoint reference for all available parameters.
Handling JavaScript-heavy pages
For JavaScript-heavy pages or Single Page Applications (SPAs), the default page load behavior may return empty or incomplete results. This happens because the browser considers the page loaded before JavaScript has finished rendering the content.
The simplest solution is to use the gotoOptions.waitUntil parameter set to networkidle0 or networkidle2:
{
"url": "https://example.com",
"gotoOptions": {
"waitUntil": "networkidle0"
}
}For faster responses, advanced users can use waitForSelector to wait for a specific element instead of waiting for all network activity to stop. This requires knowing which CSS selector indicates the content you need has loaded. For more details, refer to Quick Actions timeouts.
Set a custom user agent
You can change the user agent at the page level by passing userAgent as a top-level parameter in the JSON body. This is useful if the target website serves different content based on the user agent.
Troubleshooting
If you have questions or encounter an error, see the Browser Run FAQ and troubleshooting guide.