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

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

For large HTML documents that may exceed JSON body limits, you can upload HTML as a file:

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

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


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"
}
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

{
  "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:

@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_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

Approximately 1 credit per page generated.