Generating PDFs
Currently, Browserless V2 is available in production via two domains: production-sfo.browserless.io
and production-lon.browserless.io
The /pdf
API allows for simple navigation to a site and capturing a PDF. Browserless will respond with a Content-Type
of application/pdf
and a Buffer of the PDF file. Similar to screenshots, this REST API also exposes puppeteer's pdf
options via an options
property in the JSON body for granular control.
You can check the full Open API schema here for all options and properties.
This route requires either a url
or html
property in the JSON body. When html
is present Browserless will render the HTML for you and capture the PDF.
On this collection we’ll look at:
- Basic Usage
- Setting HTML content
- Adding custom styles and scripts
- Rejecting Undesired Requests
- Navigation Options
- Continue on Error
- Waiting for Things
Basic Usage
Rest API (Without Stealth)
Browserless recommends using our REST API to generate PDFs, unless you need to get past bot detectors.
- JSON payload
- cURL
- Javascript
- Python
- Java
- C#
// JSON body
// `options` are the options available via puppeteer's Page.pdf() method
// (see our Open API documentation)
{
"url": "https://example.com/",
"options": {
"displayHeaderFooter": true,
"printBackground": false,
"format": "A0"
// Queue the lack of a `path` parameter
}
}
curl -X POST \
https://production-sfo.browserless.io/pdf?token=YOUR_API_TOKEN_HERE \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/",
"options": {
"displayHeaderFooter": true,
"printBackground": false,
"format": "A0"
}
}'
import fs from 'fs/promises';
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/pdf?token=${TOKEN}`;
const headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
};
const data = {
url: "https://example.com/",
options: {
displayHeaderFooter: true,
printBackground: false,
format: "A0"
}
};
const generatePDF = async () => {
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(data)
});
const pdfBuffer = await response.arrayBuffer();
await fs.writeFile("output.pdf", Buffer.from(pdfBuffer));
console.log("PDF saved as output.pdf");
};
generatePDF();
import requests
TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/pdf?token={TOKEN}"
headers = {
"Cache-Control": "no-cache",
"Content-Type": "application/json"
}
data = {
"url": "https://example.com/",
"options": {
"displayHeaderFooter": True,
"printBackground": False,
"format": "A0"
}
}
response = requests.post(url, headers=headers, json=data)
with open("output.pdf", "wb") as file:
file.write(response.content)
print("PDF saved as output.pdf")
import java.io.*;
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
public class GeneratePDF {
public static void main(String[] args) {
String TOKEN = "YOUR_API_TOKEN_HERE";
String url = "https://production-sfo.browserless.io/pdf?token=" + TOKEN;
String jsonData = """
{
"url": "https://example.com/",
"options": {
"displayHeaderFooter": true,
"printBackground": false,
"format": "A0"
}
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Cache-Control", "no-cache")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
try {
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
Files.copy(response.body(), Paths.get("output.pdf"), StandardCopyOption.REPLACE_EXISTING);
System.out.println("PDF saved as output.pdf");
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
string TOKEN = "YOUR_API_TOKEN_HERE";
string url = $"https://production-sfo.browserless.io/pdf?token={TOKEN}";
string jsonData = @"
{
""url"": ""https://example.com/"",
""options"": {
""displayHeaderFooter"": true,
""printBackground"": false,
""format"": ""A0""
}
}";
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(jsonData, Encoding.UTF8, "application/json")
};
request.Headers.Add("Cache-Control", "no-cache");
try
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("output.pdf", pdfBytes);
Console.WriteLine("PDF saved as output.pdf");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
We do not allow setting a options.path
BQL (Stealth)
If the /pdf API
is getting blocked by bot detectors, then we would recommend trying BrowserQL.
- BQL Query
- cURL
- Javascript
- Python
- Java
- C#
mutation PDF {
goto(url: "https://example.com") {
status
}
pdf(displayHeaderFooter: true, printBackground: false, format: a0) {
base64
}
}
curl --request POST \
--url 'https://production-sfo.browserless.io/chromium/bql?token=YOUR_API_TOKEN_HERE' \
--header 'Content-Type: application/json' \
--data '{"query":"mutation PDF {\n goto(url: \"https://example.com\") {\n status\n }\n\n pdf(displayHeaderFooter: true, printBackground: false, format: a0) {\n base64\n }\n}","variables":"","operationName":"PDF"}'
const endpoint = "https://production-sfo.browserless.io/chromium/bql";
const token = "YOUR_API_TOKEN_HERE";
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({"query":"mutation PDF {\n goto(url: \"https://example.com\") {\n status\n }\n\n pdf(displayHeaderFooter: true, printBackground: false, format: a0) {\n base64\n }\n}","variables":"","operationName":"PDF"})
};
const url = `${endpoint}?token=${token}`;
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
import requests
endpoint = "https://production-sfo.browserless.io/chromium/bql"
query_string = {
"token": "YOUR_API_TOKEN_HERE",
}
headers = {
"Content-Type": "application/json",
}
payload = {
"query": "mutation PDF {\n goto(url: \"https://example.com\") {\n status\n }\n\n pdf(displayHeaderFooter: true, printBackground: false, format: a0) {\n base64\n }\n}",
"variables": None,
"operationName": "PDF",
}
response = requests.post(endpoint, params=query_string, headers=headers, json=payload)
print(response.json())
String url = "https://production-sfo.browserless.io/chromium/bql";
String token = "YOUR_API_TOKEN_HERE";
String endpoint = String.format("%s?token=%s%s%s", url, token);
HttpResponse<String> response = Unirest.post(endpoint)
.header("Content-Type", "application/json")
.body({"query":"mutation PDF {\n goto(url: \"https://example.com\") {\n status\n }\n\n pdf(displayHeaderFooter: true, printBackground: false, format: a0) {\n base64\n }\n}","variables":"","operationName":"PDF"})
.asString();
string url = "https://production-sfo.browserless.io/chromium/bql";
string token = "YOUR_API_TOKEN_HERE";
string endpoint = $"{url}?token={token}";
var payload = new
{
query = @"mutation PDF {
goto(url: ""https://example.com"") {
status
}
pdf(displayHeaderFooter: true, printBackground: false, format: a0) {
base64
}
}",
variables = "",
operationName = "PDF"
};
using (var client = new HttpClient())
{
var jsonPayload = System.Text.Json.JsonSerializer.Serialize(payload);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(endpoint, content);
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
For more details on BQL mutations, refer to the BrowserQL Schema reference pages.