Authentication
Every request must be authenticated using your API key via HTTP Basic Auth.
Use your API key as the username and leave the password empty.
bashcurl -X POST https://api.webtopdfapi.com/convert/pdf \ -u "your_api_key:" \ -H "Content-Type: application/json" \ -d '{"source": "https://example.com"}'
You can also use the Authorization header directly:
Authorization: Basic base64(your_api_key:)POST /convert/pdf
Convert a URL or raw HTML to a PDF document.
Endpoint: POST /convert/pdf
Request body (JSON):
| Parameter | Type | Default | Description |
|---|---|---|---|
source | string | *required* | URL or raw HTML to convert |
landscape | boolean | false | Landscape orientation |
format | string | "A4" | Paper format: A0-A5, Letter, Legal, Tabloid, Ledger |
margin | string/object | "10mm" | Margins. String (`"10mm"`) or object (`{top, right, bottom, left}`) |
css | string | — | Custom CSS to inject before rendering |
javascript | string | — | Custom JS to execute before capture |
delay | number | 0 | Wait time in ms before generating (max 30000) |
use_print | boolean | true | Emulate `@media print` styles |
disable_backgrounds | boolean | false | Remove background images and colors |
zoom | number | 1 | Zoom level (0.1 - 2) |
filename | string | — | Sets `Content-Disposition` filename |
sandbox | boolean | false | Sandbox mode (adds watermark, doesn't consume credits) |
tagged | boolean | true | Generate accessible tagged PDF |
outline | boolean | true | Generate bookmarks from headings |
page_ranges | string | — | Page ranges, e.g. `"1-3, 5"` |
viewport_width | number | 1280 | Browser viewport width in px |
viewport_height | number | 1024 | Browser viewport height in px |
timeout | number | 30000 | Navigation timeout in ms |
wait_for | string | "networkidle0" | Wait strategy: `load`, `domcontentloaded`, `networkidle0`, `networkidle2` |
wait_for_selector | string | — | Wait for a CSS selector to appear |
Headers & Footers:
| Parameter | Type | Description |
|---|---|---|
header.source | string | HTML template for header |
header.height | string | Header height (e.g. `"50px"`) |
footer.source | string | HTML template for footer |
footer.height | string | Footer height (e.g. `"50px"`) |
Header/footer templates support these variables:
- <span class="pageNumber"></span> — Current page number
- <span class="totalPages"></span> — Total pages
Authentication for source URL:
| Parameter | Type | Description |
|---|---|---|
auth.username | string | HTTP Basic auth username |
auth.password | string | HTTP Basic auth password |
cookies | array | Cookies to set: `[{name, value, domain?, path?}]` |
Orientation (Portrait / Landscape)
By default, PDFs are generated in portrait orientation. Set landscape: true for landscape.
Portrait (default):
``json
{
"source": "https://example.com",
"format": "A4",
"landscape": false
}
Landscape:
``json
{
"source": "https://example.com",
"format": "A4",
"landscape": true
}
Sandbox Mode
Use sandbox mode to test your integration without consuming credits. PDFs generated in sandbox mode have a watermark.
json{ "source": "https://example.com", "sandbox": true }
Sandbox mode is perfect for:
- Testing your integration during development
- Validating PDF output before going live
- Debugging layout issues
Note: Sandbox PDFs include a watermark and should not be used in production.
Custom CSS & JavaScript
Inject custom CSS or JavaScript to modify the page before generating the PDF.
Inject CSS (e.g., hide elements, adjust styles):
``json
{
"source": "https://example.com",
"css": ".no-print, .cookie-banner { display: none !important; } body { font-size: 14px; }"
}
Inject JavaScript (e.g., trigger rendering, expand sections):
``json
{
"source": "https://example.com",
"javascript": "document.querySelectorAll('details').forEach(d => d.open = true)"
}
JavaScript runs before the PDF is generated, after the page has loaded.
Waiting for Content
For pages with dynamic content (SPAs, lazy-loaded images, animations), you can configure how long to wait.
Wait for network idle:
``json
{
"source": "https://my-spa.com",
"wait_for": "networkidle0"
}
Wait for a specific element:
``json
{
"source": "https://my-spa.com",
"wait_for_selector": "#content-loaded"
}
Wait a fixed delay (ms):
``json
{
"source": "https://my-spa.com",
"delay": 3000
}
You can combine these options. The order is: page load → wait_for strategy → wait_for_selector → delay → generate PDF.
Credits & Pricing
Credits are consumed based on the size of the generated PDF:
| PDF Size | Credits |
|---|---|
| Up to 5 MB | 1 credit |
| 5 - 10 MB | 2 credits |
| 10 - 15 MB | 3 credits |
| ... | +1 per 5 MB |
Free tier: 50 credits/month (max 500 KB per PDF), renewed automatically. No credit card required.
Sandbox mode: Does not consume credits (adds watermark).
Checking your balance:
Your remaining credits are returned in the response headers:
X-Credits-Remaining: 47
X-Credits-Used: 1Response
Success (200):
Returns the PDF as a binary stream with these headers:
Content-Type: application/pdf
Content-Disposition: inline; filename="output.pdf"
X-Credits-Remaining: 47
X-Credits-Used: 1Errors:
| Status | Description |
|---|---|
| 400 | Missing or invalid `source` parameter |
| 401 | Invalid or missing API key |
| 402 | Insufficient credits |
| 500 | Conversion failed (check error message) |
Error response body:
``json
{
"error": "Bad Request",
"message": "The 'source' parameter is required."
}
Full Examples
cURL:
``bash
curl -X POST https://api.webtopdfapi.com/convert/pdf \
-u "sk_live_abc123...xyz:" \
-H "Content-Type: application/json" \
-d '{
"source": "https://example.com",
"format": "A4",
"landscape": true,
"use_print": true,
"css": ".no-print { display: none; }",
"delay": 2000
}' \
-o report.pdf
Node.js:
``javascript
const response = await fetch("https://api.webtopdfapi.com/convert/pdf", {
method: "POST",
headers: {
Authorization: Basic ${Buffer.from("sk_live_abc123...xyz:").toString("base64")}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
source: "https://example.com",
format: "A4",
landscape: true,
}),
});
const pdf = Buffer.from(await response.arrayBuffer());
fs.writeFileSync("report.pdf", pdf);
console.log("Credits remaining:", response.headers.get("x-credits-remaining"));
```
Python:
```python
import requests
response = requests.post(
"https://api.webtopdfapi.com/convert/pdf",
auth=("sk_live_abc123...xyz", ""),
json={
"source": "https://example.com",
"format": "A4",
"landscape": True,
"css": ".cookie-banner { display: none; }",
},
)
response.raise_for_status()
with open("report.pdf", "wb") as f:
f.write(response.content)
print(f"Credits remaining: {response.headers['x-credits-remaining']}")
```
n8n (HTTP Request node):
- Method: POST
- URL: https://api.webtopdfapi.com/convert/pdf
- Authentication: Basic Auth (username = your API key, password = empty)
- Body: JSON with source, format, etc.
- Response: Binary data → save or send as attachment