PDFs
The pdf
mutation 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.
On this collection we'll look at:
For more details on BQL mutations, refer to the BrowserQL Schema reference pages.
Generating PDFs can also be done with Browserless Rest API. For endpoint details, parameters, and code samples, see the Browserless REST API.
Basic Usage
- 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 reliable PDF generation, it's important to wait for the site and elements to be ready before capturing. Learn more about BrowserQL's built-in wait methods in our Waiting for Things documentation.
Setting HTML Content
You can set the HTML content of the page to render dynamically generated content as well.
- BQL Query
- cURL
- Javascript
- Python
- Java
- C#
mutation PDF {
content(html: "<h1>Hello, World!</h1>") {
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 {\ncontent(html: \"<h1>Hello, World!</h1>\") {\n status\n}\n\npdf(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 {\ncontent(html: \"<h1>Hello, World!</h1>\") {\n status\n}\n\npdf(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 {\ncontent(html: \"<h1>Hello, World!</h1>\") {\n status\n}\n\npdf(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 {\ncontent(html: \"<h1>Hello, World!</h1>\") {\n status\n}\n\npdf(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 {
content(html: ""<h1>Hello, World!</h1>"") {
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);
}
Adding Header and Footer Templates
You can add custom header and footer templates to your PDFs with dynamic content like page numbers. The templates support special CSS classes for injecting values: pageNumber
, totalPages
, title
, url
, and date
.
When using header and footer templates, you may need to specify font sizes explicitly (e.g., font-size: 16pt
) as the default text may appear too small depending on your page format.
- BQL Query
- cURL
- Javascript
- Python
- Java
- C#
mutation addFooterAndHeaderToPDF {
goto(url: "https://www.example.com", waitUntil: networkIdle) {
status
}
invoice: pdf(
format: a4
displayHeaderFooter: true
headerTemplate: "<div style='font-size:12pt; line-height:1.2; width:100%; text-align:center; padding-top:2mm;'><span class='title'></span></div>"
footerTemplate: "<div style='font-size:11pt; line-height:1.2; width:100%; text-align:center; padding-bottom:2mm;'><span class='pageNumber'></span>/<span class='totalPages'></span></div>"
printBackground: true
) {
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 addFooterAndHeaderToPDF {\n goto(url: \"https://www.example.com\", waitUntil: networkIdle) {\n status\n }\n invoice: pdf(\n format: a4\n displayHeaderFooter: true\n headerTemplate: \"<div style='\''font-size:12pt; line-height:1.2; width:100%; text-align:center; padding-top:2mm;'\''><span class='\''title'\''></span></div>\"\n footerTemplate: \"<div style='\''font-size:11pt; line-height:1.2; width:100%; text-align:center; padding-bottom:2mm;'\''><span class='\''pageNumber'\''></span>/<span class='\''totalPages'\''></span></div>\"\n printBackground: true\n ) {\n base64\n }\n}","variables":"","operationName":"addFooterAndHeaderToPDF"}'
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 addFooterAndHeaderToPDF {\n goto(url: \"https://www.example.com\", waitUntil: networkIdle) {\n status\n }\n invoice: pdf(\n format: a4\n displayHeaderFooter: true\n headerTemplate: \"<div style='font-size:12pt; line-height:1.2; width:100%; text-align:center; padding-top:2mm;'><span class='title'></span></div>\"\n footerTemplate: \"<div style='font-size:11pt; line-height:1.2; width:100%; text-align:center; padding-bottom:2mm;'><span class='pageNumber'></span>/<span class='totalPages'></span></div>\"\n printBackground: true\n ) {\n base64\n }\n}","variables":"","operationName":"addFooterAndHeaderToPDF"})
};
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 addFooterAndHeaderToPDF {\n goto(url: \"https://www.example.com\", waitUntil: networkIdle) {\n status\n }\n invoice: pdf(\n format: a4\n displayHeaderFooter: true\n headerTemplate: \"<div style='font-size:12pt; line-height:1.2; width:100%; text-align:center; padding-top:2mm;'><span class='title'></span></div>\"\n footerTemplate: \"<div style='font-size:11pt; line-height:1.2; width:100%; text-align:center; padding-bottom:2mm;'><span class='pageNumber'></span>/<span class='totalPages'></span></div>\"\n printBackground: true\n ) {\n base64\n }\n}",
"variables": None,
"operationName": "addFooterAndHeaderToPDF",
}
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", url, token);
HttpResponse<String> response = Unirest.post(endpoint)
.header("Content-Type", "application/json")
.body("{\"query\":\"mutation addFooterAndHeaderToPDF {\\n goto(url: \\\"https://www.example.com\\\", waitUntil: networkIdle) {\\n status\\n }\\n invoice: pdf(\\n format: a4\\n displayHeaderFooter: true\\n headerTemplate: \\\"<div style='font-size:12pt; line-height:1.2; width:100%; text-align:center; padding-top:2mm;'><span class='title'></span></div>\\\"\\n footerTemplate: \\\"<div style='font-size:11pt; line-height:1.2; width:100%; text-align:center; padding-bottom:2mm;'><span class='pageNumber'></span>/<span class='totalPages'></span></div>\\\"\\n printBackground: true\\n ) {\\n base64\\n }\\n}\",\"variables\":\"\",\"operationName\":\"addFooterAndHeaderToPDF\"}")
.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 addFooterAndHeaderToPDF {
goto(url: ""https://www.example.com"", waitUntil: networkIdle) {
status
}
invoice: pdf(
format: a4
displayHeaderFooter: true
headerTemplate: ""<div style='font-size:12pt; line-height:1.2; width:100%; text-align:center; padding-top:2mm;'><span class='title'></span></div>""
footerTemplate: ""<div style='font-size:11pt; line-height:1.2; width:100%; text-align:center; padding-bottom:2mm;'><span class='pageNumber'></span>/<span class='totalPages'></span></div>""
printBackground: true
) {
base64
}
}",
variables = "",
operationName = "addFooterAndHeaderToPDF"
};
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);
}
Next Steps
Ready to take your PDF generation to the next level? Explore these key areas: