Generating PDFs in PHP used to mean installing wkhtmltopdf binaries, fighting system dependencies, or embedding complex libraries like TCPDF. This tutorial shows a simpler way: call the URLSnap REST API from PHP using cURL — no binary installs, no library bloat.
<?php
$response = file_get_contents('https://urlsnap.dev/api/register', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode(['email' => 'you@example.com']),
]
]));
$data = json_decode($response, true);
echo $data['key']; // us_abc123...
?>
<?php
function urlToPdf(string $url, string $outputPath, string $apiKey, array $options = []): void {
$params = array_merge(['url' => $url], $options);
$queryString = http_build_query($params);
$ch = curl_init("https://urlsnap.dev/api/pdf?{$queryString}");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: {$apiKey}"],
CURLOPT_TIMEOUT => 60,
CURLOPT_FOLLOWLOCATION => true,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
$err = json_decode($body, true);
throw new \RuntimeException($err['error'] ?? "HTTP {$status}");
}
file_put_contents($outputPath, $body);
echo "Saved PDF to {$outputPath} (" . round(strlen($body) / 1024, 1) . " KB)\n";
}
$apiKey = 'us_your_key_here';
// Basic A4 PDF
urlToPdf('https://example.com', 'page.pdf', $apiKey);
// Letter-size, landscape, with margin
urlToPdf(
'https://en.wikipedia.org/wiki/PHP',
'php-wiki.pdf',
$apiKey,
['format' => 'Letter', 'landscape' => 'true', 'margin' => '15px']
);
?>
Send an HTML string directly — great for rendering invoice or report templates:
<?php
function htmlToPdf(string $html, string $outputPath, string $apiKey, string $format = 'A4'): void {
$ch = curl_init('https://urlsnap.dev/api/pdf');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['html' => $html, 'format' => $format]),
CURLOPT_HTTPHEADER => [
"x-api-key: {$apiKey}",
'Content-Type: application/json',
],
CURLOPT_TIMEOUT => 60,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
$err = json_decode($body, true);
throw new \RuntimeException($err['error'] ?? "HTTP {$status}");
}
file_put_contents($outputPath, $body);
}
$invoiceHtml = '<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 40px; color: #111; }
h1 { color: #6366f1; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { padding: 10px; border-bottom: 1px solid #eee; text-align: left; }
.total { font-weight: bold; }
</style>
</head>
<body>
<h1>Invoice #INV-2026-001</h1>
<p>Bill to: Acme Corp</p>
<table>
<tr><th>Item</th><th>Amount</th></tr>
<tr><td>API Starter Plan</td><td>$9.00</td></tr>
<tr class="total"><td>Total</td><td>$9.00</td></tr>
</table>
</body>
</html>';
htmlToPdf($invoiceHtml, 'invoice.pdf', 'us_your_key_here');
echo "Invoice generated!\n";
?>
Useful for download endpoints in Laravel or plain PHP:
<?php
// download-pdf.php — e.g. GET /download-pdf.php?url=https://example.com
$url = $_GET['url'] ?? '';
$apiKey = 'us_your_key_here';
if (!$url) {
http_response_code(400);
echo json_encode(['error' => 'url required']);
exit;
}
$ch = curl_init('https://urlsnap.dev/api/pdf?' . http_build_query(['url' => $url, 'format' => 'A4']));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: {$apiKey}"],
CURLOPT_TIMEOUT => 60,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
http_response_code($status);
echo $body;
exit;
}
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="page.pdf"');
header('Content-Length: ' . strlen($body));
echo $body;
?>
<?php
function safePdf(string $url, string $outputPath, string $apiKey): bool {
$ch = curl_init('https://urlsnap.dev/api/pdf?' . http_build_query(['url' => $url, 'format' => 'A4']));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: {$apiKey}"],
CURLOPT_TIMEOUT => 60,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlErr = curl_error($ch);
curl_close($ch);
if ($curlErr) {
error_log("cURL error: {$curlErr}");
return false;
}
if ($status === 429) {
error_log('Daily limit reached. Upgrade at urlsnap.dev/#pricing');
return false;
}
if ($status === 401) {
error_log('Invalid API key');
return false;
}
if ($status !== 200) {
$err = json_decode($body, true);
error_log('PDF error: ' . ($err['error'] ?? "HTTP {$status}"));
return false;
}
file_put_contents($outputPath, $body);
return true;
}
$ok = safePdf('https://example.com', 'output.pdf', 'us_your_key_here');
echo $ok ? "PDF saved!\n" : "Failed — check error log\n";
?>
<?php
$ch = curl_init('https://urlsnap.dev/api/me');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: us_your_key_here'],
]);
$info = json_decode(curl_exec($ch), true);
curl_close($ch);
echo "Plan: {$info['plan']}\n";
echo "Used today: {$info['requests_today']}/{$info['daily_limit']}\n";
echo "Total all-time: {$info['requests_total']}\n";
?>
Free tier: 20 PDFs/day. No binary installs, no server config.
Get your free API key →