URL to PDF
Capture any webpage as a PDF document.
URL to PDF
Capture any publicly accessible webpage as a PDF document. Supports dynamic content, custom viewports, and authentication.
POST
/v1/pdf/url
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | URL to capture (must be publicly accessible) |
options | object | No | PDF generation options |
Options Object
| Parameter | Type | Default | Description |
|---|---|---|---|
format | string | "A4" | Paper format |
landscape | boolean | false | Landscape orientation |
margin | object | - | Page margins |
print_background | boolean | true | Include backgrounds |
wait_for | number | 0 | Wait time in ms for dynamic content |
viewport | object | - | Browser viewport size |
full_page | boolean | false | Capture full scrollable page |
cookies | array | - | Cookies for authentication |
Viewport Object
| Parameter | Type | Default | Description |
|---|---|---|---|
width | number | 1920 | Viewport width in pixels |
height | number | 1080 | Viewport height in pixels |
Code Examples
curl -X POST https://api.pdfapi.dev/v1/pdf/url \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/report",
"options": {
"format": "A4",
"wait_for": 2000,
"viewport": {
"width": 1920,
"height": 1080
}
}
}' \
--output report.pdf
const response = await fetch('https://api.pdfapi.dev/v1/pdf/url', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PDFAPI_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://example.com/report',
options: {
format: 'A4',
wait_for: 2000,
full_page: true,
viewport: { width: 1920, height: 1080 }
}
}),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error.message);
}
const buffer = await response.arrayBuffer();
// Save or process the PDF
import requests
import os
response = requests.post(
'https://api.pdfapi.dev/v1/pdf/url',
headers={
'Authorization': f'Bearer {os.environ["PDFAPI_KEY"]}',
'Content-Type': 'application/json',
},
json={
'url': 'https://example.com/report',
'options': {
'format': 'A4',
'wait_for': 2000,
'full_page': True,
'viewport': {'width': 1920, 'height': 1080}
}
}
)
if response.status_code == 200:
with open('report.pdf', 'wb') as f:
f.write(response.content)
else:
print(f"Error: {response.json()['error']['message']}")
package main
import (
"bytes"
"encoding/json"
"io"
"net/http"
"os"
)
func main() {
payload := map[string]interface{}{
"url": "https://example.com/report",
"options": map[string]interface{}{
"format": "A4",
"wait_for": 2000,
"full_page": true,
"viewport": map[string]int{
"width": 1920, "height": 1080,
},
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.pdfapi.dev/v1/pdf/url", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("PDFAPI_KEY"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
pdf, _ := io.ReadAll(resp.Body)
os.WriteFile("report.pdf", pdf, 0644)
}
Wait for Dynamic Content
For pages with JavaScript-rendered content, use wait_for to ensure content loads:
{
"url": "https://example.com/dashboard",
"options": {
"wait_for": 3000
}
}
The wait_for value is in milliseconds. Maximum: 30,000ms (30 seconds).
Authentication with Cookies
For pages requiring authentication, pass session cookies:
{
"url": "https://example.com/private/report",
"options": {
"cookies": [
{
"name": "session_id",
"value": "abc123xyz",
"domain": "example.com",
"path": "/",
"secure": true,
"httpOnly": true
}
]
}
}
Cookie Object
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Cookie name |
value | string | Yes | Cookie value |
domain | string | Yes | Cookie domain |
path | string | No | Cookie path (default: /) |
secure | boolean | No | HTTPS only |
httpOnly | boolean | No | HTTP only flag |
Full Page Capture
Capture the entire scrollable page:
{
"url": "https://example.com/long-page",
"options": {
"full_page": true
}
}
Full page capture may result in multi-page PDFs for long pages.
Custom Viewport
Set a specific viewport size for responsive pages:
{
"url": "https://example.com/responsive",
"options": {
"viewport": {
"width": 1440,
"height": 900
}
}
}
Common viewport sizes:
- Desktop:
1920×1080,1440×900 - Tablet:
1024×768,768×1024 - Mobile:
390×844,375×667
Limitations
- Only publicly accessible URLs (or URLs accessible with provided cookies)
- Maximum page load timeout: 30 seconds
- JavaScript execution is supported
- CAPTCHA-protected pages are not supported
- Some SPAs may require longer
wait_forvalues
Response
Success (200)
Content-Type: application/pdf
Content-Disposition: attachment; filename="document.pdf"
Error Responses
Invalid URL (400)
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Valid URL is required"
}
}
Page Load Failed (500)
{
"error": {
"code": "PDF_GENERATION_ERROR",
"message": "Failed to load URL",
"details": {
"reason": "Page load timeout after 30000ms"
}
}
}
URL Not Accessible (500)
{
"error": {
"code": "PDF_GENERATION_ERROR",
"message": "URL is not accessible",
"details": {
"status_code": 403
}
}
}