Markdown to PDF

Convert Markdown content to beautifully styled PDF documents.

Markdown to PDF

Convert GitHub-flavored Markdown to beautifully styled PDF documents with syntax highlighting, tables, and more.

POST /v1/pdf/markdown

Request Body

ParameterTypeRequiredDescription
markdownstringYesMarkdown content to convert
themestringNoTheme to apply (default: "default")
optionsobjectNoPDF generation options

Options Object

ParameterTypeDefaultDescription
formatstring"A4"Paper format (A4, A3, A5, Letter, Legal, Tabloid)
landscapebooleanfalseLandscape orientation
marginobject-Page margins (top, bottom, left, right)
print_backgroundbooleantrueInclude background colors/images
scalenumber1.0Scale factor (0.1 to 2.0)
headerstring-HTML for page header
footerstring-HTML for page footer

Code Examples

curl -X POST https://api.pdfapi.dev/v1/pdf/markdown \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "markdown": "# Monthly Report\n\n## Summary\n\n- Revenue: $45,678\n- Users: 1,234\n\n## Details\n\n| Metric | Value |\n|--------|-------|\n| New signups | 156 |\n| Churn | 2.3% |",
    "theme": "corporate",
    "options": {
      "format": "A4",
      "margin": {
        "top": "20mm",
        "bottom": "20mm",
        "left": "15mm",
        "right": "15mm"
      }
    }
  }' \
  --output report.pdf
const response = await fetch('https://api.pdfapi.dev/v1/pdf/markdown', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.PDFAPI_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    markdown: `# Monthly Report

## Summary
- Revenue: $45,678
- Users: 1,234

## Details
| Metric | Value |
|--------|-------|
| New signups | 156 |
| Churn | 2.3% |`,
    theme: 'corporate',
    options: {
      format: 'A4',
      margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' }
    }
  }),
});

if (!response.ok) {
  const error = await response.json();
  throw new Error(error.error.message);
}

const buffer = await response.arrayBuffer();
// Save or process the PDF
import requests
import os

response = requests.post(
    'https://api.pdfapi.dev/v1/pdf/markdown',
    headers={
        'Authorization': f'Bearer {os.environ["PDFAPI_KEY"]}',
        'Content-Type': 'application/json',
    },
    json={
        'markdown': '''# Monthly Report

## Summary
- Revenue: $45,678
- Users: 1,234

## Details
| Metric | Value |
|--------|-------|
| New signups | 156 |
| Churn | 2.3% |''',
        'theme': 'corporate',
        'options': {
            'format': 'A4',
            'margin': {'top': '20mm', 'bottom': '20mm', 'left': '15mm', 'right': '15mm'}
        }
    }
)

if response.status_code == 200:
    with open('report.pdf', 'wb') as f:
        f.write(response.content)
else:
    print(f"Error: {response.json()['error']['message']}")
package main

import (
    "bytes"
    "encoding/json"
    "io"
    "net/http"
    "os"
)

func main() {
    payload := map[string]interface{}{
        "markdown": "# Monthly Report\n\n## Summary\n- Revenue: $45,678",
        "theme":    "corporate",
        "options": map[string]interface{}{
            "format": "A4",
            "margin": map[string]string{
                "top": "20mm", "bottom": "20mm",
            },
        },
    }

    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", "https://api.pdfapi.dev/v1/pdf/markdown", bytes.NewBuffer(body))
    req.Header.Set("Authorization", "Bearer "+os.Getenv("PDFAPI_KEY"))
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()

    pdf, _ := io.ReadAll(resp.Body)
    os.WriteFile("report.pdf", pdf, 0644)
}

Supported Markdown Features

GitHub Flavored Markdown

Full support for GFM including:

  • Bold and italic text
  • Strikethrough
  • Links
  • Images with alt text
  • Autolinks

Tables

| Header 1 | Header 2 | Header 3 |
|:---------|:--------:|---------:|
| Left     | Center   | Right    |
| Cell     | Cell     | Cell     |

Code Blocks with Syntax Highlighting

Supports 40+ languages including JavaScript, Python, Go, Ruby, and more.

```javascript
function greet(name) {
  return `Hello, ${name}!`;
}
```

Task Lists

- [x] Completed task
- [ ] Pending task
- [ ] Another pending task

Blockquotes

> This is a blockquote.
> It can span multiple lines.

Headings (H1-H6)

# Heading 1
## Heading 2
### Heading 3
#### Heading 4

Available Themes

ThemeDescriptionAvailability
defaultClean, modern stylingAll plans
minimalSimple, minimal designAll plans
corporateProfessional business styleAll plans
invoiceOptimized for financial documentsPro+
academicAcademic paper formattingPro+
resumeResume/CV formattingPro+

Response

Success (200)

Returns the PDF file directly:

Content-Type: application/pdf
Content-Disposition: attachment; filename="document.pdf"

Error Responses

Missing Markdown (400)

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Markdown content is required"
  }
}

Theme Not Available (403)

{
  "error": {
    "code": "THEME_NOT_AVAILABLE",
    "message": "Theme 'invoice' requires a Pro plan or higher"
  }
}

See Error Codes for complete reference.