API Reference

The PDFRender API lets you generate PDFs and screenshots from HTML or URLs with a single HTTP request. All endpoints are served over HTTPS at:

https://api.pdfrender.co

Requests and responses use JSON, except for the /v1/pdf endpoint which returns binary PDF data in synchronous mode.

All API requests require authentication via Bearer token. Rate limits and available features depend on your plan.

Authentication

Every request must include your API key in the Authorization header:

header
Authorization: Bearer pk_live_xxxxxxxxxxxxxxxx

API keys come in two flavours:

pk_live_

Production key

Full access, no watermarks. Use in your production app.

pk_test_

Test key

PDFs include a watermark. Use for development and testing.

You receive both keys when you register. Keys are shown only once — store them securely. You can generate additional keys by logging in.

Generate PDF

POST/v1/pdf

Render HTML or a URL to a pixel-perfect PDF. Returns binary PDF data by default, or accepts an async webhook.

Request Body

ParameterTypeDescription
sourcestringHTML string to render. Provide this or url.
urlstringURL to navigate to and render. Provide this or source.
optionsobjectRendering options (see below).

Options Object

ParameterTypeDescription
formatstringPage format: A4, Letter, Legal, Tabloid. Default: A4.
widthstringCustom width (e.g. "210mm"). Overrides format.
heightstringCustom height (e.g. "297mm"). Overrides format.
orientationstringportrait or landscape. Default: portrait.
marginobject{ top, right, bottom, left } in CSS units. Default: 20mm/15mm.
printBackgroundbooleanInclude CSS backgrounds. Default: true.
scalenumberScale factor 0.1–2.0. Default: 1.
preferCSSPageSizebooleanUse @page CSS from HTML. Default: false.
waitForstringload | domcontentloaded | networkidle | selector.
waitForSelectorstringCSS selector to wait for before rendering.
waitForTimeoutnumberMax wait time in ms. Capped by your plan limit.
javascriptbooleanExecute JS. Set false for faster static rendering.
displayHeaderFooterbooleanShow header/footer. Default: false.
headerTemplatestringHTML template for page header.
footerTemplatestringHTML template for page footer. Supports <span class='pageNumber'> and <span class='totalPages'>.
pageRangesstringPage range to render, e.g. "1-5" or "1,3,5".
cssstringExtra CSS to inject before rendering.
jsstringExtra JS to evaluate before rendering.
compressbooleanAuto-compress PDF with Ghostscript. Growth+ plans.
filenamestringFilename in Content-Disposition header. Default: document.pdf.
webhookstringURL for async delivery. Growth+ plans.
metadataobject{ title, author, subject } PDF metadata.

Example — Synchronous

cURL
curl -X POST https://api.pdfrender.co/v1/pdf \
  -H "Authorization: Bearer pk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "<html><body><h1>Invoice #1042</h1><p>Amount: $250.00</p></body></html>",
    "options": {
      "format": "A4",
      "margin": { "top": "20mm", "bottom": "20mm" },
      "compress": true
    }
  }' \
  -o invoice.pdf

Response: Binary PDF with informational headers:

response headers
Content-Type: application/pdf
Content-Disposition: attachment; filename="invoice.pdf"
X-PDFRender-Pages: 1
X-PDFRender-Size: 48210
X-PDFRender-Time: 847ms
X-RateLimit-Remaining: 97

Example — Async (Webhook)

Pass a webhook URL to receive the result asynchronously. Available on Growth and Business plans.

request
{
  "source": "<html>...</html>",
  "options": {
    "webhook": "https://myapp.com/webhook/pdf-done",
    "compress": true
  }
}
response — 202 Accepted
{
  "id": "job_abc123",
  "status": "processing",
  "webhook": "https://myapp.com/webhook/pdf-done"
}
webhook POST payload
{
  "id": "job_abc123",
  "status": "completed",
  "pages": 3,
  "size": 145232,
  "time": 1204
}

Screenshot

POST/v1/screenshot

Generate PNG or JPEG screenshots from HTML or URLs. Same API key, same speed. Perfect for OG images, thumbnails, and visual testing.

Request Body

ParameterTypeDescription
sourcestringHTML string to render. Provide this or url.
urlstringURL to navigate to and capture. Provide this or source.
optionsobjectScreenshot options (see below).

Options Object

ParameterTypeDescription
viewportobject{ width, height, deviceScaleFactor }. Default: 1280×720 @1x.
typestringImage format: png or jpeg. Default: png.
qualityintegerJPEG quality 0–100. Only applies when type is jpeg.
fullPagebooleanCapture entire scrollable page. Default: false.
omitBackgroundbooleanTransparent background (PNG only). Default: false.
darkModebooleanEmulate dark color scheme. Default: false.
clipobjectClip region: { x, y, width, height }.
waitForstringload | domcontentloaded | networkidle | selector.
waitForSelectorstringCSS selector to wait for before capturing.
waitForTimeoutnumberMax wait time in ms. Capped by your plan limit.
cssstringExtra CSS to inject before capturing.
jsstringExtra JS to evaluate before capturing.
filenamestringFilename in Content-Disposition header. Default: screenshot.png.

Example

cURL
curl -X POST https://api.pdfrender.co/v1/screenshot \
  -H "Authorization: Bearer pk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "options": {
      "type": "png",
      "viewport": { "width": 1280, "height": 720, "deviceScaleFactor": 2 },
      "fullPage": false,
      "darkMode": false
    }
  }' \
  -o screenshot.png

