pdf-mcp Documentation
Browse documentation
Markdown

HTML to PDF

Request and response details for converting HTML to PDF with /htmlToPdf

On this page

Use /htmlToPdf to render HTML as a PDF. It is the primary endpoint for custom templates, invoices, reports, and other HTML-based documents.

Endpoint

Plain text
POST /htmlToPdf

Authentication

Send a valid API key or OAuth token in the Authorization header:

Plain text
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

FieldTypeRequiredDescription
htmlstringYesHTML content to convert to PDF
cssstringNoAdditional CSS styles to apply
filenamestringNoOutput filename (default: document.pdf)
base_urlstringNoBase URL for resolving relative URLs in the HTML
storageobjectNoStorage options for the generated PDF (see below)
return_binarybooleanNoReturn PDF binary even when using storage (default: false)

Multipart form data

Content-Type: multipart/form-data

Upload large HTML documents as files when they may exceed the JSON body limit:

FieldTypeRequiredDescription
filefileYesHTML file to convert to PDF
css_filefileNoCSS file with styles to apply
htmlstringNoHTML string (alternative to file upload)
cssstringNoCSS string (alternative to css_file upload)
filenamestringNoOutput filename (default: document.pdf)
base_urlstringNoBase 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 renderer supports full HTML5, including:

  • Semantic elements (<header>, <section>, <article>, etc.)
  • Tables for data presentation
  • Images (inline base64 or absolute URLs)
  • Custom fonts via @font-face or 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:

CSS
/* 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.

FieldTypeRequiredDefaultDescription
storage.modestringNomemoryStorage mode: memory, default, or byob
storage.filenamestringNoendpoint defaultCustom filename (auto-suffixed with timestamp if duplicate)
storage.expires_inintegerNo3600Signed URL expiry in seconds (60-604800)
storage.retention_daysintegerNo14Auto-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.


Request examples

Basic HTML conversion

Shell
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

Shell
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

Shell
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

Persistent storage

Shell
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
    }
  }'

Multipart file upload

Shell
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 the binary

Shell
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 API stores the file in S3 but returns the binary PDF instead of JSON. Custom response headers contain the storage metadata (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:

Plain text
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:

JSON
{
  "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"
}
FieldTypeDescription
successbooleanAlways true on success
document_idstringUUID of the stored document
urlstringPresigned URL for downloading the PDF
filenamestringDocument filename
file_size_bytesintegerSize of the PDF in bytes
page_countintegerNumber of pages in the PDF
storage_modestringStorage mode used (default or byob)
expires_atstringAuto-deletion timestamp (ISO 8601), if retention is set
signed_url_expires_atstringExpiration time of the signed URL (ISO 8601)

Error

JSON
{
  "error": "Internal server error",
  "message": "Error description"
}

Status codes:

CodeDescription
200Success - PDF returned or stored
400Bad Request - Invalid input or BYOB not configured
401Unauthorized - Missing or invalid Authorization header
402Payment Required - Insufficient credits
403Forbidden - Invalid API key or OAuth token
500Internal Server Error - PDF generation failed
502Bad Gateway - Storage operation failed (S3 upload or URL generation)

Page formatting

Page size

Control page dimensions using the @page CSS rule:

CSS
@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:

HTML
<!-- 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:

CSS
@page {
  @top-center {
    content: "Company Name";
  }
  @bottom-right {
    content: "Page " counter(page) " of " counter(pages);
  }
}

Implementation notes

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_url for external resources
  • Test with different page sizes for international documents
  • Use web-safe fonts or embed fonts via @font-face
  • Add @media print styles for PDF-specific formatting
  • Use page-break-inside: avoid for elements that should stay together
  • Test with multi-page content to verify pagination

Credit usage

The first page costs 1 credit. Each additional page costs 0.01 credits.