Markdown-to-PDF API
This guide demonstrates how to convert Markdown content into professionally styled PDF documents using the Markdown-to-PDF API. Whether you’re generating reports from documentation, turning README files into shareable PDFs, or building a content pipeline that outputs print-ready documents, this API handles the conversion for you — complete with syntax-highlighted code blocks, GitHub Flavored Markdown(opens in a new tab) (GFM) tables, and a choice of built-in templates or completely custom HTML and CSS.
Quick start
Send a JSON request with inline Markdown to get a PDF back:
curl -X POST https://api.nutrient.io/processor/md_to_pdf \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "markdown": "# Hello World\n\nThis is **bold** and this is *italic*.\n\n- Item one\n- Item two\n\n> A blockquote" }' \ -o output.pdfPOST /processor/md_to_pdf HTTP/1.1Authorization: Bearer YOUR_API_KEYContent-Type: application/json
{ "markdown": "# Hello World\n\nThis is **bold** and this is *italic*.\n\n- Item one\n- Item two\n\n> A blockquote"}Sending raw Markdown
If you have a .md file and don’t need any options, send the file contents directly with the text/markdown content type:
curl -X POST https://api.nutrient.io/processor/md_to_pdf \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: text/markdown" \ --data-binary @document.md \ -o output.pdfPOST /processor/md_to_pdf HTTP/1.1Authorization: Bearer YOUR_API_KEYContent-Type: text/markdown
# My Document
Content of the Markdown file...Using a built-in template with custom CSS
Select a template and override specific styles with the css parameter:
curl -X POST https://api.nutrient.io/processor/md_to_pdf \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "markdown": "# Quarterly Report\n\n## Revenue\n\n| Quarter | Revenue |\n|---------|--------:|\n| Q1 | $1.2M |\n| Q2 | $1.5M |\n\n> Full details in the appendix.", "template": "built-in:corporate", "css": "h1 { color: #1a365d; } table { width: 100%; }" }' \ -o report.pdfPOST /processor/md_to_pdf HTTP/1.1Authorization: Bearer YOUR_API_KEYContent-Type: application/json
{ "markdown": "# Quarterly Report\n\n## Revenue\n\n| Quarter | Revenue |\n|---------|--------:|\n| Q1 | $1.2M |\n| Q2 | $1.5M |\n\n> Full details in the appendix.", "template": "built-in:corporate", "css": "h1 { color: #1a365d; } table { width: 100%; }"}Uploading assets
When your Markdown references local images or you want to include custom fonts or other files, use multipart/form-data to upload the Markdown file and assets together. Each uploaded file part becomes an asset that can be referenced by filename in the Markdown or in your CSS and HTML templates.
curl -X POST https://api.nutrient.io/processor/md_to_pdf \ -H "Authorization: Bearer YOUR_API_KEY" \ -F markdown=@document.md \ -F logo.png=@images/logo.png \ -F chart.svg=@images/chart.svg \ -o output.pdfPOST /processor/md_to_pdf HTTP/1.1Authorization: Bearer YOUR_API_KEYContent-Type: multipart/form-data; boundary=customboundary
--customboundaryContent-Disposition: form-data; name="markdown"; filename="document.md"Content-Type: text/markdown
# Company Report

