Render HTML to PDF with the Screenshot API
Turn an invoice, report or certificate template into a PDF from PHP, with no headless browser on your own server.
Generating PDFs in PHP usually means bundling a headless browser or a heavyweight library. The Screenshot (HTML) endpoint does the rendering for you: send a complete HTML document, ask for format=pdf, and get back the URL of the finished file.
1. Build the document#
The endpoint renders exactly what you send, in isolation. Two rules follow from that:
- Use absolute URLs for images, fonts and stylesheets. Relative paths will not resolve.
- Inline the CSS you care about. External stylesheets work if they are reachable over HTTPS, but inline styles remove a failure mode.
<?php
$html = <<<HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { font-family: Helvetica, Arial, sans-serif; color: #171717; margin: 40px; }
h1 { font-size: 24px; margin: 0 0 8px; }
table { width: 100%; border-collapse: collapse; margin-top: 24px; }
th, td { text-align: left; padding: 8px 0; border-bottom: 1px solid #e6e4e1; }
.total { font-weight: bold; }
</style>
</head>
<body>
<h1>Invoice #1042</h1>
<p>Issued 15 September 2026</p>
<table>
<tr><th>Item</th><th>Qty</th><th>Amount</th></tr>
<tr><td>Design retainer</td><td>1</td><td>$1,200.00</td></tr>
<tr class="total"><td>Total</td><td></td><td>$1,200.00</td></tr>
</table>
</body>
</html>
HTML;
2. Send it#
Post the document as a form field. Rendering takes a few seconds, so give cURL a generous timeout.
$ch = curl_init('https://api.zactonz.com/screen/html/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 90,
CURLOPT_POSTFIELDS => http_build_query([
'html' => $html,
'format' => 'pdf',
]),
]);
$result = json_decode(curl_exec($ch), true);
if ((int) ($result['status'] ?? 0) !== 200) {
throw new RuntimeException('Render failed: ' . ($result['data'] ?? 'no response'));
}
$pdfUrl = $result['data'];
3. Store or forward the file#
data is a URL on the API host. Fetch it and keep your own copy; that way your application does not depend on the capture staying available.
file_put_contents('/var/app/invoices/1042.pdf', file_get_contents($pdfUrl));
To send it straight to the browser instead:
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="invoice-1042.pdf"');
readfile($pdfUrl);
Page size and margins#
The HTML endpoint prints with Chromium's defaults. If you need control over paper size, orientation or margins, host the document at a URL and use Screenshot (URL) instead, which accepts paperWidth, paperHeight, orientation, margin* and scale for PDF output.
Images instead of PDFs#
The same request with format=png or format=jpeg returns a raster capture at the requested width and height. That is handy for social-share cards and email-safe previews of the same template.