Create a PDF
curl --request POST \
--url https://api.pdfbase.dev/v1/pdfs \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"html": "<string>",
"url": "<string>",
"output": "<string>",
"format": "<string>",
"custom_size": {},
"margin": {},
"landscape": true,
"scale": 123,
"header": {},
"footer": {},
"wait_until": "<string>",
"wait_for_selector": "<string>",
"wait_for_timeout": 123,
"javascript": "<string>",
"resource_timeout": 123,
"skip_failed_resources": true,
"compress": "<string>",
"watermark": {},
"debug": true,
"timeout": 123,
"metadata": {}
}
'import requests
url = "https://api.pdfbase.dev/v1/pdfs"
payload = {
"html": "<string>",
"url": "<string>",
"output": "<string>",
"format": "<string>",
"custom_size": {},
"margin": {},
"landscape": True,
"scale": 123,
"header": {},
"footer": {},
"wait_until": "<string>",
"wait_for_selector": "<string>",
"wait_for_timeout": 123,
"javascript": "<string>",
"resource_timeout": 123,
"skip_failed_resources": True,
"compress": "<string>",
"watermark": {},
"debug": True,
"timeout": 123,
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
html: '<string>',
url: '<string>',
output: '<string>',
format: '<string>',
custom_size: {},
margin: {},
landscape: true,
scale: 123,
header: {},
footer: {},
wait_until: '<string>',
wait_for_selector: '<string>',
wait_for_timeout: 123,
javascript: '<string>',
resource_timeout: 123,
skip_failed_resources: true,
compress: '<string>',
watermark: {},
debug: true,
timeout: 123,
metadata: {}
})
};
fetch('https://api.pdfbase.dev/v1/pdfs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pdfbase.dev/v1/pdfs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'html' => '<string>',
'url' => '<string>',
'output' => '<string>',
'format' => '<string>',
'custom_size' => [
],
'margin' => [
],
'landscape' => true,
'scale' => 123,
'header' => [
],
'footer' => [
],
'wait_until' => '<string>',
'wait_for_selector' => '<string>',
'wait_for_timeout' => 123,
'javascript' => '<string>',
'resource_timeout' => 123,
'skip_failed_resources' => true,
'compress' => '<string>',
'watermark' => [
],
'debug' => true,
'timeout' => 123,
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.pdfbase.dev/v1/pdfs"
payload := strings.NewReader("{\n \"html\": \"<string>\",\n \"url\": \"<string>\",\n \"output\": \"<string>\",\n \"format\": \"<string>\",\n \"custom_size\": {},\n \"margin\": {},\n \"landscape\": true,\n \"scale\": 123,\n \"header\": {},\n \"footer\": {},\n \"wait_until\": \"<string>\",\n \"wait_for_selector\": \"<string>\",\n \"wait_for_timeout\": 123,\n \"javascript\": \"<string>\",\n \"resource_timeout\": 123,\n \"skip_failed_resources\": true,\n \"compress\": \"<string>\",\n \"watermark\": {},\n \"debug\": true,\n \"timeout\": 123,\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.pdfbase.dev/v1/pdfs")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"html\": \"<string>\",\n \"url\": \"<string>\",\n \"output\": \"<string>\",\n \"format\": \"<string>\",\n \"custom_size\": {},\n \"margin\": {},\n \"landscape\": true,\n \"scale\": 123,\n \"header\": {},\n \"footer\": {},\n \"wait_until\": \"<string>\",\n \"wait_for_selector\": \"<string>\",\n \"wait_for_timeout\": 123,\n \"javascript\": \"<string>\",\n \"resource_timeout\": 123,\n \"skip_failed_resources\": true,\n \"compress\": \"<string>\",\n \"watermark\": {},\n \"debug\": true,\n \"timeout\": 123,\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pdfbase.dev/v1/pdfs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"html\": \"<string>\",\n \"url\": \"<string>\",\n \"output\": \"<string>\",\n \"format\": \"<string>\",\n \"custom_size\": {},\n \"margin\": {},\n \"landscape\": true,\n \"scale\": 123,\n \"header\": {},\n \"footer\": {},\n \"wait_until\": \"<string>\",\n \"wait_for_selector\": \"<string>\",\n \"wait_for_timeout\": 123,\n \"javascript\": \"<string>\",\n \"resource_timeout\": 123,\n \"skip_failed_resources\": true,\n \"compress\": \"<string>\",\n \"watermark\": {},\n \"debug\": true,\n \"timeout\": 123,\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"object": "<string>",
"status": "<string>",
"url": "<string>",
"base64": "<string>",
"pages": 123,
"bytes": 123,
"render_time_ms": 123,
"warnings": [
{}
],
"debug": {}
}PDFs
Create a PDF
Generate a PDF from HTML content, a URL, or raw markup.
POST
/
v1
/
pdfs
Create a PDF
curl --request POST \
--url https://api.pdfbase.dev/v1/pdfs \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"html": "<string>",
"url": "<string>",
"output": "<string>",
"format": "<string>",
"custom_size": {},
"margin": {},
"landscape": true,
"scale": 123,
"header": {},
"footer": {},
"wait_until": "<string>",
"wait_for_selector": "<string>",
"wait_for_timeout": 123,
"javascript": "<string>",
"resource_timeout": 123,
"skip_failed_resources": true,
"compress": "<string>",
"watermark": {},
"debug": true,
"timeout": 123,
"metadata": {}
}
'import requests
url = "https://api.pdfbase.dev/v1/pdfs"
payload = {
"html": "<string>",
"url": "<string>",
"output": "<string>",
"format": "<string>",
"custom_size": {},
"margin": {},
"landscape": True,
"scale": 123,
"header": {},
"footer": {},
"wait_until": "<string>",
"wait_for_selector": "<string>",
"wait_for_timeout": 123,
"javascript": "<string>",
"resource_timeout": 123,
"skip_failed_resources": True,
"compress": "<string>",
"watermark": {},
"debug": True,
"timeout": 123,
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
html: '<string>',
url: '<string>',
output: '<string>',
format: '<string>',
custom_size: {},
margin: {},
landscape: true,
scale: 123,
header: {},
footer: {},
wait_until: '<string>',
wait_for_selector: '<string>',
wait_for_timeout: 123,
javascript: '<string>',
resource_timeout: 123,
skip_failed_resources: true,
compress: '<string>',
watermark: {},
debug: true,
timeout: 123,
metadata: {}
})
};
fetch('https://api.pdfbase.dev/v1/pdfs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pdfbase.dev/v1/pdfs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'html' => '<string>',
'url' => '<string>',
'output' => '<string>',
'format' => '<string>',
'custom_size' => [
],
'margin' => [
],
'landscape' => true,
'scale' => 123,
'header' => [
],
'footer' => [
],
'wait_until' => '<string>',
'wait_for_selector' => '<string>',
'wait_for_timeout' => 123,
'javascript' => '<string>',
'resource_timeout' => 123,
'skip_failed_resources' => true,
'compress' => '<string>',
'watermark' => [
],
'debug' => true,
'timeout' => 123,
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.pdfbase.dev/v1/pdfs"
payload := strings.NewReader("{\n \"html\": \"<string>\",\n \"url\": \"<string>\",\n \"output\": \"<string>\",\n \"format\": \"<string>\",\n \"custom_size\": {},\n \"margin\": {},\n \"landscape\": true,\n \"scale\": 123,\n \"header\": {},\n \"footer\": {},\n \"wait_until\": \"<string>\",\n \"wait_for_selector\": \"<string>\",\n \"wait_for_timeout\": 123,\n \"javascript\": \"<string>\",\n \"resource_timeout\": 123,\n \"skip_failed_resources\": true,\n \"compress\": \"<string>\",\n \"watermark\": {},\n \"debug\": true,\n \"timeout\": 123,\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.pdfbase.dev/v1/pdfs")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"html\": \"<string>\",\n \"url\": \"<string>\",\n \"output\": \"<string>\",\n \"format\": \"<string>\",\n \"custom_size\": {},\n \"margin\": {},\n \"landscape\": true,\n \"scale\": 123,\n \"header\": {},\n \"footer\": {},\n \"wait_until\": \"<string>\",\n \"wait_for_selector\": \"<string>\",\n \"wait_for_timeout\": 123,\n \"javascript\": \"<string>\",\n \"resource_timeout\": 123,\n \"skip_failed_resources\": true,\n \"compress\": \"<string>\",\n \"watermark\": {},\n \"debug\": true,\n \"timeout\": 123,\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pdfbase.dev/v1/pdfs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"html\": \"<string>\",\n \"url\": \"<string>\",\n \"output\": \"<string>\",\n \"format\": \"<string>\",\n \"custom_size\": {},\n \"margin\": {},\n \"landscape\": true,\n \"scale\": 123,\n \"header\": {},\n \"footer\": {},\n \"wait_until\": \"<string>\",\n \"wait_for_selector\": \"<string>\",\n \"wait_for_timeout\": 123,\n \"javascript\": \"<string>\",\n \"resource_timeout\": 123,\n \"skip_failed_resources\": true,\n \"compress\": \"<string>\",\n \"watermark\": {},\n \"debug\": true,\n \"timeout\": 123,\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"object": "<string>",
"status": "<string>",
"url": "<string>",
"base64": "<string>",
"pages": 123,
"bytes": 123,
"render_time_ms": 123,
"warnings": [
{}
],
"debug": {}
}Phase
Phase 1 (Launch) — Core endpoint. Ships day one.Request
string
HTML content to render as a PDF. Supports full CSS, JavaScript, web fonts, SVG, Canvas — anything Chromium renders. Mutually exclusive with
url.string
URL of a page to render as PDF. PDFBase loads the page in a headless Chromium browser and captures it. Mutually exclusive with
html.string
default:"url"
How to return the generated PDF.
url— Returns a signed download URL (recommended). File is stored for your plan’s retention period.base64— Returns the raw PDF as a base64-encoded string in the response body. Holds the rendering slot until transfer completes.
string
default:"a4"
Page size. One of:
a4, a3, a5, letter, legal, tabloid, or a custom object.object
Custom page dimensions. Overrides
format.width(string) — e.g.,"210mm","8.5in","800px"height(string) — e.g.,"297mm","11in","1200px"
string | object
default:"20mm"
Page margins. Pass a string for uniform margins (
"20mm") or an object for per-side control:top(string)right(string)bottom(string)left(string)
boolean
default:"false"
Render in landscape orientation.
number
default:"1"
Scale of the webpage rendering. Range:
0.1 to 2.0.object
Page header. Rendered on every page.
html(string) — HTML content for the header. Supports Chromium’s special classes:date,title,url,pageNumber,totalPages.height(string) — Header height, e.g.,"40mm".
object
Page footer. Same structure as
header.string
default:"networkidle"
When to consider the page “loaded” before capturing.
load— Wait for theloadevent.domcontentloaded— Wait forDOMContentLoaded.networkidle— Wait until no network requests for 500ms (recommended).
string
CSS selector to wait for before capturing. Useful when content loads dynamically.
integer
Additional milliseconds to wait after
wait_until fires. Max: 10000.string
JavaScript to execute on the page before capturing. Runs after
wait_until resolves.integer
default:"10000"
Max milliseconds to wait for each external resource (fonts, images, stylesheets). Resources that exceed this are skipped.
boolean
default:"true"
Continue rendering even if some resources fail to load. When
false, any failed resource causes the request to return an error.string
default:"none"
Compression level for the output PDF. One of:
none, low, medium, high. Higher compression = smaller file, slightly slower.object
Stamp a text watermark on the generated PDF. For watermarking existing PDFs, see Add watermark (Phase 2).
text(string, required) — The watermark text, e.g., “DRAFT”, “CONFIDENTIAL”.color(string, default: “#00000020”) — Color with alpha, hex format.rotation(number, default: -45) — Rotation in degrees.position(string, default: “center”) — One of:center,top-left,top-right,bottom-left,bottom-right.
boolean
default:"false"
Include a screenshot, console output, and failed resource list in the response. See Debug Mode.
integer
default:"30000"
Max milliseconds for the entire rendering operation. Range:
5000 to 120000.object
Arbitrary key-value pairs stored with the PDF. Useful for linking PDFs to your internal records.
{ "order_id": "42", "customer": "acme-corp" }
Response
{
"id": "pdf_x7Kf9m",
"object": "pdf",
"status": "completed",
"url": "https://files.pdfbase.dev/pdf_x7Kf9m.pdf?token=sig_abc123",
"pages": 3,
"bytes": 142000,
"format": "a4",
"landscape": false,
"compress": "none",
"watermark": null,
"metadata": {
"order_id": "42",
"customer": "acme-corp"
},
"created_at": "2026-05-19T10:30:00Z",
"expires_at": "2026-05-20T10:30:00Z",
"render_time_ms": 1240
}
string
Unique identifier, prefixed with
pdf_.string
Always
"pdf".string
One of:
completed, completed_with_warnings, failed.string
Signed download URL. Expires at
expires_at. Only present when output: "url".string
Base64-encoded PDF content. Only present when
output: "base64".integer
Number of pages in the generated PDF.
integer
File size in bytes.
integer
Time spent rendering, in milliseconds. Does not include queue wait time.
array
Present when
status is completed_with_warnings. Each warning has code, message, and optionally resource.object
Present when
debug: true. Contains screenshot_url, console array, and failed_resources array.Examples
Minimal
curl -X POST https://api.pdfbase.dev/v1/pdfs \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Hello</h1>"}'
Full options
curl -X POST https://api.pdfbase.dev/v1/pdfs \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-42-invoice" \
-d '{
"html": "<!DOCTYPE html><html>...</html>",
"format": "a4",
"margin": { "top": "25mm", "bottom": "25mm", "left": "15mm", "right": "15mm" },
"header": {
"html": "<div style=\"font-size:10px;text-align:right;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>",
"height": "20mm"
},
"footer": {
"html": "<div style=\"font-size:9px;text-align:center;color:#888;\">Generated by Acme Corp</div>",
"height": "15mm"
},
"wait_until": "networkidle",
"compress": "medium",
"debug": true,
"metadata": { "order_id": "42" },
"output": "url"
}'
From URL
curl -X POST https://api.pdfbase.dev/v1/pdfs \
-H "Authorization: Bearer pk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/reports/monthly?token=abc",
"wait_for_selector": "#report-ready",
"format": "letter",
"output": "url"
}'