API Reference

POST your HTML, get a pixel-perfect PDF back. Built on Chromium — every CSS property, custom font, and image renders exactly as it does in Chrome.

Base URL: https://api.renderlyapi.com

Quickstart

Get your first PDF in under 60 seconds:

1. Create a free account — your API key is generated instantly.

2. Make a POST request with your HTML:

curl -X POST https://api.renderlyapi.com/v1/pdf/from-html \
  -H "Authorization: Bearer rly_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html":"<h1 style=\"font-family:sans-serif\">Hello!</h1>"}' \
  --output hello.pdf

You'll get a PDF file back immediately. That's it.

Authentication

All API requests must include your API key in the Authorization header:

Authorization: Bearer rly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

You can manage your API keys from the dashboard. Keys start with rly_live_.

Never expose your API key in client-side JavaScript or public repositories. If a key is compromised, revoke it immediately from your dashboard.

POST /v1/pdf/from-html

Convert an HTML string to a PDF. The most common endpoint.

POSThttps://api.renderlyapi.com/v1/pdf/from-html

Request body

ParameterTypeRequiredDescription
htmlstring✓ requiredFull HTML string to render. Can include inline CSS, external fonts, images.
formatstringoptionalA4LetterLegal — defaults to A4
landscapebooleanoptionalRotate to landscape. Default false
marginobjectoptionalPage margins. Keys: toprightbottomleft — values like "1cm", "20px"
scalenumberoptionalViewport scale factor 0.1–2.0. Default 1
print_backgroundbooleanoptionalInclude CSS backgrounds. Default true
wait_forstringoptionalloaddomcontentloadednetworkidle0networkidle2

Example

{
  "html": "<html><body style='font-family:sans-serif; padding:40px'><h1>Invoice #001</h1><p>Amount: €500</p></body></html>",
  "format": "A4",
  "margin": { "top": "1cm", "right": "1cm", "bottom": "1cm", "left": "1cm" }
}
200 OK — application/pdf
Binary PDF data in response body

POST /v1/pdf/from-url

Navigate to a URL and capture it as a PDF. Useful for generating PDFs from existing web pages.

POSThttps://api.renderlyapi.com/v1/pdf/from-url

Request body

ParameterTypeRequiredDescription
urlstring✓ requiredPublicly accessible URL to capture. Must include https://
formatstringoptionalSame as from-html. Default A4
landscapebooleanoptionalDefault false
marginobjectoptionalPage margins
wait_forstringoptionalWait condition. Default networkidle2

Example

{
  "url": "https://example.com/report",
  "format": "A4",
  "landscape": false,
  "wait_for": "networkidle2"
}
200 OK — application/pdf
Binary PDF data in response body

GET /v1/usage

Returns your current period usage and 6-month history.

GEThttps://api.renderlyapi.com/v1/usage

Response

{
  "plan": "free",
  "period": "2026-05",
  "docs_rendered": 12,
  "docs_limit": 50,
  "docs_remaining": 38,
  "reset_date": "2026-06-01",
  "history": [
    { "period": "2026-05", "docs_rendered": 12 },
    { "period": "2026-04", "docs_rendered": 31 }
  ]
}

PDF options reference

OptionValuesDefault
formatA4A3A5LetterLegalTabloidA4
landscapetrue / falsefalse
margin.topCSS length (e.g. "1cm", "20px", "0")"0"
margin.rightCSS length"0"
margin.bottomCSS length"0"
margin.leftCSS length"0"
scale0.1 – 2.01
print_backgroundtrue / falsetrue
wait_forloaddomcontentloadednetworkidle0networkidle2load

Errors

All errors follow the same shape:

{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key."
  }
}
HTTP statusCodeMeaning
400invalid_inputMissing required field or bad value
401unauthorizedMissing, invalid, or revoked API key
429rate_limitedToo many requests — slow down
402quota_exceededMonthly PDF limit reached for your plan
500internal_errorSomething went wrong on our end

Rate limits

Requests are rate-limited per API key to prevent abuse. When you exceed the limit you'll receive a 429 response. Limits are:

Plans & limits

PlanPDFs / monthMax HTML sizePrice
Free505 MB€0
Starter50020 MB€19/mo
Pro2,00050 MB€49/mo
Scale10,000100 MB€99/mo

View full pricing details →

Example — Invoice PDF

const res = await fetch('https://api.renderlyapi.com/v1/pdf/from-html', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer rly_live_YOUR_KEY',
    'Content-Type':  'application/json',
  },
  body: JSON.stringify({
    html: `
      <html>
        <head>
          <style>
            body { font-family: 'Helvetica Neue', sans-serif; padding: 48px; color: #111; }
            h1   { font-size: 28px; margin-bottom: 4px; }
            .meta  { color: #888; font-size: 14px; margin-bottom: 32px; }
            table  { width: 100%; border-collapse: collapse; }
            th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #eee; }
            th     { font-size: 12px; text-transform: uppercase; color: #888; }
            .total { font-weight: 700; font-size: 18px; }
          </style>
        </head>
        <body>
          <h1>Invoice #001</h1>
          <p class="meta">Acme Corp · May 28, 2026</p>
          <table>
            <tr><th>Item</th><th>Qty</th><th>Price</th></tr>
            <tr><td>API Platform License</td><td>1</td><td>€1,200.00</td></tr>
            <tr><td>Support Package</td><td>1</td><td>€300.00</td></tr>
            <tr><td class="total">Total</td><td></td><td class="total">€1,500.00</td></tr>
          </table>
        </body>
      </html>
    `,
    format: 'A4',
    margin: { top: '1cm', right: '1cm', bottom: '1cm', left: '1cm' },
  }),
});

const buffer = await res.arrayBuffer();
fs.writeFileSync('invoice.pdf', Buffer.from(buffer));

cURL

curl -X POST https://api.renderlyapi.com/v1/pdf/from-html \
  -H "Authorization: Bearer rly_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html":"<h1>Hello Renderly</h1>","format":"A4"}' \
  --output document.pdf

Node.js

// Works with node-fetch, undici, or the built-in fetch (Node 18+)
import fs from 'fs';

async function renderPDF(html) {
  const res = await fetch('https://api.renderlyapi.com/v1/pdf/from-html', {
    method: 'POST',
    headers: {
      Authorization:  'Bearer rly_live_YOUR_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ html, format: 'A4' }),
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.error.message);
  }

  const buffer = await res.arrayBuffer();
  fs.writeFileSync('output.pdf', Buffer.from(buffer));
}

await renderPDF('<h1>My document</h1>');

Python

import requests

def render_pdf(html: str, output_path: str = "output.pdf"):
    res = requests.post(
        "https://api.renderlyapi.com/v1/pdf/from-html",
        headers={
            "Authorization": "Bearer rly_live_YOUR_KEY",
            "Content-Type":  "application/json",
        },
        json={"html": html, "format": "A4"},
    )
    res.raise_for_status()
    with open(output_path, "wb") as f:
        f.write(res.content)

render_pdf("<h1>Hello from Python!</h1>")