New User Offer Get $5 free credit instantly — no credit card required. Use code WELCOME Claim $5 Free
API V1 — Production Ready

HTML & CSS to PDF & PNG API

Render HTML and CSS exactly as a browser does, then take it away as a PDF or a full-page PNG. Grid, flexbox, gradients and web fonts all work, with optional JavaScript execution and full control over page size, margins and scale.

Full CSS
Grid, flexbox, web fonts
500+ Pages
Long documents supported
PDF + PNG
Page images for long documents
~250ms
Typical render

Built for Documents That Have to Look Right

Invoices, reports, certificates, tickets and dashboards — rendered by the same engine that draws them on screen, so the output matches the design instead of approximating it.

Modern CSS

Grid, flexbox, custom properties, gradients and transforms, rendered by a real browser engine.

Fast

A warm engine renders a typical document in about a quarter of a second.

Full Page Control

Named or custom page sizes, orientation, margins and scale.

JavaScript

Run scripts before capture so charts and client-rendered content appear in the output.

Your Fonts

Web fonts and local families load and are waited for before the page is captured.

PDF or PNG

Take a paginated PDF, or a full-height screenshot of the entire page.

Simple, Transparent Pricing

Start free and move up when you need more. Every plan renders with the same engine — higher tiers unlock larger documents, more output formats and full styling control.

Free
Free
  • 30 documents/month
  • 3 requests/minute
  • Up to 512 KB input (~150 pages)
  • Full modern CSS support
  • Hosted link valid 2 hours
  • Page size, margins, scale
Start Free
Starter
$6.99/month
  • 500 documents/month
  • 8 requests/minute
  • Up to 1 MB input (~290 pages)
  • JavaScript execution
  • PNG page images
  • Hosted link valid 7 days
  • Headers, footers, page numbers
Get Started
Pro
$19.99/month
  • 2,500 documents/month
  • 15 requests/minute
  • Up to 1.5 MB input (~440 pages)
  • JavaScript execution
  • PNG page images
  • Hosted link valid 7 days
  • Headers, footers, page numbers
Choose Pro
Max
$39.99/month
  • 8,000 documents/month
  • 25 requests/minute
  • Up to 2 MB input (~570 pages)
  • JavaScript execution
  • PNG page images
  • Hosted link valid 7 days
  • Priority processing
Choose Max
Enterprise

Enterprise & Agency Plan

High-volume document generation, custom limits, dedicated capacity and SLAs. We build the plan around your workload.

Unlimited documents
Custom input size
Custom rate limit
Dedicated capacity
24/7 Support

API Reference

Everything you need to integrate the HTML to PDF API

Authentication

Every request needs your API key in the x-api-key header. Keys are created in the dashboard and belong to your account rather than to a single API.

Header
x-api-key: your_api_key
Keep the key server sideAnyone holding it can spend your quota. Call this API from your backend, never from a browser.

API Endpoint

POSThttps://api.corenexis.com/html-to-pdf/v1

One synchronous endpoint. Send the HTML and the finished document comes back in the same response — there is no job to poll.

What Renders

Documents are rendered by a real browser engine, so what you see in a browser is what lands in the PDF. Grid, flexbox, custom properties, gradients, transforms, web fonts and SVG all work without a compatibility layer.

Backgrounds are printed by defaultColoured panels, gradients and background images appear in the output. There is no need for a print-specific stylesheet.

External resources

Stylesheets, images and web fonts referenced by public URL are fetched and waited for before capture. Reference them absolutely — a relative path has no page to resolve against.

Input Modes

The HTML can arrive in any of these forms. Use whichever suits your environment.

1. JSON body — recommended

cURL
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Invoice</h1><p>Thank you.</p>", "page_size": "a4"}'

2. Form field

cURL
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: your_api_key" \
  -F "html=<h1>Hello</h1>" \
  -F "page_size=letter"

3. File upload

cURL
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: your_api_key" \
  -F "[email protected]"

4. Raw request body

cURL
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: your_api_key" \
  -H "Content-Type: text/html" \
  --data-binary @invoice.html

Parameters

