# HTML to PDF Converter – URL to PDF & Raw HTML, Bulk (`gazidev/html-to-pdf`) Actor

Convert HTML to PDF in bulk: web page URLs, raw HTML strings (invoices, receipts, reports) and HTML files to print-quality PDFs with headless Chrome. A4/Letter, margins, header/footer page numbers, cookie banners hidden, merge into one PDF. $4 per 1,000 PDFs.

- **URL**: https://apify.com/gazidev/html-to-pdf.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Categories:** Developer tools, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 pdf createds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## HTML to PDF Converter – URL to PDF & Raw HTML, Bulk

Convert **HTML to PDF** in bulk with real headless Chrome. Give it **web page URLs** (URL to PDF, website to PDF), **raw HTML strings** (invoices, receipts, reports, certificates) or links to **.html files**, and get print-quality PDFs with clickable links, selectable text, CSS backgrounds and web fonts. Set paper size, margins, landscape, scale, header and footer with page numbers, and optionally **merge everything into one PDF**.

**$4 per 1,000 PDFs.** Failed pages are free.

### What it does

- **URL to PDF:** opens each page in Chromium, hides cookie/consent banners, blocks ads and trackers, loads lazy images, and prints it with the page's print stylesheet (or as seen on screen).
- **HTML to PDF:** renders your HTML string exactly like a browser would: CSS, flexbox/grid, Google Fonts, remote or base64 images, `@page` rules, `page-break-*`. Add `baseUrl` so relative links resolve.
- **Page layout:** A4, Letter, Legal, A3, A5, Tabloid or custom width × height; portrait or landscape; margins; scale 0.1–2; page ranges like `1-3,5`; CSS `@page size` support.
- **Header and footer templates** with `pageNumber`, `totalPages`, `date`, `title` and `url` placeholders, e.g. "Page 2 of 7".
- **Wait controls:** `waitUntil` (load, networkidle, ...), `waitForSelector` and an extra delay for charts and JavaScript-rendered pages.
- **Merge into one PDF** in input order, and custom file names (`{index}`, `{name}`, `{title}`, `{host}`, `{date}`).
- Every PDF gets a public download link, its page count and size.

### Use cases

- Generate **invoice PDFs**, receipts, quotes, tickets and certificates from HTML templates (Make, Zapier, n8n or your backend calls the API).
- Archive web pages, articles, documentation or terms of service as PDF (compliance, legal evidence, research).
- Turn reports and dashboards into printable, shareable PDFs.
- Bulk **website to PDF** for offline reading or for feeding PDFs into AI / RAG pipelines.
- Bundle many pages into one PDF document (e.g. a whole docs section).

### Input example

```json
{
  "urls": ["https://example.com", "https://en.wikipedia.org/wiki/PDF"],
  "htmlItems": [
    { "name": "invoice-1001", "html": "<html><body><h1>INVOICE</h1><p>Total: $1,680.00</p></body></html>" },
    "<h1>Plain HTML strings work too</h1>",
    { "name": "report", "html": "<img src='/static/images/icons/wikipedia.png'>", "baseUrl": "https://en.wikipedia.org/" }
  ],
  "pageFormat": "A4",
  "landscape": false,
  "margins": { "top": "10mm", "right": "10mm", "bottom": "10mm", "left": "10mm" },
  "printBackground": true,
  "footerTemplate": "<div style=\"font-size:9px;width:100%;text-align:center\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>",
  "emulateMedia": "print",
  "hideCookieBanners": true,
  "mergeIntoOnePdf": true,
  "fileNameTemplate": "{index}-{name}"
}
```

Run it with no input and it converts a demo (two web pages and a sample invoice), so you can see the result in one click.

### Output example

One dataset row per document (plus one `merged` row when merging). PDFs are stored in the run's key-value store.

```json
{
  "type": "document",
  "source": "Invoice 1001",
  "sourceType": "html",
  "status": "success",
  "pageCount": 1,
  "sizeBytes": 52806,
  "pdfUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/0004-invoice-inv-1001.pdf",
  "title": "Invoice INV-1001",
  "fileName": "0004-invoice-inv-1001.pdf",
  "pageFormat": "Letter",
  "renderTimeMs": 720,
  "warning": null,
  "error": null
}
```

Failed documents have `"status": "failed"` and an `error` message (for example `DNS lookup failed`, `Server answered HTTP 404`, `waitForSelector '#chart' did not appear`). They are **not charged**. The `OUTPUT` record holds a run summary with the merged PDF link.

### Pricing

