# Markdown to PDF & Word: Reports with Diagrams, Math & Tables (`jumblemog/markdown-to-pdf`) Actor

Convert Markdown to PDF, Word (DOCX) or HTML with tables, code highlighting, Mermaid diagrams, LaTeX math, a table of contents and page numbers. Built for AI agents and automations: send Markdown or links, get file links back.

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

## Pricing

Pay per event

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

## Markdown to PDF & Word: Reports with Diagrams, Math & Tables

**Turn Markdown into polished PDF, Word and HTML documents.** Send Markdown text or links to `.md` files and get back download links for a **PDF**, an editable **Word (DOCX)** file or a standalone **HTML** page, with tables, highlighted code, **Mermaid diagrams**, **LaTeX math**, task lists, footnotes, GitHub alerts, a table of contents and page numbers. Built for AI agents and automations that write Markdown and need a real document to send, attach or archive. Many documents per run, pay per document, and failed ones are free.

![A Markdown report with a table, a Mermaid flowchart, a formula and code, next to the PDF and the Word file this Actor made from it](https://api.apify.com/v2/key-value-stores/Km5b4PG3kYHdZSb1E/records/markdown-to-pdf-example.png?signature=1kxx7eAIlRnTOrDsrlBaa)

### What it does

- **GitHub-style Markdown**: headings, lists, tables with column alignment, task lists, footnotes, definition lists, strikethrough, emoji shortcodes such as `:rocket:`, GitHub alerts (`> [!NOTE]`, `> [!WARNING]` and the others), and YAML front matter with `title`, `subtitle`, `author` and `date` for a title block.
- **Mermaid diagrams**: ` ```mermaid ` blocks become real diagrams, sharp vector graphics in PDF and HTML and pictures in Word. Flowcharts, sequence, class, state, ER and Gantt diagrams, mindmaps, timelines and the other types built into Mermaid 12.2. If a diagram has a mistake, it's shown as code and the run tells you Mermaid's exact error.
- **LaTeX math**: `$inline$` and `$$display$$` formulas, and also `\( \)`, `\[ \]` and bare `\begin{align}` blocks, the way ChatGPT, Claude and other models usually write them. PDF and HTML get crisp vector formulas (MathJax), and Word gets native, editable Word equations.
- **Code highlighting** for over 100 languages.
- **Three formats from one input**:
  - **PDF**: A4, Letter, Legal, A5 or Tabloid, portrait or landscape, three margin sizes, page numbers ("3 / 12").
  - **Word (DOCX)**: real headings, lists, tables, equations and pictures, so it opens and edits cleanly in Microsoft Word, Google Docs and LibreOffice.
  - **HTML**: one self-contained file with the diagrams and formulas inline and no scripts.
- **Themes**: Default (clean sans-serif), Serif report and Compact, any font size from 8 to 16 pt, and your own CSS on top for brand colors and fonts.
- **Table of contents** built from the headings, on its own page.
- **Page breaks** where you want them: a line with `\newpage` or `\pagebreak`, or `<div style="page-break-after: always"></div>`.
- **Links to Markdown files**: direct links, GitHub and GitLab file pages, Google Drive and Dropbox share links. Relative images load from next to the file, so a GitHub README comes out with its logo and screenshots.
- **Images from the web** (PNG, JPEG, GIF, WebP, SVG). In Word files, SVG images such as badges and logos are turned into PNG so every Word version shows them.
- **Safe with untrusted Markdown**: raw HTML is kept for layout (centered logos, `<details>` sections, which are opened in the PDF), but scripts, frames, embedded objects and event attributes are removed, and local files are never read.
- **Batch conversion**: send a list of documents, each with its own name, and get one result per document.
- **The file straight from the API**: the first file is also the run's `OUTPUT`, so the run-sync endpoint answers with the PDF itself.
- **No outside services**: pandoc, Mermaid and MathJax run inside the Actor, so your documents aren't sent to a third-party conversion API.

### Who it's for

- **AI agents and LLM apps** that write reports, summaries, proposals, meeting notes or research in Markdown and need to hand over a PDF or Word file.
- **Automation builders** in n8n, Make or Zapier who turn data into weekly reports, client updates, handouts or archives.
- **Developers** who want docs, READMEs and changelogs as PDF or Word without installing pandoc, LaTeX, Chromium or Mermaid CLI.
- **Students, teachers and writers** with notes full of formulas and diagrams.

### How to use it

1. Paste your Markdown into **Markdown**, or add links in **Links to Markdown files**.
2. Pick the formats (PDF by default) and, if you like, a theme, page size and table of contents.
3. Click **Start**. Each document appears in the **Output** tab with its download links.

You can also run it through the [Apify API](https://docs.apify.com/api/v2), on a schedule, or from Make, n8n, Zapier and other integrations.

### Input

| Field | What it does |
| --- | --- |
| `markdown` | One document in Markdown. |
| `markdownUrls` | Links to Markdown files: direct links, GitHub or GitLab file pages, Google Drive or Dropbox share links. |
| `documents` | More documents: a list of Markdown strings, or objects with `markdown` or `url` and an optional `name`. |
| `formats` | Any of `pdf` (default), `docx` and `html`. Each document is saved in all of them. |
| `theme` | `default`, `serif` or `compact`. |
| `pageSize` | `A4` (default), `Letter`, `Legal`, `A5` or `Tabloid`. |
| `landscape` | `true` for landscape pages (default `false`). |
| `margins` | `normal` (18 mm, default), `narrow` (12 mm) or `wide` (25 mm). |
| `fontSize` | Body text size in points, 8 to 16 (default 11). |
| `tableOfContents` | `true` adds a table of contents built from the headings (default `false`). |
| `pageNumbers` | Page numbers at the bottom of PDF pages (default `true`). |
| `customCss` | Your own CSS for PDF and HTML, added after the theme. |
| `maxDocuments` | Stop after this many documents (default 100). |

Example with a batch:

```json
{
  "formats": ["pdf", "docx"],
  "theme": "serif",
  "tableOfContents": true,
  "documents": [
    {"name": "weekly-report", "markdown": "---\ntitle: Weekly Report\nauthor: Ops agent\ndate: 2026-10-23\n---\n\n## Highlights\n\n- Uptime **99.98%**\n- p95 latency $\\approx 120$ ms"},
    {"name": "crawlee-readme", "url": "https://github.com/apify/crawlee/blob/master/README.md"}
  ],
  "customCss": "h1, h2 { color: #0b5394; }"
}
```

### Output

Each document becomes one dataset item, and the files are saved in the run's key-value store:

```json
{
  "index": 1,
  "name": "weekly-report",
  "title": "Weekly Report",
  "status": "ok",
  "error": null,
  "warnings": [],
  "pdfUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/001-weekly-report.pdf?signature=...",
  "docxUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/001-weekly-report.docx?signature=...",
  "htmlUrl": null,
  "pdfSizeBytes": 61234,
  "docxSizeBytes": 11873,
  "pages": 2,
  "sourceUrl": null,
  "processingSeconds": 1.9
}
```

`warnings` lists anything that didn't come out as written but didn't stop the document, such as a Mermaid diagram with a mistake (shown as code instead) or an image that couldn't be downloaded:

```json
"warnings": ["Mermaid diagram 1 couldn't be drawn and is shown as code: Parse error on line 3: ...lowchart LR  A --> ---------------------^ Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'"]
```

A document that can't be read is reported with the reason, and isn't billed:

```json
{
  "index": 2,
  "status": "failed",
  "error": "The link returned 404 Not Found.",
  "sourceUrl": "https://example.com/missing.md",
  "pdfUrl": null
}
```

Download your files within your plan's data retention period, or copy them to your own storage, because run storage expires.

### Pricing

You pay per **document converted**, at the price shown on this page, whichever formats you ask for: a PDF, a Word file and an HTML page of the same document count as one. Documents that fail are never charged. If you set a maximum cost per run, the Actor stops when the next document wouldn't fit.

### Speed

Converting is quick: measured on Apify at the default 2 GB of memory, a batch of five documents saved as PDF, Word and HTML (a report with a Mermaid diagram and a formula, a GitHub README with its logo and badges, a Chinese and Japanese note, and two short documents) took 10 seconds of work in total once the run had started. A plain document takes about half a second, one with Mermaid diagrams 2 to 3 seconds, plus the time to download its images. Starting a run adds a few seconds, more when a server downloads the Actor for the first time. For many documents, one run with a batch is much quicker than one run per document.

### Tips and limits

- Word files follow Word's own styles rather than the theme or custom CSS, so they're easy to restyle in Word. Mermaid diagrams become pictures and formulas become Word equations. Raw HTML other than images and page breaks is left out of Word files.
- In Word files, the table of contents is a Word field that Word fills in when it opens the file; click **Yes** if it asks to update fields.
- Images have to be on the web (http or https). Images that don't load within 30 seconds are left out, with a warning.
- Chinese, Japanese and Korean text and emoji are supported.
- Web fonts work in custom CSS, for example `@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap'); :root { --font-body: Inter, sans-serif; }`. The themes read their fonts from `--font-body`, `--font-heading` and `--font-code`.
- Markdown can be up to 2,000,000 characters per document, and files from links up to 5 MB.

### For AI agents and developers

This Actor works with the [Apify MCP server](https://mcp.apify.com), so AI agents can call it as a tool: pass the Markdown in `markdown` (or a list in `documents`) and read `pdfUrl`, `docxUrl` or `htmlUrl` from each dataset item. Markdown can come straight from a model's answer, math and Mermaid included. For a direct API call that waits for the result:

```bash
curl -X POST "https://api.apify.com/v2/acts/jumblemog~markdown-to-pdf/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"markdown": "# Hello\n\nThis is **Markdown** with math: $e^{i\\pi} + 1 = 0$", "formats": ["pdf", "docx"]}'
```

To get the file itself as the response, call `run-sync` instead. It returns the run's `OUTPUT`, which is the first document in the first format you listed (or the error as JSON):

```bash
curl -X POST "https://api.apify.com/v2/acts/jumblemog~markdown-to-pdf/run-sync?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"markdown": "# Invoice notes\n\n| Item | Price |\n| --- | ---: |\n| Design | $400 |"}' \
  -o document.pdf
```

### Credits

- [pandoc](https://pandoc.org) (GPL-2.0-or-later, run as a separate program), [Mermaid](https://github.com/mermaid-js/mermaid) (MIT), [MathJax](https://www.mathjax.org) (Apache-2.0) and [librsvg](https://gitlab.gnome.org/GNOME/librsvg) (LGPL), with pages laid out and printed by headless Chromium through [Playwright](https://playwright.dev). This Actor isn't affiliated with these projects.

# Actor input Schema

## `markdown` (type: `string`):

The document in Markdown (GitHub style): headings, lists, tables, code, task lists, footnotes, \`\`\`mermaid diagrams, $math$ and $$display math$$, and YAML front matter with a title, author and date.

## `markdownUrls` (type: `array`):

Direct links to .md files, GitHub or GitLab file pages (converted to the raw file), or Google Drive and Dropbox share links. Relative images in these files are loaded from next to them.

## `documents` (type: `array`):

A list of documents to convert in the same run. Each entry is a Markdown string, or an object with "markdown" or "url" and an optional "name" for the file.

## `formats` (type: `array`):

pdf (default), docx for Microsoft Word, Google Docs and LibreOffice (with native Word equations), and html for a single self-contained web page.

## `theme` (type: `string`):

default: clean sans-serif. serif: a classic report or paper with justified text. compact: smaller headings and tighter spacing. Applies to PDF and HTML.

## `pageSize` (type: `string`):

Paper size of the PDF.

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

Turn PDF pages sideways, for wide tables.

## `margins` (type: `string`):

PDF page margins: normal (18 mm), narrow (12 mm) or wide (25 mm).

## `fontSize` (type: `integer`):

Body text size for PDF and HTML, from 8 to 16 points.

## `tableOfContents` (type: `boolean`):

Add a table of contents built from the headings, on its own page.

## `pageNumbers` (type: `boolean`):

Print page numbers ("3 / 12") at the bottom of PDF pages.

## `maxDocuments` (type: `integer`):

Stop after this many documents, so the cost of a run stays predictable.

## `customCss` (type: `string`):

Your own CSS for PDF and HTML output, added after the theme. For example brand colors: h1, h2 { color: #0b5394; } or a different font size for tables: table { font-size: 9pt; }. Word files keep the built-in styles.

## Actor input object example

````json
{
  "markdown": "# Quarterly Report: Q3 2026\n\n**Prepared by** the analytics agent, October 2026\n\n## Summary\n\nRevenue grew **18%** quarter over quarter, driven by the new self-serve plan.\n\n| Metric | Q2 | Q3 | Change |\n| --- | ---: | ---: | ---: |\n| Revenue | $1.20M | $1.42M | +18% |\n| New customers | 310 | 402 | +30% |\n| Churn | 3.1% | 2.6% | −0.5 pts |\n\n## How a visitor becomes a customer\n\n```mermaid\nflowchart LR\n  A[Visit] --> B[Free trial]\n  B --> C{Activated?}\n  C -->|Yes| D[Paid plan]\n  C -->|No| E[Nurture emails]\n  E --> B\n```\n\n## Forecast\n\nNext quarter's revenue is estimated with compound monthly growth:\n\n$$R_{t+3} = R_t \\times (1 + g)^{3}, \\quad g = 0.06$$\n\n```python\ndef forecast(revenue, growth=0.06, months=3):\n    return revenue * (1 + growth) ** months\n```\n\n> [!NOTE]\n> Figures are unaudited.\n\n## Next steps\n\n- [x] Launch the self-serve plan\n- [ ] Add annual billing\n",
  "formats": [
    "pdf"
  ],
  "theme": "default",
  "pageSize": "A4",
  "landscape": false,
  "margins": "normal",
  "fontSize": 11,
  "tableOfContents": false,
  "pageNumbers": true,
  "maxDocuments": 100
}
````

# Actor output Schema

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

One item per document: file links, title and page count, or the error.

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

The PDF, DOCX and HTML files saved in the run's key-value store.

# 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 = {
    "markdown": `# Quarterly Report: Q3 2026

**Prepared by** the analytics agent, October 2026

## Summary

Revenue grew **18%** quarter over quarter, driven by the new self-serve plan.

| Metric | Q2 | Q3 | Change |
| --- | ---: | ---: | ---: |
| Revenue | $1.20M | $1.42M | +18% |
| New customers | 310 | 402 | +30% |
| Churn | 3.1% | 2.6% | −0.5 pts |

## How a visitor becomes a customer

```mermaid
flowchart LR
  A[Visit] --> B[Free trial]
  B --> C{Activated?}
  C -->|Yes| D[Paid plan]
  C -->|No| E[Nurture emails]
  E --> B
````

## Forecast

Next quarter's revenue is estimated with compound monthly growth:

$R\_{t+3} = R_t \times (1 + g)^{3}, \quad g = 0.06$

```python
def forecast(revenue, growth=0.06, months=3):
    return revenue * (1 + growth) ** months
```

> \[!NOTE]
> Figures are unaudited.

## Next steps

- \[x] Launch the self-serve plan
- \[ ] Add annual billing\`
  };

// Run the Actor and wait for it to finish
const run = await client.actor("jumblemog/markdown-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 = { "markdown": """# Quarterly Report: Q3 2026

**Prepared by** the analytics agent, October 2026

## Summary

Revenue grew **18%** quarter over quarter, driven by the new self-serve plan.

| Metric | Q2 | Q3 | Change |
| --- | ---: | ---: | ---: |
| Revenue | $1.20M | $1.42M | +18% |
| New customers | 310 | 402 | +30% |
| Churn | 3.1% | 2.6% | −0.5 pts |

## How a visitor becomes a customer

```mermaid
flowchart LR
  A[Visit] --> B[Free trial]
  B --> C{Activated?}
  C -->|Yes| D[Paid plan]
  C -->|No| E[Nurture emails]
  E --> B
````

## Forecast

Next quarter's revenue is estimated with compound monthly growth:

$$R\_{t+3} = R_t \times (1 + g)^{3}, \quad g = 0.06$$

```python
def forecast(revenue, growth=0.06, months=3):
    return revenue * (1 + growth) ** months
```

> \[!NOTE]
> Figures are unaudited.

## Next steps

- \[x] Launch the self-serve plan
- \[ ] Add annual billing
  """ }

# Run the Actor and wait for it to finish

run = client.actor("jumblemog/markdown-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 '{
  "markdown": "# Quarterly Report: Q3 2026\\n\\n**Prepared by** the analytics agent, October 2026\\n\\n## Summary\\n\\nRevenue grew **18%** quarter over quarter, driven by the new self-serve plan.\\n\\n| Metric | Q2 | Q3 | Change |\\n| --- | ---: | ---: | ---: |\\n| Revenue | $1.20M | $1.42M | +18% |\\n| New customers | 310 | 402 | +30% |\\n| Churn | 3.1% | 2.6% | −0.5 pts |\\n\\n## How a visitor becomes a customer\\n\\n```mermaid\\nflowchart LR\\n  A[Visit] --> B[Free trial]\\n  B --> C{Activated?}\\n  C -->|Yes| D[Paid plan]\\n  C -->|No| E[Nurture emails]\\n  E --> B\\n```\\n\\n## Forecast\\n\\nNext quarter'\''s revenue is estimated with compound monthly growth:\\n\\n$$R_{t+3} = R_t \\\\times (1 + g)^{3}, \\\\quad g = 0.06$$\\n\\n```python\\ndef forecast(revenue, growth=0.06, months=3):\\n    return revenue * (1 + growth) ** months\\n```\\n\\n> [!NOTE]\\n> Figures are unaudited.\\n\\n## Next steps\\n\\n- [x] Launch the self-serve plan\\n- [ ] Add annual billing\\n"
}' |
apify call jumblemog/markdown-to-pdf --silent --output-dataset

````

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jumblemog/markdown-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/yAWxIcGL2u8soDr8M/builds/FHzpIdjFoggdvVz1y/openapi.json