## Performance
--customboundaryContent-Disposition: form-data; name="logo.png"; filename="logo.png"Content-Type: image/png
<PNG data>--customboundaryContent-Disposition: form-data; name="chart.svg"; filename="chart.svg"Content-Type: image/svg+xml
<SVG data>--customboundary--To combine asset uploads with template or CSS options, include a data part containing JSON:
curl -X POST https://api.nutrient.io/processor/md_to_pdf \ -H "Authorization: Bearer YOUR_API_KEY" \ -F markdown=@report.md \ -F 'data={"template":"built-in:elegant","css":"img { max-width: 100%; }","markdown_options":{"syntax_highlight":{"theme":"github"}}};type=application/json' \ -F chart.png=@assets/chart.png \ -F logo.svg=@assets/logo.svg \ -o report.pdfPOST /processor/md_to_pdf HTTP/1.1Authorization: Bearer YOUR_API_KEYContent-Type: multipart/form-data; boundary=customboundary
--customboundaryContent-Disposition: form-data; name="markdown"; filename="report.md"Content-Type: text/markdown
<Markdown data>--customboundaryContent-Disposition: form-data; name="data"Content-Type: application/json
{ "template": "built-in:elegant", "css": "img { max-width: 100%; }", "markdown_options": { "syntax_highlight": { "theme": "github" } }}--customboundaryContent-Disposition: form-data; name="chart.png"; filename="chart.png"Content-Type: image/png
<PNG data>--customboundaryContent-Disposition: form-data; name="logo.svg"; filename="logo.svg"Content-Type: image/svg+xml
<SVG data>--customboundary--Custom HTML templates
For complete control over the output, provide an HTML template via the html part in a multipart request. The rendered Markdown body is inserted at the {{content}} placeholder inside your HTML.
curl -X POST https://api.nutrient.io/processor/md_to_pdf \ -H "Authorization: Bearer YOUR_API_KEY" \ -F markdown=@document.md \ -F html=@template.html \ -F brand-font.woff2=@fonts/brand-font.woff2 \ -F header-bg.png=@images/header-bg.png \ -o output.pdfPOST /processor/md_to_pdf HTTP/1.1Authorization: Bearer YOUR_API_KEYContent-Type: multipart/form-data; boundary=customboundary
--customboundaryContent-Disposition: form-data; name="markdown"; filename="document.md"Content-Type: text/markdown
<Markdown data>--customboundaryContent-Disposition: form-data; name="html"; filename="template.html"Content-Type: text/html
<HTML template data>--customboundaryContent-Disposition: form-data; name="brand-font.woff2"; filename="brand-font.woff2"Content-Type: font/woff2
<Font data>--customboundaryContent-Disposition: form-data; name="header-bg.png"; filename="header-bg.png"Content-Type: image/png
<PNG data>--customboundary--A minimal custom HTML template looks as follows. The {{content}} placeholder is required and is where the rendered Markdown will be injected:
<!DOCTYPE html><html><head> <style> @font-face { font-family: 'BrandFont'; src: url('brand-font.woff2') format('woff2'); } body { font-family: 'BrandFont', sans-serif; max-width: 800px; margin: 0 auto; padding: 40px; } h1 { color: #2c3e50; border-bottom: 2px solid #3498db; } </style></head><body> <header> <img src="header-bg.png" alt="Header" style="width:100%"> </header> {{content}}</body></html>Asset files uploaded alongside the HTML template (fonts, images, stylesheets) can be referenced by their part name. When using an inline HTML template, the css parameter is ignored — all styling is controlled by the HTML.
Supported Markdown features
The parser is CommonMark(opens in a new tab) compliant. All standard CommonMark syntax is supported:
- Headings (
#through######) - Paragraphs and line breaks
- Emphasis (
*italic*,**bold**,***bold italic***) - Links and images
- Inline code and fenced code blocks with syntax highlighting
- Block quotes
- Ordered and unordered lists
- Thematic breaks (
---)
The following GFM features are also supported:
| Feature | Syntax |
|---|---|
| Tables | Pipe-delimited tables with column alignment |
| Strikethrough | ~~deleted text~~ |
| Autolinks | Bare URLs and email addresses become clickable |
| Task lists | - [x] done / - [ ] todo |
| Alerts | > [!NOTE], > [!WARNING], > [!TIP], > [!IMPORTANT], > [!CAUTION] |
| Footnotes | [^1] reference-style and ^[inline] footnotes |
| Superscript | ^superscript^ |
| Subscript | ~subscript~ |
| Highlight | ==highlighted text== |
| Description lists | Term followed by : Definition |
Built-in templates
Select a template with the template parameter. When no template is specified, built-in:default is used.
Report templates
Optimized for multipage documents, articles, and documentation.
| Template | Page | Description |
|---|---|---|
built-in:default | A4 | GFM style. Arimo font, heading underlines, light gray table headers. Used when no template is specified. |
built-in:minimal | A4, narrow margins | Clean and lightweight. Carlito font, no heading borders, minimal decoration. Maximizes content area. |
built-in:corporate | US Letter, one-inch margins | Professional business style. Navy headings and table headers. Suitable for formal business documents. |
built-in:elegant | A4 | Dense report style with blue accent headings. Dark table headers. Optimized for data-heavy reports. |
built-in:executive | A4, one-inch margins | Premium and polished. Generous whitespace, large title. Designed for presentation-quality reports. |
built-in:nordic | A4 | Scandinavian design with serif headings and sans-serif body. Blue accent on lower-level headings. |
built-in:nordic-report | A4 | Dense Nordic style for data-heavy reports. Dark navy table headers, alternating row colors. |
built-in:technical | A4, tight margins | Information-dense technical documentation. Tight line-height, prominent code blocks. Maximizes content per page. |
Presentation templates
Larger text and more whitespace, optimized for executive briefings.
| Template | Page | Description |
|---|---|---|
built-in:elegant-presentation | A4 | Elegant scaled up for presentations. Larger body and title text. Blue accent headings. |
built-in:nordic-executive | A4 | Premium with large title, inverted code blocks (dark background, light text). |
built-in:nordic-presentation | A4 | Nordic style scaled for projection. Large headings, dark navy table headers. |
Custom CSS
Override or extend the selected template’s styles with the css parameter. The custom CSS is appended after the template stylesheet:
{ "markdown": "# My Document\n\nStyled content here.", "template": "built-in:nordic", "css": "body { font-size: 12pt; } h1 { color: #e74c3c; } table th { background: #2c3e50; color: white; }"}When no template is specified, the CSS is appended after the default stylesheet. When using a custom HTML template (via the html multipart part), the css parameter is ignored.
Page layout
The layout parameter controls page dimensions, orientation, and margins. If omitted, the template’s default layout is used.
{ "markdown": "# Landscape Report\n\nWide tables look better in landscape.", "layout": { "size": "Letter", "orientation": "landscape", "margin": { "top": 20, "right": 20, "bottom": 20, "left": 20 } }}| Option | Type | Default | Description |
|---|---|---|---|
size | String or object | "A4" | A preset name ("A4", "Letter", "Legal", "A0"–"A8") or custom dimensions {"width": mm, "height": mm}. |
orientation | String | "portrait" | "portrait" or "landscape". |
margin | Object | {"top": 10, "right": 10, "bottom": 10, "left": 10} | Page margins in millimeters. Each field must be >= 0. |
Syntax highlighting
Fenced code blocks with a language identifier receive automatic syntax highlighting. Configure via markdown_options.syntax_highlight:
{ "markdown": "# Code Example\n\n```python\ndef greet(name):\n return f'Hello, {name}!'\n```", "markdown_options": { "syntax_highlight": { "theme": "github" } }}| Option | Type | Default | Description |
|---|---|---|---|
theme | string | "onedark" | Color theme name. Refer to the dark themes and light themes options below. |
Set syntax_highlight to false to disable highlighting entirely.
Dark themes
onedark(default)draculamonokainordgithub-darkgithub-dark-dimmedgruvbox-darkcatppuccin-mochabase16-ocean-darkayu-darkayu-miragesolarized-darkvisual-studio-darkmaterial-darknight-owlsynthwave-84coldark-darktokyonight-stormtokyonight-nightkanagawa-wavekanagawa-dragonrose-pinerose-pine-moonnightfoxnordfoxcarbonfoxterafoxduskfoxeverforest-darkoxocarbon-darktomorrow-nightzenburn
Light themes
githubgithub-lightinspired-githubcatppuccin-lattegruvbox-lightsolarized-lightayu-lightmaterial-lightone-lightcoldark-coldtokyonight-daykanagawa-lotusrose-pine-dawndawnfoxdayfoxeverforest-lightoxocarbon-lightemacsbase16-ocean-light
Available fonts
The following fonts are available out of the box:
| Font | Style | Metric equivalent |
|---|---|---|
| Carlito | Sans-serif | Calibri |
| Arimo | Sans-serif | Arial |
| Caladea | Serif | Cambria |
| Noto Sans | Sans-serif | — |
| DejaVu Sans | Sans-serif | — |
| Liberation Mono | Monospace | Courier New |
| Cousine | Monospace | — |
Use these font families in your custom CSS or HTML templates. To use a custom font, upload the font file as a multipart part and reference it with @font-face in your CSS or HTML template.