ParameterTypeDescription
x-api-keyRequiredStringYour API key. Send in the request header.
htmlRequiredStringThe HTML to render. May also be sent as an uploaded file or as the raw request body.
formatOptionalStringpdf or png. PNG requires a paid plan.
Default: pdf
outputOptionalStringOnly url. Every result is delivered as a hosted link, on every plan, so this can be omitted. base64 and binary were withdrawn and now return a clear error.
Default: url
page_sizeOptionalStringa3, a4, a5, letter, legal or tabloid.
Default: a4
orientationOptionalStringportrait or landscape.
Default: portrait
widthOptionalNumberCustom page width in millimetres, 20 to 2000. Must be sent with height.
heightOptionalNumberCustom page height in millimetres, 20 to 2000. Must be sent with width.
margin_topOptionalNumberTop margin in millimetres, 0 to 100.
Default: 20
margin_rightOptionalNumberRight margin in millimetres, 0 to 100.
Default: 15
margin_bottomOptionalNumberBottom margin in millimetres, 0 to 100.
Default: 20
margin_leftOptionalNumberLeft margin in millimetres, 0 to 100.
Default: 15
scaleOptionalNumberRender scale, 0.1 to 2.
Default: 1
jsOptionalBooleanRun scripts in the page before capture. Paid plans only.
Default: false
wait_msOptionalNumberExtra delay after load, 0 to 5000 ms. Requires js.
Default: 0
header_htmlOptionalStringHTML for the running header. Paid plans only.
footer_htmlOptionalStringHTML for the running footer. Paid plans only.
filenameOptionalStringName for the produced file, without extension.
Default: document
Everything except the HTML is optionalSend nothing else and you get a sensible A4 portrait document. Anything you do send is applied.

JavaScript

Set js to true to run scripts before capture, and use wait_ms to allow for work that finishes after load. Charts, templating and client-side rendering all work. Available on paid plans.

JSON
{
  "html": "<div id=\"chart\"></div><script>renderChart()</script>",
  "js": true,
  "wait_ms": 500
}
Give async work time to finishThe page is captured once the network goes quiet. If your script draws after that, add wait_ms.

Headers and Footers

Send header_html and footer_html to place a running header or footer on every page. Inside them, <span class="pageNumber"></span> and <span class="totalPages"></span> are replaced with page numbers.

JSON
{
  "html": "<h1>Report</h1>",
  "margin_bottom": 25,
  "footer_html": "<div style=\"font-size:9px;width:100%;padding:0 12mm;text-align:right;color:#666\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
}
Give the page roomA header or footer draws inside the margin, so increase margin_top or margin_bottom or it will overlap the content.

How the Result Is Delivered

Every result is stored and handed back as a hosted link under data.url, on every plan including the free one. There is nothing to decode and nothing to stream.

PlanLink valid forWhy
Free2 hoursLong enough to fetch and use the file in the workflow that produced it.
Any paid plan7 daysLong enough to email, queue or hand on to another service.
Fetch the file, do not hotlink itThe link expires. Download it once and store the bytes yourself rather than pointing your users at it.

What changed

Inline delivery was withdrawn. A caller still sending the old value gets an error that says so rather than a silent change of behaviour.

outputStatusNotes
base64WithdrawnThe file inside the JSON response. It inflated every result by a third and had to be held in memory twice.
binaryWithdrawnThe raw file as the response body. It could not carry a document that had become several images.
urlThe only modeA hosted link under data.url. This is now the default, so the parameter can be omitted.

PDF and Page Images

Set format to png to receive images instead of a PDF. PNG output is a paid feature.

png_modeWhat you getWhen to use it
stackThe document laid out into pages, returned as an ordered sequence of images in data.images.Default. Reading or displaying a whole document.
firstOne image of page one.Thumbnails and previews.
pageOne image of the page named by png_page.Pulling a single page out of a long document.
viewportOne continuous screenshot with no page breaks, at the page's natural height.Capturing a design rather than a document.
Why paged is the defaultA continuous capture stops at the renderer's maximum height, so on a long page it silently returned only the top. The paged modes have no such limit: the pages are grouped into as many images as it takes, and image.truncated tells you whether the set is complete. viewport is still there when you want one unbroken image, and it reports clipped when it had to stop.

