Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.zenrows.com/llms.txt

Use this file to discover all available pages before exploring further.

The response_type=pdf parameter tells ZenRows to render the target page and return it as a PDF file instead of HTML. The result is a pixel-perfect snapshot of the page as it appears in a browser, including styles, images, and JavaScript-rendered content. This is useful when you need to archive pages, generate reports, produce shareable snapshots, or feed visual page content into document processing pipelines.
response_type=pdf cannot be combined with the outputs parameter. Use one or the other depending on whether you need a rendered PDF or targeted data extraction.

How it works

PDF generation always requires a full browser render. When you add response_type=pdf to your request, ZenRows automatically enables JavaScript rendering and captures the fully rendered page as a PDF. You must include js_render=true explicitly in your request for the PDF response to work.
Find more details on our JS Rendering Documentation.
The returned binary content is a standard PDF file that you can save to disk, upload to storage, or pass directly to a document processing tool.

Basic usage

Add response_type=pdf and js_render=true to your request parameters:
import requests

url = "https://www.scrapingcourse.com/ecommerce/"
apikey = "YOUR_ZENROWS_API_KEY"

params = {
    "url": url,
    "apikey": apikey,
    "js_render": "true",
    "response_type": "pdf",
}

response = requests.get("https://api.zenrows.com/v1/", params=params)
print(response.text)

Saving the PDF to disk

The API returns the PDF as binary content. Use response.content (not response.text) to write it correctly to a file:
Python
import requests

url = "https://www.scrapingcourse.com/ecommerce/"
apikey = "YOUR_ZENROWS_API_KEY"

params = {
    "url": url,
    "apikey": apikey,
    "js_render": "true",
    "response_type": "pdf",
}

response = requests.get("https://api.zenrows.com/v1/", params=params)

with open("output.pdf", "wb") as file:
    file.write(response.content)

print("PDF saved to output.pdf")
Always write the response as binary ("wb" mode in Python). Writing it as text will corrupt the PDF file.

When to use PDF response

PDF response is the right choice when you need a visual, printable, or archivable snapshot of a page. It works well for:
  • Page archiving: capture a timestamped visual record of a page’s content and layout.
  • Report generation: convert data-rich pages, dashboards, or invoices into portable PDF documents.
  • Compliance and auditing: preserve the rendered state of a page as it appeared at a specific point in time.
  • Document pipelines: feed rendered page snapshots into PDF processing tools, OCR engines, or document management systems.
  • Sharing and distribution: generate a shareable, print-ready version of a page without requiring the recipient to visit the URL.
If you need to extract text or structured data from the page rather than a visual snapshot, use response_type=markdown, response_type=plaintext, or the outputs parameter instead.

Best practices

Always include js_render=true:
PDF generation requires a full browser render. Requests without js_render=true will not return a valid PDF.
Use wait or wait_for for pages with delayed content:
If the page loads content after the initial render (lazy-loaded images, deferred scripts), use wait (milliseconds) or wait_for (CSS selector) to ensure the full page is visible before the PDF is captured.
Save as binary, not text:
PDF files are binary. Always write the response body in binary mode (for example, "wb" mode in Python and Ruby, Buffer in Node.js, FileOutputStream in Java). Writing binary content as text will produce a corrupt file.
Credits are charged on successful responses:
A request using response_type=pdf is charged when the API returns a 200 status code, regardless of whether the PDF contains the content you expected. Because js_render=true is required, the JS rendering credit cost also applies. Test on a small set of URLs before running at scale.

Troubleshooting

The page likely loads content after the initial render. Add wait (in milliseconds) to give the page time to finish loading, or use wait_for with a CSS selector that is only present once the main content is visible. Also confirm that js_render=true is included in the request.
You are likely writing the response as text instead of binary. Always use binary write mode in your language of choice ("wb" in Python and Ruby, Buffer in Node.js, FileOutputStream in Java) and write the raw response body. PDF is a binary format and writing it as text will corrupt the file.
These two parameters are mutually exclusive. response_type=pdf returns a rendered PDF of the full page, while outputs performs targeted data extraction from the HTML. You can only use one per request.
This usually happens when external resources (stylesheets, images, fonts) fail to load during the render. Make sure the target URL is publicly accessible and that js_render=true is included. If the page uses resources that require authentication, those assets may not render correctly.

Pricing

The response_type=pdf parameter is included at no additional cost beyond the standard JS rendering rate. Because PDF generation requires js_render=true, all PDF requests are billed at the JS rendering credit rate. You only pay extra for Premium Proxy when used.
You can monitor your ZenRows usage in multiple ways to stay informed about your account activity and prevent unexpected overages.Dashboard monitoring: View real-time usage statistics, remaining requests, success rates, and request history on your Analytics Page. You can also set up usage alerts in your notification settings to receive notifications when you approach your limits.Programmatic monitoring: For automated monitoring in your applications, call the /v1/subscriptions/self/details endpoint with your API key in the X-API-Key header. This returns real-time usage data that you can integrate into your monitoring systems. Learn more about the usage endpoint.Response header monitoring: Track your concurrency usage through response headers included with each request:
  • Concurrency-Limit: Your maximum concurrent requests
  • Concurrency-Remaining: Available concurrent request slots
  • X-Request-Cost: Cost of the current request

FAQ (Frequently Asked Questions)

Yes. PDF generation requires a full browser render. You must include js_render=true in every request that uses response_type=pdf. Requests without it will not return a valid PDF.
PDF requests are billed at the JS rendering credit rate because js_render=true is required. The response_type=pdf parameter itself does not add an extra cost beyond that.
No, response_type=pdf is a parameter of the Universal Scraper API. It is not available in Scraping Browser (CDP/Playwright) sessions. In a Scraping Browser session, you can generate PDFs using Playwright’s built-in page.pdf() method directly in your script.
Not currently. The PDF is generated using the browser’s default page settings. If you need specific page dimensions or orientation, consider post-processing the PDF with a library like pypdf or reportlab after saving it.
The PDF captures a single page render. For paginated content, you would need to make a separate request for each URL or page state you want to capture, then combine the resulting PDFs if needed.