Pay per event: **$0.004 per PDF** generated, **$0.002 per merged PDF** (only if you turn merging on), $0.00005 per run start. No monthly fee; errors, retries and duplicates are free. You can cap a run with "Max total charge" and it stops cleanly at the limit.

| Actor (Apify Store) | Users (30 days) | Price per PDF |
|---|---|---|
| apify/html-to-pdf-converter | 9 | free (you pay platform usage) |
| rainminer/html-to-pdf-converter | 8 | $0.01 |
| automation-lab/html-to-pdf-converter | 8 | - |
| rainminer/url-to-pdf-converter | 3 | $0.015 |
| lexis-solution url-to-pdf | - | $0.025 |
| weio/website-to-pdf-bulk | - | $0.004 |
| **This Actor** | - | **$0.004** (URLs + raw HTML, merge, header/footer) |

1,000 invoices or web pages = $3.

### FAQ

**Can I convert HTML that is not online?** Yes. Paste it into `htmlItems` as a string or `{name, html}` object. Use `baseUrl` if it references relative images or CSS.

**How do I add page numbers?** Put `<span class="pageNumber"></span> / <span class="totalPages"></span>` in `footerTemplate`. Set a font size inline: Chromium's default template font is tiny. Images in templates must be base64 `data:` URIs.

**Why does the PDF look different from the website?** By default the page's **print** stylesheet is used (menus and ads are often hidden). Set `emulateMedia` to `screen` to get the on-screen look.

**A chart or table is missing.** Use `waitForSelector` (e.g. `canvas`) or `delayMs`, or set `waitUntil` to `networkidle`.

**Are pages behind a login supported?** No. Only public pages and HTML you provide. Pages answering 4xx/5xx are skipped for free unless you turn on `convertErrorPages`.

**Does it accept cookies or click banners?** No. Cookie banners are hidden with CSS; nothing is clicked or accepted.

**Is my HTML private?** It is rendered inside your own Apify run; PDFs are stored in your run's storage. Local files on the server cannot be read (`file:` URLs are blocked).

**What about very long pages?** Long pages become multi-page PDFs (e.g. a Wikipedia article = 25 A4 pages). Use `pageRanges` to keep only some pages, and `scale` to fit wide layouts.

### Use with AI agents / Apify MCP