Code Examples

Python

Python
import base64, requests

resp = requests.post(
    "https://api.corenexis.com/html-to-pdf/v1",
    headers={"x-api-key": "your_api_key"},
    json={
        "html": open("invoice.html").read(),
        "page_size": "a4",
        "margin_top": 12,
        "margin_bottom": 12,
        "js": True,
        "wait_ms": 300,
    },
    timeout=120,
)
data = resp.json()
if not data["success"]:
    raise SystemExit(data["message"])

with open("invoice.pdf", "wb") as fh:
    fh.write(base64.b64decode(data["data"]["content"]))

Node.js

JavaScript
const fs = require("fs");

const res = await fetch("https://api.corenexis.com/html-to-pdf/v1", {
  method: "POST",
  headers: { "x-api-key": "your_api_key", "Content-Type": "application/json" },
  body: JSON.stringify({
    html: fs.readFileSync("invoice.html", "utf8"),
    format: "png",
    output: "url",
  }),
});

const data = await res.json();
if (!data.success) throw new Error(data.message);
console.log(data.data.url, data.data.image);

PHP

PHP
<?php
$ch = curl_init('https://api.corenexis.com/html-to-pdf/v1');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'x-api-key: your_api_key',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'html'        => file_get_contents('invoice.html'),
        'page_size'   => 'a4',
        'orientation' => 'landscape',
        'output'      => 'binary',
    ]),
]);
$pdf = curl_exec($ch);
curl_close($ch);

file_put_contents('invoice.pdf', $pdf);
Set a User-AgentPython's built-in urllib sends a default agent string our edge network refuses. The requests library, Node, Go, Java and cURL all work unchanged.

Response

JSON
{
  "success": true,
  "plan": "pro",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "pages": 1,
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 305,
    "url": "https://cdn.corenexis.com/f/qLm6VWHVlur.pdf",
    "filename": "document.pdf",
    "size_bytes": 45589,
    "expires_at": "2026-08-16T06:24:41+00:00"
  },
  "usage": { "remaining": 2498, "rate_limit": 15, "monthly_limit": 2500 }
}

Always check the success field rather than the status code alone. On failure the body carries a code and a message naming what to change.

Every Option, Worked

Every option below was sent to the live API and the response shown is what came back, including the request that produced it. Copy a command, put your own key in it, and you get the same shape of answer.

Minimal request

