html-to-pdf

Convert an HTML file to a high-quality PDF using WeasyPrint rendering. Supports custom page sizes, margins, orientation, headers, footers, and grayscale output via pdf_options.


Endpoint

POST /v1/convert/html-to-pdf

Content-Type: multipart/form-data

Accepted input: .html or .htm files (UTF-8 encoded)

Output format: .pdf (application/pdf)


Authentication

Requires either a private API key or a JWT token from a public key.

X-API-Key: sk_live_your_private_key

Or:

Authorization: Bearer <jwt_token>

Request Parameters

Parameter Type Required Default Description
file file Yes -- The .html or .htm file to convert. Must be UTF-8 encoded.
output_filename string No Input filename Custom output filename. The .pdf extension is added automatically.
direct_download boolean No true When true, returns raw PDF bytes. When false, returns JSON metadata with a presigned download URL.
pdf_options string No null JSON string containing PDF configuration options. See below.

PDF Options

Pass as a JSON string in the pdf_options form field. All fields are optional.

Parameter Type Default Description
page_size string "A4" Named page size. Ignored when both page_width and page_height are set.
page_width float null Custom page width in millimeters. Both page_width and page_height must be set together.
page_height float null Custom page height in millimeters.
orientation string "portrait" "portrait" or "landscape".
margins object {"top": 10, "bottom": 10, "left": 10, "right": 10} Page margins in millimeters.
grayscale boolean false Convert the output to grayscale via Ghostscript post-processing.
header object null Page header. Format: {"content": "<text>", "height": 15}. Supports template variables.
footer object null Page footer. Same format as header.

Supported page sizes: A0, A1, A2, A3, A4, A5, A6, B0, B1, B2, B3, B4, B5, Letter, Legal, Tabloid, Ledger

Header/footer template variables: {{page}}, {{total_pages}}, {{date}}, {{title}}, {{url}}


Conversion Details

  • Uses WeasyPrint for CSS-based PDF rendering
  • The pdf_options are translated into CSS @page rules injected into the HTML before rendering
  • WeasyPrint respects the document's own CSS styles in addition to the injected page rules
  • All rendering is synchronous and server-side
Note: External resources referenced by URL in the HTML (images, stylesheets, fonts) may not resolve. For best results, use inline CSS and base64-encoded images, or ensure all resources are publicly accessible.

Response

Direct Download (direct_download=true, default)

HTTP 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="document_20260405_123456789.pdf"

Returns raw PDF bytes.

Metadata Response (direct_download=false)

{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/html-to-pdf/document_20260405_123456789.pdf",
    "filename": "document_20260405_123456789.pdf",
    "file_size": 45678,
    "conversion_time_seconds": 1.2
}

Code Examples

Python

import requests
import json

with open("report.html", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/html-to-pdf",
        headers={"X-API-Key": "sk_live_your_private_key"},
        files={"file": ("report.html", f, "text/html")},
        data={
            "pdf_options": json.dumps({
                "page_size": "A4",
                "orientation": "portrait",
                "margins": {"top": 20, "bottom": 20, "left": 15, "right": 15}
            })
        }
    )

with open("report.pdf", "wb") as out:
    out.write(response.content)

Node.js

const form = new FormData();
form.append("file", fs.createReadStream("report.html"));
form.append("pdf_options", JSON.stringify({
    page_size: "A4",
    orientation: "portrait",
    margins: { top: 20, bottom: 20, left: 15, right: 15 }
}));

const response = await fetch("https://api.enconvert.com/v1/convert/html-to-pdf", {
    method: "POST",
    headers: { "X-API-Key": "sk_live_your_private_key" },
    body: form
});

fs.writeFileSync("report.pdf", Buffer.from(await response.arrayBuffer()));

PHP

$ch = curl_init("https://api.enconvert.com/v1/convert/html-to-pdf");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_live_your_private_key"],
    CURLOPT_POSTFIELDS => [
        "file" => new CURLFile("report.html", "text/html"),
        "pdf_options" => json_encode([
            "page_size" => "A4",
            "margins" => ["top" => 20, "bottom" => 20, "left" => 15, "right" => 15]
        ])
    ]
]);
$pdf = curl_exec($ch);
curl_close($ch);
file_put_contents("report.pdf", $pdf);

Go

body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

part, _ := writer.CreateFormFile("file", "report.html")
file, _ := os.Open("report.html")
io.Copy(part, file)

writer.WriteField("pdf_options", `{"page_size":"A4","margins":{"top":20,"bottom":20,"left":15,"right":15}}`)
writer.Close()

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/html-to-pdf", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-API-Key", "sk_live_your_private_key")
resp, _ := http.DefaultClient.Do(req)

Error Responses

Status Condition
400 Bad Request File is not a .html or .htm file
400 Bad Request Invalid HTML encoding (expected UTF-8)
400 Bad Request HTML to PDF conversion failed
400 Bad Request Invalid pdf_options JSON
401 Unauthorized Missing or invalid API key / JWT token
402 Payment Required Monthly conversion limit reached
402 Payment Required Storage limit reached
413 Payload Too Large File exceeds plan's maximum file size

Limits

Limit Value
Max file size Plan-dependent (Free: 5 MB)
Input encoding UTF-8 only
Header/footer content 2000 characters max
Scale range 0.1 -- 2.0
Monthly conversions Plan-dependent