How to Generate PDFs from URLs in PHP

Published April 3, 2026 · 6 min read · URLSnap Team

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.

Prerequisites

Get a Free API Key

<?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...
?>

Convert a URL to PDF

<?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']
);
?>
📄 Supported formats: A4, Letter, Legal, A3, Tabloid.

Convert HTML to PDF

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";
?>

Stream PDF Directly to the Browser

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;
?>
💡 Free plan: 20 req/day. Starter ($9/mo): 500 req/day. Pro ($29/mo): 5,000 req/day. Upgrade at urlsnap.dev/#pricing.

Error Handling

<?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";
?>

Check Your Quota

<?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";
?>

Start generating PDFs in PHP today

Free tier: 20 PDFs/day. No binary installs, no server config.

Get your free API key →