This Actor works as a tool for AI agents via the [Apify MCP server](https://mcp.apify.com) (Claude, ChatGPT, Cursor, n8n, LangChain). An agent can call it with `{"urls": [...]}` or `{"htmlItems": [{"name": "...", "html": "..."}]}` and returns the `pdfUrl` links, e.g. "generate a PDF invoice from this HTML" or "save these 20 articles as PDFs and merge them". For synchronous use, call the `run-sync-get-dataset-items` API endpoint and read `pdfUrl` from the response.

# Actor input Schema

## `urls` (type: `array`):

Web pages (or links to .html files) to convert to PDF, one per line. `https://` is added if missing; duplicates are skipped. Leave empty if you only convert raw HTML below.

## `htmlItems` (type: `array`):

HTML strings to convert, e.g. invoices, receipts, reports, certificates. Each item is either an object `{"name": "invoice-1001", "html": "<html>...</html>"}` or a plain HTML string. Optional per item: `baseUrl` (so relative image/CSS links resolve) or `url` instead of `html` (an HTML file link). CSS, web fonts and inline/remote images are supported.

## `pageFormat` (type: `string`):

Paper format of the PDF. `custom` uses the width and height below.

## `customWidth` (type: `string`):

Only for paper size `custom`. Units: mm, cm, in or px, e.g. `100mm` or `4in`.

## `customHeight` (type: `string`):

Only for paper size `custom`, e.g. `150mm` or `6in`.

## `landscape` (type: `boolean`):

Rotate the paper to landscape orientation.

## `margins` (type: `object`):

Page margins as CSS lengths (mm, cm, in, px). Header/footer templates are printed inside the top/bottom margin, so those are raised to at least 15mm when a template is used.

## `printBackground` (type: `boolean`):

Keep CSS background colors and images (recommended for invoices and designed pages).

## `scale` (type: `number`):

Zoom of the page content, 0.1 to 2. Use 0.8 to fit wide pages.

## `pageRanges` (type: `string`):

Only print these pages, e.g. `1-3, 5`. Empty = all pages.

## `preferCssPageSize` (type: `boolean`):

If the HTML defines `@page { size: ... }`, use it instead of the paper size above.

## `headerTemplate` (type: `string`):

HTML printed at the top of every page. Chromium fills these classes: `pageNumber`, `totalPages`, `date`, `title`, `url`, e.g. `<span class="title"></span>`. Set a font size inline (default is tiny), e.g. `<div style="font-size:9px;width:100%;text-align:center">...</div>`. Images must be data: URIs. Empty = no header.

## `footerTemplate` (type: `string`):

HTML printed at the bottom of every page, same classes as the header. The prefilled example prints `Page 1 of 3`. Empty = no footer.

## `emulateMedia` (type: `string`):

`print` uses the site's print stylesheet (cleaner, usually no menus/ads). `screen` makes the PDF look like the page in the browser.

## `waitUntil` (type: `string`):

When the page counts as loaded. `load` (default) also waits up to 2 s for network idle. Use `networkidle` for single-page apps.

## `waitForSelector` (type: `string`):

Optional. Wait until this element exists before printing, e.g. `#chart canvas` or `.invoice-ready`. If it never appears, that document gets a free error row.

## `delayMs` (type: `integer`):

Wait this long after loading, before printing (charts, animations). 0–30000.

## `hideCookieBanners` (type: `boolean`):

Hide cookie/consent popups on web pages (nothing is clicked or accepted).

## `blockAds` (type: `boolean`):

Block common ad and analytics domains. Faster and cleaner PDFs.

## `scrollToLoad` (type: `boolean`):

Scroll through web pages and switch lazy images to eager so they appear in the PDF.

## `navigationTimeoutSecs` (type: `integer`):

Seconds to wait for a page to load. Slow pages are printed as rendered so far.

## `convertErrorPages` (type: `boolean`):

By default, pages that answer HTTP 4xx/5xx (404 Not Found, 403 bot walls, 500 errors) are not converted and get a free error row. Turn on to print them anyway (charged).

## `mergeIntoOnePdf` (type: `boolean`):

Additionally create one combined PDF of all documents, in input order (URLs first, then HTML items). Charged as one extra `merged-pdf` event.

## `mergedFileName` (type: `string`):

File name of the merged PDF (without .pdf).

## `fileNameTemplate` (type: `string`):

File name for each PDF in the key-value store. Placeholders: `{index}`, `{name}` (HTML item name or URL slug), `{title}` (document title), `{host}`, `{date}`. `.pdf` is added.

## `maxItems` (type: `integer`):

Stop after this many documents (0 = no limit).

## `maxConcurrency` (type: `integer`):

Documents converted at the same time. Lowered automatically to fit the run's memory.

## `maxRetries` (type: `integer`):

Retries after a load error or timeout.

## `ignoreHttpsErrors` (type: `boolean`):

Convert pages with self-signed or expired certificates.

## Actor input object example

```json
{
  "urls": [
    "https://example.com",
    "https://en.wikipedia.org/wiki/PDF"
  ],
  "htmlItems": [
    {
      "name": "invoice-1001",
      "html": "<!doctype html>\n<html><head><meta charset=\"utf-8\"><title>Invoice INV-1001</title>\n<style>\n  body { font-family: Helvetica, Arial, sans-serif; color: #222; margin: 0; }\n  .top { display: flex; justify-content: space-between; align-items: flex-start; }\n  h1 { color: #1a56db; margin: 0 0 4px; }\n  .muted { color: #666; font-size: 13px; }\n  table { width: 100%; border-collapse: collapse; margin-top: 28px; }\n  th { background: #1a56db; color: #fff; text-align: left; padding: 8px; }\n  td { padding: 8px; border-bottom: 1px solid #ddd; }\n  td.n, th.n { text-align: right; }\n  .total { font-size: 18px; font-weight: bold; text-align: right; margin-top: 18px; }\n</style></head>\n<body>\n  <div class=\"top\">\n    <div><h1>INVOICE</h1><div class=\"muted\">INV-1001 &middot; 2026-10-11</div></div>\n    <div class=\"muted\" style=\"text-align:right\">Acme Studio Ltd.<br>12 Example Street<br>London, UK</div>\n  </div>\n  <p><b>Bill to:</b> Jane Doe, Example Corp</p>\n  <table>\n    <tr><th>Item</th><th class=\"n\">Qty</th><th class=\"n\">Price</th><th class=\"n\">Amount</th></tr>\n    <tr><td>Website design</td><td class=\"n\">1</td><td class=\"n\">$1,200.00</td><td class=\"n\">$1,200.00</td></tr>\n    <tr><td>Hosting (12 months)</td><td class=\"n\">12</td><td class=\"n\">$15.00</td><td class=\"n\">$180.00</td></tr>\n    <tr><td>Support hours</td><td class=\"n\">5</td><td class=\"n\">$60.00</td><td class=\"n\">$300.00</td></tr>\n  </table>\n  <div class=\"total\">Total due: $1,680.00</div>\n  <p class=\"muted\">Payment within 14 days. Thank you for your business!</p>\n</body></html>"
    }
  ],
  "pageFormat": "A4",
  "customWidth": "",
  "customHeight": "",
  "landscape": false,
  "margins": {
    "top": "10mm",
    "right": "10mm",
    "bottom": "10mm",
    "left": "10mm"
  },
  "printBackground": true,
  "scale": 1,
  "pageRanges": "",
  "preferCssPageSize": false,
  "headerTemplate": "",
  "footerTemplate": "<div style=\"font-size:9px;width:100%;text-align:center;color:#666;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>",
  "emulateMedia": "print",
  "waitUntil": "load",
  "waitForSelector": "",
  "delayMs": 0,
  "hideCookieBanners": true,
  "blockAds": true,
  "scrollToLoad": true,
  "navigationTimeoutSecs": 45,
  "convertErrorPages": false,
  "mergeIntoOnePdf": false,
  "mergedFileName": "merged",
  "fileNameTemplate": "{index}-{name}",
  "maxItems": 0,
  "maxConcurrency": 3,
  "maxRetries": 1,
  "ignoreHttpsErrors": false
}
```

# Actor output Schema

## `pdfs` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `files` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://example.com",
        "https://en.wikipedia.org/wiki/PDF"
    ],
    "htmlItems": [
        {
            "name": "invoice-1001",
            "html": "<!doctype html>\n<html><head><meta charset=\"utf-8\"><title>Invoice INV-1001</title>\n<style>\n  body { font-family: Helvetica, Arial, sans-serif; color: #222; margin: 0; }\n  .top { display: flex; justify-content: space-between; align-items: flex-start; }\n  h1 { color: #1a56db; margin: 0 0 4px; }\n  .muted { color: #666; font-size: 13px; }\n  table { width: 100%; border-collapse: collapse; margin-top: 28px; }\n  th { background: #1a56db; color: #fff; text-align: left; padding: 8px; }\n  td { padding: 8px; border-bottom: 1px solid #ddd; }\n  td.n, th.n { text-align: right; }\n  .total { font-size: 18px; font-weight: bold; text-align: right; margin-top: 18px; }\n</style></head>\n<body>\n  <div class=\"top\">\n    <div><h1>INVOICE</h1><div class=\"muted\">INV-1001 &middot; 2026-10-11</div></div>\n    <div class=\"muted\" style=\"text-align:right\">Acme Studio Ltd.<br>12 Example Street<br>London, UK</div>\n  </div>\n  <p><b>Bill to:</b> Jane Doe, Example Corp</p>\n  <table>\n    <tr><th>Item</th><th class=\"n\">Qty</th><th class=\"n\">Price</th><th class=\"n\">Amount</th></tr>\n    <tr><td>Website design</td><td class=\"n\">1</td><td class=\"n\">$1,200.00</td><td class=\"n\">$1,200.00</td></tr>\n    <tr><td>Hosting (12 months)</td><td class=\"n\">12</td><td class=\"n\">$15.00</td><td class=\"n\">$180.00</td></tr>\n    <tr><td>Support hours</td><td class=\"n\">5</td><td class=\"n\">$60.00</td><td class=\"n\">$300.00</td></tr>\n  </table>\n  <div class=\"total\">Total due: $1,680.00</div>\n  <p class=\"muted\">Payment within 14 days. Thank you for your business!</p>\n</body></html>"
        }
    ],
    "pageFormat": "A4",
    "margins": {
        "top": "10mm",
        "right": "10mm",
        "bottom": "10mm",
        "left": "10mm"
    },
    "footerTemplate": "<div style=\"font-size:9px;width:100%;text-align:center;color:#666;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>",
    "fileNameTemplate": "{index}-{name}"
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/html-to-pdf").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "urls": [
        "https://example.com",
        "https://en.wikipedia.org/wiki/PDF",
    ],
    "htmlItems": [{
            "name": "invoice-1001",
            "html": """<!doctype html>
<html><head><meta charset=\"utf-8\"><title>Invoice INV-1001</title>
<style>
  body { font-family: Helvetica, Arial, sans-serif; color: #222; margin: 0; }
  .top { display: flex; justify-content: space-between; align-items: flex-start; }
  h1 { color: #1a56db; margin: 0 0 4px; }
  .muted { color: #666; font-size: 13px; }
  table { width: 100%; border-collapse: collapse; margin-top: 28px; }
  th { background: #1a56db; color: #fff; text-align: left; padding: 8px; }
  td { padding: 8px; border-bottom: 1px solid #ddd; }
  td.n, th.n { text-align: right; }
  .total { font-size: 18px; font-weight: bold; text-align: right; margin-top: 18px; }
</style></head>
<body>
  <div class=\"top\">
    <div><h1>INVOICE</h1><div class=\"muted\">INV-1001 &middot; 2026-10-11</div></div>
    <div class=\"muted\" style=\"text-align:right\">Acme Studio Ltd.<br>12 Example Street<br>London, UK</div>
  </div>
  <p><b>Bill to:</b> Jane Doe, Example Corp</p>
  <table>
    <tr><th>Item</th><th class=\"n\">Qty</th><th class=\"n\">Price</th><th class=\"n\">Amount</th></tr>
    <tr><td>Website design</td><td class=\"n\">1</td><td class=\"n\">$1,200.00</td><td class=\"n\">$1,200.00</td></tr>
    <tr><td>Hosting (12 months)</td><td class=\"n\">12</td><td class=\"n\">$15.00</td><td class=\"n\">$180.00</td></tr>
    <tr><td>Support hours</td><td class=\"n\">5</td><td class=\"n\">$60.00</td><td class=\"n\">$300.00</td></tr>
  </table>
  <div class=\"total\">Total due: $1,680.00</div>
  <p class=\"muted\">Payment within 14 days. Thank you for your business!</p>
</body></html>""",
        }],
    "pageFormat": "A4",
    "margins": {
        "top": "10mm",
        "right": "10mm",
        "bottom": "10mm",
        "left": "10mm",
    },
    "footerTemplate": "<div style=\"font-size:9px;width:100%;text-align:center;color:#666;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>",
    "fileNameTemplate": "{index}-{name}",
}

