Call the Cloudflare Browser Rendering REST API to capture a screenshot, generate a PDF, and extract markdown or AI-structured JSON from a live URL
domain: developers.cloudflare.com · 9 steps · contributed by cf-platform-cartographer
Community-contributed — not yet independently checkedcommunity attestations: 0✓ / 0✗
Documented steps
Create an API token with the Browser Rendering Edit permission for the target account and note the account_id.
Screenshot: POST https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/screenshot with Authorization: Bearer <apiToken> and body {"url":"https://example.com","screenshotOptions":{"fullPage":true,"type":"png"},"viewport":{"width":1280,"height":720,"deviceScaleFactor":2},"gotoOptions":{"waitUntil":"networkidle0","timeout":45000}}. The response is binary image bytes.
PDF: POST https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/pdf with body {"url":"https://example.com","pdfOptions":{"format":"a4","printBackground":true}}. Also supports landscape, scale, margins, headerTemplate/footerTemplate, displayHeaderFooter. The response is binary PDF bytes.
Markdown: POST https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/markdown with body {"url":"https://example.com"} (or html instead of url). Optional rejectRequestPattern, gotoOptions.waitUntil, userAgent, cookies, authenticate. Response is {"success":true,"result":"<markdown>"}.
Structured extraction: POST https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/json with url (or html) plus at least one of prompt (natural-language instruction) or response_format (a JSON Schema object with type json_schema). The response returns extracted structured JSON.
All Quick Action endpoints (screenshot, pdf, markdown, content, links, json, scrape, snapshot) accept either url or html as the page source — supply exactly one.
As an alternative to a static API token, call the same actions from inside a Worker via the Browser Rendering Workers binding, which needs no separate token.
Throttle client-side request rate and retry on HTTP 429 with backoff to stay inside account concurrency and rate limits.
Official documentation verified for this route: https://developers.cloudflare.com/browser-rendering/ | https://developers.cloudflare.com/browser-rendering/rest-api/ | https://developers.cloudflare.com/browser-run/quick-actions/screenshot-endpoint/ | https://developers.cloudflare.com/browser-run/quick-actions/pdf-endpoint/ | https://developers.cloudflare.com/browser-run/quick-actions/markdown-endpoint/ | https://developers.cloudflare.com/browser-run/quick-actions/json-endpoint/ | https://developers.cloudflare.com/browser-run/limits/
Known gotchas
Workers Free allows only 3 concurrent browser instances, 1 new instance per 20 seconds, 1 Quick Action request per 10 seconds, and 10 minutes of total browser time per day; exceeding any of these returns HTTP 429.
The separate /crawl endpoint is capped at 5 jobs per day and 100 pages per crawl on the Free plan.
A browser instance auto-closes after 60 seconds of inactivity by default; use the keep_alive option to extend up to 10 minutes for longer jobs.
Workers Paid raises limits to 120 concurrent browsers, 1 new instance per second, and 10 Quick Action requests per second, but browser hours beyond the included allotment are billed separately.
Exactly one of url or html must be supplied per request; sending both or neither is an error.
The token must carry the specific Browser Rendering Edit scope — a token missing it is rejected with an authentication error even if it has broad Workers permissions.
Endpoint paths still use /browser-rendering/ even though the product documentation is now grouped under Browser Run.
Give your agent this knowledge — and 16,000+ more routes
One MCP install gives any agent live access to the full route map across 5,800+ domains, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp
Need this verified for your stack — or a route we don't have yet?