Only the document is required. Grid, flexbox, gradients and web fonts all render, because a real browser engine draws the page.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...your document..."
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 1539,
    "pages": 1,
    "url": "https://cdn.corenexis.com/f/M5Cd8FtSTtV.pdf",
    "filename": "document.pdf",
    "size_bytes": 16304,
    "expires_at": "2026-08-09T06:57:53+00:00"
  },
  "usage": {
    "remaining": 4987,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

Page size and orientation

One of a3, a4, a5, letter, legal or tabloid, in either orientation.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...your document...",
    "page_size": "letter",
    "orientation": "landscape"
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "page_size": "letter",
    "orientation": "landscape",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 318,
    "pages": 1,
    "url": "https://cdn.corenexis.com/f/J8XaCP3y547.pdf",
    "filename": "document.pdf",
    "size_bytes": 16276,
    "expires_at": "2026-08-09T06:57:53+00:00"
  },
  "usage": {
    "remaining": 4986,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

Custom page dimensions

Millimetres, 20 to 2000, supplied together. Overrides page_size, and the response reports page_size as custom so it is clear which applied.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...your document...",
    "width": 150,
    "height": 100
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "page_size": "custom",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 453,
    "pages": 1,
    "width_mm": 150,
    "height_mm": 100,
    "url": "https://cdn.corenexis.com/f/n6LiWb0bJ0D.pdf",
    "filename": "document.pdf",
    "size_bytes": 16296,
    "expires_at": "2026-08-09T06:57:54+00:00"
  },
  "usage": {
    "remaining": 4985,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

All four margins

Millimetres, 0 to 100 each.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...your document...",
    "margin_top": 25,
    "margin_right": 20,
    "margin_bottom": 25,
    "margin_left": 20
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 311,
    "pages": 1,
    "url": "https://cdn.corenexis.com/f/0iaopelfqvs.pdf",
    "filename": "document.pdf",
    "size_bytes": 16289,
    "expires_at": "2026-08-09T06:57:54+00:00"
  },
  "usage": {
    "remaining": 4984,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

Scale

0.1 to 2.0. Scales the rendered page before it is paginated, so 0.75 fits more onto each sheet rather than shrinking the sheet.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...your document...",
    "scale": 0.75
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 0.75,
    "js_enabled": false,
    "render_time_ms": 290,
    "pages": 1,
    "url": "https://cdn.corenexis.com/f/in3LLDB6jqu.pdf",
    "filename": "document.pdf",
    "size_bytes": 16317,
    "expires_at": "2026-08-09T06:57:55+00:00"
  },
  "usage": {
    "remaining": 4983,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

JavaScript execution

Off by default. wait_ms waits after load for scripted content to settle, and only applies when JavaScript is enabled.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<html><body><h1 id='t'>placeholder</h1><script>document.getElementById('t').textContent='written by script';</script></body></html>",
    "js": true,
    "wait_ms": 300
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": true,
    "render_time_ms": 2507,
    "pages": 1,
    "url": "https://cdn.corenexis.com/f/YL7zK3syOjb.pdf",
    "filename": "document.pdf",
    "size_bytes": 7764,
    "expires_at": "2026-08-09T06:57:57+00:00"
  },
  "usage": {
    "remaining": 4982,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

Header and footer with page numbers

Full HTML, up to 2000 characters each. The browser substitutes pageNumber and totalPages.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...long document...",
    "header_html": "<div style='font-size:9pt;width:100%;text-align:center'>Invoice</div>",
    "footer_html": "<div style='font-size:9pt;width:100%;text-align:center'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></div>"
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "pdf",
    "mime": "application/pdf",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 2194,
    "pages": 94,
    "url": "https://cdn.corenexis.com/f/TSC4XHrqoJK.pdf",
    "filename": "document.pdf",
    "size_bytes": 527013,
    "expires_at": "2026-08-09T06:57:59+00:00"
  },
  "usage": {
    "remaining": 4981,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

PNG, whole document

Pages are rendered and returned as an ordered sequence of images, so a long document comes back complete.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...long document...",
    "format": "png"
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "png",
    "mime": "image/png",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 56288,
    "pages": 94,
    "url": "https://cdn.corenexis.com/f/3Vqgm5fTcVa.png",
    "filename": "document-p1-17.png",
    "size_bytes": 1379418,
    "expires_at": "2026-08-09T06:58:56+00:00",
    "image": {
      "mode": "stack",
      "dpi": 144,
      "pages_total": 94,
      "pages_rendered": 94,
      "pages_per_image": 17,
      "truncated": false
    },
    "image_count": 6,
    "total_bytes": 7571082,
    "images": [
      {
        "url": "https://cdn.corenexis.com/f/3Vqgm5fTcVa.png",
        "filename": "document-p1-17.png",
        "size_bytes": 1379418,
        "expires_at": "2026-08-09T06:58:56+00:00",
        "page_from": 1,
        "page_to": 17,
        "width": 1192,
        "height": 28628
      },
      {
        "url": "https://cdn.corenexis.com/f/HHMBPPVvek2.png",
        "filename": "document-p18-34.png",
        "size_bytes": 1381082,
        "expires_at": "2026-08-09T06:58:56+00:00",
        "page_from": 18,
        "page_to": 34,
        "width": 1192,
        "height": 28628
      },
      "... 4 more, one per page range, in order"
    ]
  },
  "usage": {
    "remaining": 4980,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

PNG, one chosen page

Any page the document has.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...long document...",
    "format": "png",
    "png_mode": "page",
    "png_page": 12
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "png",
    "mime": "image/png",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 2229,
    "pages": 94,
    "url": "https://cdn.corenexis.com/f/H7AoJ1d5zIR.png",
    "filename": "document.png",
    "size_bytes": 126506,
    "expires_at": "2026-08-09T06:58:58+00:00",
    "image": {
      "mode": "page",
      "dpi": 144,
      "pages_total": 94,
      "pages_rendered": 1,
      "pages_per_image": 17,
      "truncated": false
    },
    "image_count": 1,
    "total_bytes": 126506,
    "images": [
      {
        "url": "https://cdn.corenexis.com/f/H7AoJ1d5zIR.png",
        "filename": "document.png",
        "size_bytes": 126506,
        "expires_at": "2026-08-09T06:58:58+00:00",
        "page_from": 12,
        "page_to": 12,
        "width": 1192,
        "height": 1684
      }
    ]
  },
  "usage": {
    "remaining": 4979,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

PNG, continuous viewport capture

One continuous screenshot with no page breaks, for capturing a design rather than a document. It stops at the renderer's maximum height, so clipped tells you whether the whole page was captured.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...your document...",
    "format": "png",
    "png_mode": "viewport"
  }'
