Convert HTML content to PDF documents. This is the primary endpoint for generating PDFs from custom HTML templates, invoices, reports, and any HTML-based content.
Endpoint
POST /htmlToPdf
Authentication
Requires a valid API key or OAuth token in the Authorization header:
Authorization: Bearer YOUR_API_KEY
See Authentication for details.
Request Body
This endpoint accepts both JSON and multipart form data.
JSON Body
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
html | string | Yes | HTML content to convert to PDF |
css | string | No | Additional CSS styles to apply |
filename | string | No | Output filename (default: document.pdf) |
base_url | string | No | Base URL for resolving relative URLs in the HTML |
storage | object | No | Storage options for the generated PDF (see below) |
return_binary | boolean | No | Return PDF binary even when using storage (default: false) |
Multipart Form Data
Content-Type: multipart/form-data
For large HTML documents that may exceed JSON body limits, you can upload HTML as a file:
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | HTML file to convert to PDF |
css_file | file | No | CSS file with styles to apply |
html | string | No | HTML string (alternative to file upload) |
css | string | No | CSS string (alternative to css_file upload) |
filename | string | No | Output filename (default: document.pdf) |
base_url | string | No | Base URL for resolving relative URLs |
When uploading files, the file field takes priority over the html form field, and css_file takes priority over the css form field.
Field Details
html (required)
The HTML content to render as a PDF. Supports full HTML5 including:
- Semantic elements (
<header>,<section>,<article>, etc.) - Tables for data presentation
- Images (inline base64 or absolute URLs)
- Custom fonts via
@font-faceor CDN links - CSS Grid and Flexbox layouts
css (optional)
Additional CSS to apply to the document. If not provided, a default stylesheet is applied that includes page break handling for common elements like tables and rows.
Default CSS includes:
/* Prevent page breaks inside elements */
.no-break {
page-break-inside: avoid;
break-inside: avoid;
}
/* Force page break after element */
.page-break {
page-break-after: always;
break-after: page;
}
/* Table rows don't split across pages */
tr {
page-break-inside: avoid;
break-inside: avoid;
}
filename (optional)
The filename for the downloaded PDF. If not provided, defaults to document.pdf. The .pdf extension is automatically appended if not present.
base_url (optional)
Base URL for resolving relative URLs in your HTML (images, stylesheets, etc.). Useful when your HTML references assets with relative paths.
Storage Options
Control how the generated PDF is stored and returned.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storage.mode | string | No | memory | Storage mode: memory, default, or byob |
storage.filename | string | No | endpoint default | Custom filename (auto-suffixed with timestamp if duplicate) |
storage.expires_in | integer | No | 3600 | Signed URL expiry in seconds (60-604800) |
storage.retention_days | integer | No | 14 | Auto-delete document after N days (1-365) |
Storage Modes:
- memory: Return PDF bytes directly in response (no persistence). This is the default for REST API calls.
- default: Store in pdf-mcp S3 bucket, return JSON with document metadata and signed URL.
- byob: Store in your own S3 bucket (requires BYOB configuration).
See Storage Modes for a detailed guide on storage behavior, channel defaults, and the return_binary parameter.
Example Request
Basic HTML Conversion
curl -X POST https://api.pdf-mcp.io/htmlToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Hello, World!</h1><p>This is a PDF document.</p>"
}' \
--output document.pdf
Invoice with Custom CSS
curl -X POST https://api.pdf-mcp.io/htmlToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<!DOCTYPE html><html><head><title>Invoice</title></head><body><h1>Invoice #12345</h1><table><tr><th>Item</th><th>Amount</th></tr><tr><td>Service Fee</td><td>$99.00</td></tr></table><p>Total: $99.00</p></body></html>",
"css": "@page { size: A4; margin: 2cm; } body { font-family: Arial, sans-serif; } table { width: 100%; border-collapse: collapse; } th, td { border: 1px solid #ddd; padding: 8px; }",
"filename": "invoice-12345.pdf"
}' \
--output invoice-12345.pdf
HTML with External Assets
curl -X POST https://api.pdf-mcp.io/htmlToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<html><body><img src=\"/logo.png\"><h1>Report</h1></body></html>",
"base_url": "https://example.com/assets"
}' \
--output report.pdf
With Storage (Persistent PDF)
curl -X POST https://api.pdf-mcp.io/htmlToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Invoice #12345</h1><p>Amount Due: $99.00</p>",
"storage": {
"mode": "default",
"filename": "invoice-12345.pdf",
"expires_in": 86400,
"retention_days": 30
}
}'
File Upload (Multipart)
curl -X POST https://api.pdf-mcp.io/htmlToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@report.html" \
-F "css_file=@styles.css" \
-F "filename=report.pdf" \
--output report.pdf
Store and Return Binary
curl -X POST https://api.pdf-mcp.io/htmlToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Report</h1>",
"storage": { "mode": "default" },
"return_binary": true
}' \
--output report.pdf
The file is stored to S3 as normal, but the response is the binary PDF instead of JSON. Storage metadata is available in custom response headers (X-Document-Id, X-Storage-Mode, X-Storage-Url).
Response
Success (memory mode)
When storage.mode is memory or not provided, returns the PDF as a binary file download.
Headers:
Content-Type: application/pdf
Content-Disposition: attachment; filename="document.pdf"
Success (with storage)
When storage.mode is default or byob, returns JSON with document metadata and a signed download URL:
{
"success": true,
"document_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://s3.eu-central-1.amazonaws.com/...",
"filename": "invoice-12345.pdf",
"file_size_bytes": 45678,
"page_count": 3,
"storage_mode": "default",
"expires_at": "2024-02-15T10:30:00Z",
"signed_url_expires_at": "2024-01-15T12:00:00Z"
}
| Field | Type | Description |
|---|---|---|
success | boolean | Always true on success |
document_id | string | UUID of the stored document |
url | string | Presigned URL for downloading the PDF |
filename | string | Document filename |
file_size_bytes | integer | Size of the PDF in bytes |
page_count | integer | Number of pages in the PDF |
storage_mode | string | Storage mode used (default or byob) |
expires_at | string | Auto-deletion timestamp (ISO 8601), if retention is set |
signed_url_expires_at | string | Expiration time of the signed URL (ISO 8601) |
Error
{
"error": "Internal server error",
"message": "Error description"
}
Status Codes:
| Code | Description |
|---|---|
| 200 | Success - PDF returned or stored |
| 400 | Bad Request - Invalid input or BYOB not configured |
| 401 | Unauthorized - Missing or invalid Authorization header |
| 402 | Payment Required - Insufficient credits |
| 403 | Forbidden - Invalid API key or OAuth token |
| 500 | Internal Server Error - PDF generation failed |
| 502 | Bad Gateway - Storage operation failed (S3 upload or URL generation) |
Page Formatting
Page Size
Control page dimensions using the @page CSS rule:
@page {
size: A4; /* A4, Letter, Legal, etc. */
margin: 2cm; /* Page margins */
}
/* Or explicit dimensions */
@page {
size: 8.5in 11in; /* Width x Height */
}
Page Breaks
Control pagination with CSS:
<!-- Force page break before an element -->
<div style="page-break-before: always;">New page content</div>
<!-- Force page break after an element -->
<div style="page-break-after: always;">End of section</div>
<!-- Prevent page break inside an element -->
<div style="page-break-inside: avoid;">Keep together</div>
Headers and Footers
Use CSS @page rules for running headers/footers:
@page {
@top-center {
content: "Company Name";
}
@bottom-right {
content: "Page " counter(page) " of " counter(pages);
}
}
Tips and Best Practices
Performance
- Inline critical CSS to avoid external requests
- Use base64-encoded images for small graphics
- Keep HTML structure simple and semantic
Compatibility
- Use absolute URLs or set
base_urlfor external resources - Test with different page sizes for international documents
- Use web-safe fonts or embed fonts via
@font-face
Print Styling
- Add
@media printstyles for PDF-specific formatting - Use
page-break-inside: avoidfor elements that should stay together - Test with multi-page content to verify pagination
Related Endpoints
- Text to PDF - Convert plain text to PDF
- Image to PDF - Convert images to PDF
- Merge PDFs - Combine multiple PDFs
Credit Usage
Approximately 1 credit per page generated.