API Reference
Complete API reference for all FUNBREW PDF API endpoints.
SDK
Official client libraries available on GitHub.
| Language | GitHub | Install |
|---|---|---|
| PHP | FUNBREW/funbrew-pdf-php | composer require funbrew/pdf-php※GitHub経由(READMEを参照) |
| Node.js | FUNBREW/pdf-node | npm install @funbrew/pdf |
| Python | FUNBREW/pdf-python | pip install funbrew-pdf |
| CLI | FUNBREW/pdf-cli | npm install -g @funbrew/pdf-cli |
PHP
$pdf = new Funbrew\Pdf\FunbrewPdf('sk-your-api-key');
$result = $pdf->fromHtml('<h1>Hello</h1>');
echo $result['data']['download_url'];Node.js
const { FunbrewPdf } = require('@funbrew/pdf');
const pdf = new FunbrewPdf('sk-your-api-key');
const result = await pdf.fromHtml('<h1>Hello</h1>');
console.log(result.data.download_url);Python
from funbrew_pdf import FunbrewPdf
pdf = FunbrewPdf("sk-your-api-key")
result = pdf.from_html("<h1>Hello</h1>")
print(result["data"]["download_url"])CLI
npm install -g @funbrew/pdf-cli fbpdf config set-key sk-your-api-key fbpdf html "<h1>Hello</h1>" -o hello.pdf
Authentication
All API requests require an API key. Include it as a Bearer Token in the request header.
Authorization: Bearer sk-your-api-key
X-API-Key You can also authenticate via the X-API-Key header or the ?api_key=... query parameter.
API keys can be issued from the dashboard. The key is shown only once at creation — store it securely.
Client / Project Grouping
Each API key can carry a client name and tags. Useful for agencies, contractors, and SaaS resellers running multiple customers or projects through one account — generated PDFs, API logs, and usage can all be filtered and aggregated per client.
When to use client_label vs tags
client_label | tags | |
|---|---|---|
| Count | Exactly one | Multiple allowed |
| Role | Primary axis for billing and aggregation | Sub-classification (environment, use case, etc.) |
| Example | Acme Inc | production, invoice-pdf |
| CSV export | Included as the client_label column (invoice evidence) | Not exported today — dashboard-only |
Rule of thumb: "unit you want to split invoices by" goes in client_label; everything else is a tag.
Use cases
- Reseller agencies: issue a dedicated key per client, filter PDF lists and API logs by client, and export CSV per client for invoice allocation.
- Multi-tenant SaaS: bundle keys per tenant, then add environment tags (production / staging / dev) for finer slicing.
- Contracted development: one key per project, so post-delivery support can pull only the relevant logs.
How to use
- Dashboard → API Keys → click "New key" or "Edit" on an existing key.
- Fill in the "Client / Project" field (e.g. Acme Inc) and optionally add tags (e.g. production, invoice-pdf).
- Filter PDF list and API log pages by the new "Client" dropdown. CSV exports include a client_label column.
Client names are up to 100 chars, each tag up to 50 chars. Grouping is purely a management label — it does not affect API behavior or billing.
PDF Engine Selection
FUNBREW PDF offers two rendering engines. The default is the Chromium-based high-quality engine.
| Value | Renderer | Speed | CSS Support |
|---|---|---|---|
"quality" | Gotenberg (Chromium) | Normal (1-3s) | CSS3 / Flexbox / Grid |
"fast" | wkhtmltopdf | Fast (0.5-2s) | CSS2.1 + partial CSS3 |
// Generate with Chromium engine (default)
{
"html": "<div style='display:flex'>...</div>",
"options": { "engine": "quality" }
}When engine is not specified, quality (Chromium) is used. Use engine=fast for high-throughput batch generation.
Image formats: JPEG, PNG and GIF work on both engines. WebP and AVIF render only on the quality (Chromium) engine — they are not supported by the fast (wkhtmltopdf) engine.
Rate Limiting
API requests are subject to per-minute rate limits based on your plan.
| Plan | Limit |
|---|---|
| Free | 10 req/min |
| Starter | 30 req/min |
| Basic | 60 req/min |
| Standard | 120 req/min |
| Enterprise | Unlimited |
Response Headers
All API responses include the following headers.
| Header | Description |
|---|---|
X-RateLimit-Limit | Per-minute request limit |
X-RateLimit-Remaining | Remaining requests |
X-RateLimit-Reset | Limit reset time (UNIX timestamp) |
When Exceeded
When the limit is exceeded, a 429 Too Many Requests response is returned. Wait for the number of seconds in the Retry-After header before retrying.
{
"success": false,
"message": "Rate limit exceeded. Please retry later.",
"retry_after": 42
}HTML → PDF
/api/pdf/generate-from-htmlGenerate a PDF from HTML content.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
html | string | o | HTML content (max 5MB) |
options.page-size | string | A3, A4, A5, Letter, Legal | |
options.orientation | string | Page orientation. "Portrait" (default) or "Landscape" | |
options.engine | string | PDF engine. "quality" (Chromium, default) or "fast" (wkhtmltopdf) | |
options.margin-* | number | top/right/bottom/left (mm, 0-50) | |
filename | string | Display filename for download | |
expiration_hours | integer | Expiry (1-168 hours, default 24) | |
max_downloads | integer | Max downloads (0-100, 0=unlimited, default 10) | |
watermark | string | Watermark text | |
email.to | string | Email recipient for PDF attachment | |
email.subject | string | Email subject | |
email.body | string | Email body |
Request Example
curl -X POST https://your-domain/api/pdf/generate-from-html \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Hello</h1>", "options": {"page-size": "A4"}}'Response
{
"success": true,
"data": {
"filename": "uuid.pdf",
"original_name": "請求書_2026年3月.pdf",
"download_url": "https://.../api/pdf/download/uuid.pdf",
"file_size": 45321,
"expires_at": "2026-03-21T12:00:00.000000Z",
"max_downloads": 10,
"remaining_downloads": 10
}
}URL → PDF
/api/pdf/generate-from-urlConvert a web page specified by URL to PDF.
| Name | Type | Required | Description |
|---|---|---|---|
url | string | o | Target URL (JS execution, HTTPS supported) |
filename | string | Display filename for download | |
options.* | Same as HTML → PDF | ||
email.* | Same as HTML → PDF |
Template → PDF
/api/pdf/generate-from-templateGenerate a PDF by injecting variables into a pre-registered template.
| Name | Type | Required | Description |
|---|---|---|---|
template | string | o | Template slug |
variables | object | Template variables {"name": "Taro"} | |
filename | string | Display filename for download | |
options.* | Same as HTML → PDF |
Markdown → PDF
/api/pdf/generate-from-markdownGenerate a styled PDF from Markdown text. Supports GFM (GitHub Flavored Markdown) including tables, code blocks, and checklists.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
markdown | string | o | Markdown text (max 5MB) |
theme | string | Theme name (business, modern, minimal, academic, creative). Default: business | |
filename | string | Display filename for download | |
options.* | Same as HTML → PDF | ||
email.* | Same as HTML → PDF |
Available Themes
| Theme | Description |
|---|---|
"business" | Business documents. Professional layout with muted colors |
"modern" | Modern design. Refined typography with accent colors |
"minimal" | Minimal design. Simple layout with generous whitespace |
"academic" | Academic papers. Serif fonts with paper-style layout |
"creative" | Creative. Colorful design with unique layout |
Request Example
curl -X POST https://your-domain/api/pdf/generate-from-markdown \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{"markdown": "# Hello World\n\nThis is **bold** text.", "theme": "modern"}'Related APIs
/api/markdown/themesList available themes (no authentication required).
/api/markdown/previewConvert Markdown to HTML for preview (no authentication required). Returns themed HTML output.
Batch Generation
/api/pdf/batchGenerate multiple PDFs asynchronously in batch.
| Name | Type | Required | Description |
|---|---|---|---|
items | array | o | Array of generation requests (max 100) |
items[].type | string | o | html or url |
items[].html | string | * | Required when type=html |
items[].url | string | * | Required when type=url |
/api/pdf/batch/{batch_id}Check batch progress status.
PDF Merge
/api/pdf/mergeMerge multiple existing PDFs into one.
| Name | Type | Required | Description |
|---|---|---|---|
filenames | array | o | Array of PDF filenames to merge (2-50) |
Upload & Merge
/api/pdf/merge-uploadUpload PDF files directly and merge them into one. You can also mix uploaded files with existing server files.
Content-Type: multipart/form-data
| Name | Type | Required | Description |
|---|---|---|---|
files[] | file | PDF files to upload (max 50MB each) | |
filenames[] | string | Existing server filenames to include in the merge |
At least 2 files in total (uploaded + server filenames) are required.
curl -X POST https://pdf.funbrew.cloud/api/pdf/merge-upload \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "files[]=@invoice1.pdf" \ -F "files[]=@invoice2.pdf"
Download
/api/pdf/download/{filename}Download a generated PDF. Increments the download count.
File Info
/api/pdf/info/{filename}Get PDF file metadata (size, remaining downloads, expiry, etc.).
File Delete
/api/pdf/delete/{filename}Delete a PDF file.
Template CRUD
/api/templatesList all templates.
/api/templatesCreate a template. Use variable placeholders in html_content.
| Name | Type | Required | Description |
|---|---|---|---|
name | string | o | Template name |
slug | string | o | Unique identifier (lowercase alphanumeric + hyphens) |
html_content | string | o | HTML template |
variables | array | Variable definitions [{"name": "x", "required": true}] |
/api/templates/{id}/api/templates/{id}Email Delivery
Send generated PDFs as email attachments. Two methods are available.
A) Specify in API request
Add the email parameter to your generation request to send the PDF as an attachment after generation.
curl -X POST https://your-domain/api/pdf/generate-from-html \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>請求書</h1>",
"email": {
"to": "customer@example.com",
"subject": "請求書をお送りします",
"body": "添付の請求書をご確認ください。"
}
}'B) Pre-configure in dashboard
Set up recipient, subject, and body templates in Email Notification Settings. Emails are sent automatically on every PDF generation.
The following placeholders can be used in subject and body:
| Placeholder | Content |
|---|---|
{{filename}} | Filename |
{{file_size}} | File size |
{{expires_at}} | Expiry date |
{{download_url}} | Download URL |
Webhook / Slack Notifications
/api/webhooks/api/webhooksRegister a webhook URL. Events are sent via POST.
| Name | Type | Required | Description |
|---|---|---|---|
url | string | o | Notification URL |
events | array | o | Events to notify (see below) |
Supported Events
| Event | Description |
|---|---|
pdf.generated | PDF generation complete |
pdf.downloaded | PDF downloaded |
pdf.expired | PDF expired |
batch.completed | Batch processing complete |
Slack Integration
When you specify a Slack Incoming Webhook URL, notifications are automatically formatted as Slack Block Kit messages with download buttons.
Webhook and Slack notifications can also be configured from the dashboard.
Signature Verification
Standard webhooks include a X-Webhook-Signature: sha256=HMAC(payload, secret) header.
Usage
/api/usageReturns current month's usage count, remaining quota, plan info, and enabled features.
S3 Storage Integration
Auto-upload generated PDFs to AWS S3 or S3-compatible services. When configured, PDFs are saved to both local and S3 storage, and the response includes an s3_url.
Configure from the dashboard. Also available via API:
/api/storage-config/api/storage-config/api/storage-config/api/storage-config| Name | Type | Required | Description |
|---|---|---|---|
driver | string | o | s3 |
config.bucket | string | o | Bucket name |
config.region | string | o | Region |
config.key | string | o | Access key ID |
config.secret | string | o | Secret access key |
config.endpoint | string | Custom endpoint (for S3-compatible services like Wasabi) |
Credentials are encrypted at rest on the server.
Error Codes
| Status | Meaning | Action |
|---|---|---|
401 | Authentication error | Check your API key |
403 | Forbidden / Feature not enabled | Upgrade your plan or check IP restrictions |
404 | Resource not found | Check the filename or ID |
422 | Validation error | Check request parameters |
429 | Monthly limit exceeded | Wait until next month or upgrade your plan |
500 | Server error | Contact support |
All error responses follow this format:
{ "success": false, "message": "Error description" }