Response — HTTP 200
{
  "success": true,
  "plan": "basic",
  "data": {
    "status": "completed",
    "format": "png",
    "mime": "image/png",
    "page_size": "a4",
    "orientation": "portrait",
    "scale": 1,
    "js_enabled": false,
    "render_time_ms": 435,
    "url": "https://cdn.corenexis.com/f/OuQ6HZMAjhm.png",
    "filename": "document.png",
    "size_bytes": 20267,
    "expires_at": "2026-08-09T06:58:59+00:00",
    "image": {
      "mode": "viewport",
      "width": 1280,
      "height": 1200,
      "clipped": false
    }
  },
  "usage": {
    "remaining": 4978,
    "rate_limit": 120,
    "monthly_limit": 5000
  }
}

Refused: retired output mode

Inline delivery was withdrawn. Every result is a hosted link.

Request
curl -X POST "https://api.corenexis.com/html-to-pdf/v1" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "...your document...",
    "output": "binary"
  }'
Response — HTTP 400
{
  "success": false,
  "code": "INVALID_INPUT",
  "message": "'output' no longer accepts 'binary'. Every result is delivered as a hosted link, so omit the parameter or send output=url. The response carries the link in data.url."
}

Errors

Errors arrive as JSON with a stable code.

CodeHTTPMeaning
MISSING_KEY401The x-api-key header was not sent.
INVALID_KEY401The key does not exist or has been revoked.
KEY_DISABLED403The key exists but has been switched off.
ACCOUNT_SUSPENDED403The account is suspended.
NO_SUBSCRIPTION402The account has no subscription to this API.
SUBSCRIPTION_EXPIRED402The subscription lapsed and the grace period has passed.
RATE_LIMIT_EXCEEDED429Too many requests this minute. Retry shortly.
QUOTA_EXCEEDED429The monthly allowance is used up.
PARAM_LIMIT_EXCEEDED400A requested feature or value is above what the plan allows. The response names the parameter.
INVALID_INPUT400Something in the request is malformed. The message names the field.
RENDER_TIMEOUT408The document took too long. Simplify it and retry.
PROCESSING_FAILED422The document could not be rendered.
RENDERER_BUSY503Every worker is busy. Retry in a moment.
Quota-safe failuresIf rendering fails after your request was accepted, your monthly quota is not charged. Only successful documents count.
Rate limitingFree 3/min · Starter 8/min · Pro 15/min · Max 25/min.

Limits

LimitValue
Maximum input size512 KB free, up to 2 MB on Max
Pages that means in practiceAbout 150 pages free, about 570 on Max, for ordinary prose
Page limitThere is no page limit. A 660-page document renders in about 20 seconds
Maximum delivered file15 MB
Render deadline25 seconds in the renderer. Beyond it you receive RENDER_TIMEOUT and nothing is charged
Hosted link lifetime2 hours on the free plan, 7 days on any paid plan
ConcurrencyOne document at a time, so latency stays predictable

Documents render one at a time so latency stays predictable. If every worker is busy you receive RENDERER_BUSY and nothing is charged; retry a moment later.

Sample output

The samples/ directory in the project repository holds real output across page sizes, orientations and both formats, so you can see what each option produces before calling the API.

Ready to Ship Pixel-Perfect PDFs?

Create your free account and turn your first HTML page into a PDF in seconds. No credit card required.

Stay in the Loop

Get the latest updates delivered straight to your inbox