Generate PDFs from HTML with just a few lines of code. This guide walks you through the FUNBREW PDF API with step-by-step examples in Node.js, Python, and PHP. If you're migrating from Puppeteer or Playwright, see the Puppeteer migration guide.
Setup
1. Create an Account
Sign up for free. You get 30 PDF generations per month at no cost.
2. Get Your API Key
Navigate to the "API Keys" section in your dashboard and generate a key. It starts with sk-.
# Set as an environment variable (recommended)
export FUNBREW_PDF_API_KEY="sk-your-api-key"
For secure key management practices, see the security guide.
3. API Endpoint
POST https://api.pdf.funbrew.cloud/v1/pdf/from-html
Send HTML, get a PDF binary back. Simple request/response model.
Node.js
For TypeScript projects, see the TypeScript PDF API guide for type-safe implementations. For Next.js or Nuxt integrations, check the Next.js/Nuxt guide.
fetch (Built-in API)
Node.js 18+ includes fetch natively. No extra packages needed.
const fs = require('fs');
async function generatePdf() {
const response = await fetch('https://api.pdf.funbrew.cloud/v1/pdf/from-html', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.FUNBREW_PDF_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: `
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 40px; }
h1 { color: #1a1a1a; border-bottom: 2px solid #3b82f6; padding-bottom: 8px; }
.info { color: #6b7280; margin-top: 24px; }
</style>
</head>
<body>
<h1>Report</h1>
<p>This PDF was generated via the API.</p>
<p class="info">Generated: ${new Date().toISOString()}</p>
</body>
</html>
`,
engine: 'quality',
format: 'A4',
}),
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const pdf = Buffer.from(await response.arrayBuffer());
fs.writeFileSync('output.pdf', pdf);
console.log('PDF generated: output.pdf');
}
generatePdf();
axios
When using axios, setting the response type is key.
const axios = require('axios');
const fs = require('fs');
async function generatePdf() {
const { data } = await axios.post(
'https://api.pdf.funbrew.cloud/v1/pdf/from-html',
{
html: '<h1>Hello PDF</h1><p>Generated with axios</p>',
engine: 'fast',
format: 'A4',
},
{
headers: { 'Authorization': `Bearer ${process.env.FUNBREW_PDF_API_KEY}` },
responseType: 'arraybuffer', // Required for binary response
}
);
fs.writeFileSync('output.pdf', data);
console.log('PDF generated: output.pdf');
}
generatePdf();
Python
For Django or FastAPI integrations, see the Django/FastAPI PDF API guide.
requests
The most popular HTTP library in Python.
import os
import requests
def generate_pdf():
response = requests.post(
'https://api.pdf.funbrew.cloud/v1/pdf/from-html',
headers={
'Authorization': f'Bearer {os.environ["FUNBREW_PDF_API_KEY"]}',
},
json={
'html': '''
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 40px; }
h1 { color: #1a1a1a; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { border: 1px solid #e5e7eb; padding: 12px; text-align: left; }
th { background: #f8fafc; }
</style>
</head>
<body>
<h1>Sales Report</h1>
<table>
<tr><th>Month</th><th>Revenue</th></tr>
<tr><td>January</td><td>$12,000</td></tr>
<tr><td>February</td><td>$13,500</td></tr>
<tr><td>March</td><td>$15,000</td></tr>
</table>
</body>
</html>
''',
'engine': 'quality',
'format': 'A4',
},
timeout=30,
)
response.raise_for_status()
with open('report.pdf', 'wb') as f:
f.write(response.content)
print(f'PDF generated: report.pdf ({len(response.content)} bytes)')
generate_pdf()
httpx (Async Support)
For async workflows, httpx is a great choice.
import httpx
import asyncio
import os
async def generate_pdf():
async with httpx.AsyncClient() as client:
response = await client.post(
'https://api.pdf.funbrew.cloud/v1/pdf/from-html',
headers={'Authorization': f'Bearer {os.environ["FUNBREW_PDF_API_KEY"]}'},
json={
'html': '<h1>Async PDF</h1><p>Generated with httpx</p>',
'engine': 'fast',
'format': 'A4',
},
timeout=30,
)
response.raise_for_status()
with open('output.pdf', 'wb') as f:
f.write(response.content)
print('PDF generated: output.pdf')
asyncio.run(generate_pdf())
PHP
For Ruby or Go code examples, see the Ruby/Go quickstart guide.
Laravel (Http Facade)
The most concise approach using Laravel's built-in HTTP client.
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
$response = Http::withToken(config('services.funbrew.api_key'))
->post('https://api.pdf.funbrew.cloud/v1/pdf/from-html', [
'html' => '
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 40px; }
h1 { color: #1a1a1a; }
</style>
</head>
<body>
<h1>Delivery Note</h1>
<p>To: Acme Corp</p>
<p>Total: $3,300.00 (incl. tax)</p>
</body>
</html>
',
'engine' => 'quality',
'format' => 'A4',
]);
if ($response->successful()) {
Storage::put('pdfs/delivery-note.pdf', $response->body());
}
cURL (Framework-agnostic)
Plain PHP with cURL — works anywhere.
$ch = curl_init('https://api.pdf.funbrew.cloud/v1/pdf/from-html');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('FUNBREW_PDF_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'html' => '<h1>Hello PDF</h1>',
'engine' => 'fast',
'format' => 'A4',
]),
]);
$pdf = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
file_put_contents('output.pdf', $pdf);
}
Ruby
Use Ruby's standard library or the popular Faraday gem.
net/http (Standard Library)
require 'net/http'
require 'json'
require 'uri'
uri = URI('https://api.pdf.funbrew.cloud/v1/pdf/from-html')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = "Bearer #{ENV['FUNBREW_PDF_API_KEY']}"
request['Content-Type'] = 'application/json'
request.body = {
html: '<h1>Hello from Ruby</h1><p>PDF generated with net/http</p>',
engine: 'fast',
format: 'A4'
}.to_json
response = http.request(request)
if response.code == '200'
File.open('output.pdf', 'wb') { |f| f.write(response.body) }
puts "PDF generated: output.pdf (#{response.body.bytesize} bytes)"
end
Faraday
require 'faraday'
conn = Faraday.new(url: 'https://api.pdf.funbrew.cloud') do |f|
f.request :json
f.headers['Authorization'] = "Bearer #{ENV['FUNBREW_PDF_API_KEY']}"
end
response = conn.post('/v1/pdf/from-html', {
html: '<h1>Hello from Ruby</h1>',
engine: 'quality',
format: 'A4'
})
File.open('output.pdf', 'wb') { |f| f.write(response.body) } if response.success?
Go
Go's standard library is all you need — no external dependencies.
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
payload, _ := json.Marshal(map[string]interface{}{
"html": "<h1>Hello from Go</h1>",
"engine": "fast",
"format": "A4",
})
req, _ := http.NewRequest("POST",
"https://api.pdf.funbrew.cloud/v1/pdf/from-html",
bytes.NewBuffer(payload))
req.Header.Set("Authorization", "Bearer "+os.Getenv("FUNBREW_PDF_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
pdf, _ := io.ReadAll(resp.Body)
os.WriteFile("output.pdf", pdf, 0644)
fmt.Printf("PDF generated: output.pdf (%d bytes)\n", len(pdf))
}
}
Frequently Asked Questions
Can I use external CSS or web fonts in HTML?
Yes. Use <link> tags to load external stylesheets. Google Fonts and other web fonts work too. However, external resources add to generation time — for production, consider inline styles or self-hosted fonts.
Base64 or URL for images?
Small icons and logos (under 50 KB) work best as Base64-encoded data URIs. For larger images, use URL references to keep request size down. URL-referenced images must be publicly accessible.
How can I reduce PDF file size?
Use engine: "fast" for smaller files. Also: optimize image resolution, remove unused web fonts, and keep CSS minimal.
Choosing an Engine
FUNBREW PDF offers two rendering engines. Switch between them per request.
| Engine | Parameter | Characteristics | Best For |
|---|---|---|---|
| Fast | "engine": "fast" |
High speed, lightweight | Simple HTML, bulk generation |
| Quality | "engine": "quality" |
High fidelity, full CSS | Design-heavy, CSS Grid layouts |
For technical details on engine differences, see wkhtmltopdf vs Chromium.
Next Steps
Once you have basic PDF generation working, explore these features:
- Template Engine: Inject variables into HTML templates for dynamic PDFs
- Invoice Automation: Templates + batch API for monthly billing
- Playground: Test PDF generation live in your browser
- API Reference: Full endpoint documentation
Related
- PDF API Production Checklist — From development to production deployment
- HTML to PDF API Comparison 2026 — Feature comparison across services
- PDF API Security Guide — API key management and security practices
- wkhtmltopdf vs Chromium — Technical engine comparison
- PDF API Error Handling Guide — Error handling best practices
- PDF API Batch Processing Guide — Bulk PDF generation with concurrency
- TypeScript PDF API Guide — Type-safe implementation in TypeScript
- Django/FastAPI PDF API Guide — Python framework integrations
- Next.js/Nuxt PDF API Guide — Frontend framework integrations
- Ruby/Go Quickstart — Code examples in Ruby and Go
- Puppeteer Migration Guide — Migrating from Puppeteer to the API
- API Reference — Full endpoint documentation