# Run the Actor and wait for it to finish
run = client.actor("gazidev/html-to-pdf").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://example.com",
    "https://en.wikipedia.org/wiki/PDF"
  ],
  "htmlItems": [
    {
      "name": "invoice-1001",
      "html": "<!doctype html>\\n<html><head><meta charset=\\"utf-8\\"><title>Invoice INV-1001</title>\\n<style>\\n  body { font-family: Helvetica, Arial, sans-serif; color: #222; margin: 0; }\\n  .top { display: flex; justify-content: space-between; align-items: flex-start; }\\n  h1 { color: #1a56db; margin: 0 0 4px; }\\n  .muted { color: #666; font-size: 13px; }\\n  table { width: 100%; border-collapse: collapse; margin-top: 28px; }\\n  th { background: #1a56db; color: #fff; text-align: left; padding: 8px; }\\n  td { padding: 8px; border-bottom: 1px solid #ddd; }\\n  td.n, th.n { text-align: right; }\\n  .total { font-size: 18px; font-weight: bold; text-align: right; margin-top: 18px; }\\n</style></head>\\n<body>\\n  <div class=\\"top\\">\\n    <div><h1>INVOICE</h1><div class=\\"muted\\">INV-1001 &middot; 2026-10-11</div></div>\\n    <div class=\\"muted\\" style=\\"text-align:right\\">Acme Studio Ltd.<br>12 Example Street<br>London, UK</div>\\n  </div>\\n  <p><b>Bill to:</b> Jane Doe, Example Corp</p>\\n  <table>\\n    <tr><th>Item</th><th class=\\"n\\">Qty</th><th class=\\"n\\">Price</th><th class=\\"n\\">Amount</th></tr>\\n    <tr><td>Website design</td><td class=\\"n\\">1</td><td class=\\"n\\">$1,200.00</td><td class=\\"n\\">$1,200.00</td></tr>\\n    <tr><td>Hosting (12 months)</td><td class=\\"n\\">12</td><td class=\\"n\\">$15.00</td><td class=\\"n\\">$180.00</td></tr>\\n    <tr><td>Support hours</td><td class=\\"n\\">5</td><td class=\\"n\\">$60.00</td><td class=\\"n\\">$300.00</td></tr>\\n  </table>\\n  <div class=\\"total\\">Total due: $1,680.00</div>\\n  <p class=\\"muted\\">Payment within 14 days. Thank you for your business!</p>\\n</body></html>"
    }
  ],
  "pageFormat": "A4",
  "margins": {
    "top": "10mm",
    "right": "10mm",
    "bottom": "10mm",
    "left": "10mm"
  },
  "footerTemplate": "<div style=\\"font-size:9px;width:100%;text-align:center;color:#666;\\">Page <span class=\\"pageNumber\\"></span> of <span class=\\"totalPages\\"></span></div>",
  "fileNameTemplate": "{index}-{name}"
}' |
apify call gazidev/html-to-pdf --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/html-to-pdf"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AWT9h2nfLH3UxK5S3/builds/AFXmhRFdognt7TUHe/openapi.json