Response: Binary image with informational headers:

response headers
Content-Type: image/png
Content-Disposition: attachment; filename="screenshot.png"
X-PDFRender-Size: 284530
X-PDFRender-Time: 612ms
X-RateLimit-Remaining: 96

Register

POST/v1/auth/register

Create a new account and receive your API keys. No credit card required.

ParameterTypeDescription
emailstringYour email address.
passwordstringPassword (min 8 characters).
cURL
curl -X POST https://api.pdfrender.co/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "dev@company.com", "password": "securepass123"}'
response — 201 Created
{
  "user_id": "usr_a1b2c3d4",
  "email": "dev@company.com",
  "plan": "free",
  "api_key": "pk_live_xxxxxxxxxxxxxxxx",
  "test_api_key": "pk_test_xxxxxxxxxxxxxxxx",
  "message": "Save your API keys — they cannot be shown again."
}

Login

POST/v1/auth/login

Authenticate and generate a new API key. Existing keys remain active.

ParameterTypeDescription
emailstringYour email address.
passwordstringYour password.
response — 200 OK
{
  "user_id": "usr_a1b2c3d4",
  "email": "dev@company.com",
  "plan": "starter",
  "new_api_key": "pk_live_yyyyyyyyyyyyyyyy",
  "keys": [
    { "id": "key_1", "key_prefix": "pk_live_yyyyyyyy...", "name": "Key 2026-02-17" },
    { "id": "key_2", "key_prefix": "pk_live_xxxxxxxx...", "name": "Default" }
  ]
}

Usage

GET/v1/usage

Check your current billing period usage. Requires authentication.

response — 200 OK
{
  "plan": "starter",
  "period": {
    "start": "2026-02-01",
    "end": "2026-03-01"
  },
  "conversions": {
    "used": 342,
    "limit": 2000,
    "remaining": 1658
  },
  "breakdown": [
    {
      "type": "pdf",
      "count": 340,
      "total_size": 48102400,
      "avg_render_time": 723
    },
    {
      "type": "screenshot",
      "count": 2,
      "total_size": 204800,
      "avg_render_time": 450
    }
  ]
}

Billing Checkout

POST/v1/billing/checkout

Create a Stripe Checkout session to subscribe to a paid plan. Returns a redirect URL. Requires authentication.

ParameterTypeDescription
planstringPlan name: starter, growth, or business.
success_urlstringRedirect after successful payment.
cancel_urlstringRedirect if the user cancels.
response — 200 OK
{
  "url": "https://checkout.stripe.com/c/pay/cs_test_...",
  "session_id": "cs_test_abc123",
  "type": "checkout"
}

If the user already has an active subscription, a Stripe Billing Portal URL is returned instead (type: "portal").

Health Check

GET/health

Check service status. No authentication required.

response — 200 OK
{
  "status": "ok",
  "checks": {
    "chromium": "ready",
    "database": "ready",
    "redis": "ready"
  }
}

Rate Limits

Rate limits are enforced per API key based on concurrent requests and monthly conversions. Current limits are returned in response headers.

PlanConversions/moConcurrentTimeoutMax HTML
Free100230s1 MB
Starter2,000560s5 MB
Growth10,00010120s10 MB
Business50,000255 min20 MB

Response headers include X-RateLimit-Remaining with your remaining monthly conversions. Overage on paid plans is billed at $0.005 per extra conversion.

Error Codes

All errors return a consistent JSON structure:

error response
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}
HTTPCodeDescription
400BAD_REQUESTMissing or invalid parameters
400VALIDATION_ERRORRequest body failed schema validation
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENFeature not available on your plan
404NOT_FOUNDEndpoint or resource not found
429RATE_LIMIT_EXCEEDEDToo many concurrent requests
429USAGE_LIMIT_EXCEEDEDMonthly conversion limit reached
500RENDER_ERRORPDF rendering failed
500INTERNAL_ERRORUnexpected server error

SDKs

Official client libraries with TypeScript types and async support.

Node.js

install
npm install @pdfrender/client
usage.js
import PDFRender from '@pdfrender/client';
import fs from 'fs';

const client = new PDFRender('pk_live_xxx');

// Generate PDF from HTML
const pdf = await client.pdf({
  source: '<h1>Invoice #1042</h1><p>Amount: $250</p>',
  options: {
    format: 'A4',
    compress: true,
    margin: { top: '20mm', bottom: '20mm' }
  }
});

fs.writeFileSync('invoice.pdf', pdf);

// Generate PDF from URL
const report = await client.pdf({
  url: 'https://myapp.com/reports/monthly',
  options: { format: 'A4', waitFor: 'networkidle' }
});

fs.writeFileSync('report.pdf', report);

Python

install
pip install pdfrender
usage.py
from pdfrender import PDFRender

client = PDFRender('pk_live_xxx')

# Generate PDF from HTML
pdf = client.pdf(
    source='<h1>Invoice #1042</h1><p>Amount: $250</p>',
    options={
        'format': 'A4',
        'compress': True,
        'margin': {'top': '20mm', 'bottom': '20mm'}
    }
)

with open('invoice.pdf', 'wb') as f:
    f.write(pdf)

# Async support
import asyncio

async def main():
    pdf = await client.async_pdf(
        source='<h1>Hello World</h1>'
    )

asyncio.run(main())

Need help? Contact us at hello@pdfrender.co