# MD2PDF — Complete Documentation for AI Agents > MD2PDF is a free, open-source online tool that converts Markdown (.md) files into beautifully styled PDFs, HTML files, and PNG images. Features include Mermaid diagram rendering, auto table of contents, syntax highlighting for 180+ languages, and end-to-end encryption (AES-256-GCM). Conversion runs in the browser with no signup; only share links are stored server-side, encrypted. Includes a public REST API and an installable AI Skill. Website: https://md2pdf.studio GitHub: https://github.com/JSiapoDEV/md2pdf Last updated: 2026-04-16 API version: 1.0 (stable) --- ## Features - Live split-pane editor with real-time Markdown preview - GitHub-Flavored Markdown (GFM) support - Syntax highlighting for 180+ programming languages (via highlight.js) - **Mermaid diagram rendering** (flowcharts, sequence diagrams, Gantt charts, pie charts, etc.) - **Auto table of contents** — write `[TOC]` anywhere to generate a linked TOC from headings - 11 visual styles for document rendering - Custom CSS injection for full styling control - Export to PDF (continuous single page), HTML (standalone with inlined styles), and PNG image - **Encryption** — every shared document is stored encrypted with AES-256-GCM; end-to-end (key never reaches the server) when the client encrypts, as the web app does - Share documents via encrypted URL; link previews show a generic card because the server cannot read the content - Dark and light theme toggle - Drag-and-drop .md file upload - 5 built-in document templates - Word count and reading time indicator - Auto-save drafts to browser localStorage - Find and replace (Ctrl+F / Ctrl+H) - Copy button on every code block - Installable AI Skill in Claude Skills format - Public REST API for programmatic access - WebMCP declarative forms for browser-based AI agent integration - No cookies, no account; conversion never uploads your file, share links are encrypted --- ## Available Visual Styles | Style | Description | |-------|-------------| | notion | Clean, modern sans-serif (default) | | github | Classic GitHub markdown rendering | | minimal | Elegant serif typography, no decorations | | academic | Formal justified text with a scholarly feel | | corporate | Professional design with blue accents and styled table headers | | latex | Simulates academic papers with Libre Baskerville typography | | dracula | Vibrant purple, pink, and green on dark background | | newspaper | Editorial typography with Playfair Display headings | | handwritten | Cursive font with notebook-lined background | | terminal | Green-on-black monospace, hacker aesthetic | | pastel | Soft pink, purple, and teal with rounded elements | --- ## REST API Reference No authentication required. All documents are encrypted at rest using AES-256-GCM. The API exposes two paths with different threat models — pick based on the sensitivity of the content. ### Trust model **Path 1 — End-to-end encrypted (recommended).** The caller encrypts with AES-256-GCM locally and sends header `X-Encrypted: aes-256-gcm`. The server stores the blob as-is; it never sees the key or the plaintext. Use this for any non-public content: logs, internal notes, customer data, drafts. **Path 2 — Server-side encryption (legacy).** The caller sends plaintext; the server generates the key, encrypts, and returns the key. **The server sees the plaintext during the request.** Use only for content that is already public. ### Path 1 — Create an end-to-end encrypted document Steps: (1) generate a 256-bit key, (2) generate a 12-byte IV, (3) AES-256-GCM encrypt, (4) base64-encode `IV ‖ ciphertext ‖ 16-byte tag`, (5) POST. ``` POST https://md2pdf.studio/api/save Content-Type: text/plain X-Encrypted: aes-256-gcm ``` **Response (JSON):** ```json { "id": "BrOrr0N3", "editKey": "a1b2c3d4e5f6...", "url": "https://md2pdf.studio/s/BrOrr0N3" } ``` No `key` field — the server does not have it. Build the shareable link yourself: `{url}#k={your base64url key}`. Store the key only in the caller's process and in the URL you hand to the user. ### Path 1 — Update Reuse the same key; generate a fresh IV. Do not send `X-Enc-Key`. ``` PUT https://md2pdf.studio/api/update/{id} Content-Type: text/plain X-Edit-Key: {editKey} X-Encrypted: aes-256-gcm ``` ### Path 2 — Create (plaintext, server encrypts) ``` POST https://md2pdf.studio/api/save Content-Type: text/plain # Your Markdown content here ``` **Response (JSON):** ```json { "id": "BrOrr0N3", "editKey": "a1b2c3d4e5f6...", "url": "https://md2pdf.studio/s/BrOrr0N3", "key": "xY9kL2mN..." } ``` Build the share link as `{url}#k={key}`. ### Path 2 — Update (plaintext, server re-encrypts) ``` PUT https://md2pdf.studio/api/update/{id} Content-Type: text/plain X-Edit-Key: {editKey} X-Enc-Key: {key} # Updated Markdown content ``` Updating does not extend the link: it expires 30 days after creation. The response includes `expiresAt` (ISO 8601). ### Delete a document ``` DELETE https://md2pdf.studio/api/delete/{id} X-Edit-Key: {editKey} ``` Response 200: `{ "id": "...", "deleted": true }`. 403 with a wrong edit key, 404 if it no longer exists. ### Examples **Path 1 — Python (recommended):** ```python import os, json, base64, urllib.request from cryptography.hazmat.primitives.ciphers.aead import AESGCM markdown = "# Hello World\n\nThis is a styled document created via the API." key = AESGCM.generate_key(bit_length=256) iv = os.urandom(12) ct = AESGCM(key).encrypt(iv, markdown.encode(), None) body = base64.b64encode(iv + ct).decode() key_b64url = base64.urlsafe_b64encode(key).rstrip(b"=").decode() req = urllib.request.Request( "https://md2pdf.studio/api/save", data=body.encode(), headers={"Content-Type": "text/plain", "X-Encrypted": "aes-256-gcm"}, method="POST", ) data = json.loads(urllib.request.urlopen(req).read()) print(f"{data['url']}#k={key_b64url}") ``` **Path 2 — cURL (public content only):** ```bash curl -X POST https://md2pdf.studio/api/save \ -H "Content-Type: text/plain" \ -d "# Public release notes" # Response includes "id","editKey","url","key". # Share link: {url}#k={key} curl -X PUT https://md2pdf.studio/api/update/BrOrr0N3 \ -H "Content-Type: text/plain" \ -H "X-Edit-Key: your-edit-key" \ -H "X-Enc-Key: xY9kL2mN..." \ -d "# Updated content" ``` ### Security - Every stored document is encrypted at rest with **AES-256-GCM**. - Path 1 is true end-to-end encryption: the key is generated by the caller and never leaves the caller's process. Use it for sensitive content. - Path 2 is server-side encryption: the server sees plaintext during the request and the key during the response. Use it only for content you would publish anyway. - The `#k=` hash fragment is never sent to the server on subsequent requests. - Cloudflare KV stores only ciphertext. - The full URL — including `#k=` — is a bearer token. Never paste it in channels that may log or cache URLs. ### Limits - **Max document size:** 500 KB of Markdown (UTF-8) on either path - **Rate limit:** 10 writes per minute per IP (save, update and delete combined) - **Link expiration:** 30 days after creation (updates do not extend it) ### Error Responses | Status | Meaning | Body | |--------|---------|------| | 400 | Empty content | `{"error": "Empty content"}` | | 400 | `X-Encrypted` sent but the body is not base64 ciphertext | `{"error": "...", "code": "not_ciphertext"}` | | 400 | Malformed `X-Enc-Key` on update | `{"error": "Invalid X-Enc-Key", "code": "invalid_key"}` | | 413 | Document too large (>500KB) | `{"error": "Document too large (max 500KB)"}` | | 429 | Rate limit exceeded (`Retry-After: 60`) | `{"error": "Too many requests. Try again in a minute."}` | | 403 | Invalid edit key on update or delete | `{"error": "Unauthorized"}` | | 404 | Document not found, expired, or within its last minute | `{"error": "Document not found"}` | Every API response, including errors, carries `Access-Control-Allow-Origin: *`. --- ## AI Skill (Claude Skills Format) The following skill can be installed in Claude, Custom GPTs, Gemini, or any compatible AI agent. It allows the agent to create and share styled Markdown documents on behalf of the user. ```markdown --- name: md2pdf description: Create and share styled PDF, HTML, and image documents from Markdown via md2pdf.studio. Use when the user wants to export, share, or create a visually styled document from markdown content. --- # MD2PDF Skill Use this skill when the user asks you to: - Create a document or report from their request - Save or export markdown as a PDF, HTML, or image - Share a styled version of written content - Generate a shareable link for a document Example user prompts that trigger this skill: - "Export this as a PDF" - "Make this into a shareable document" - "Create a styled report from this markdown" - "Generate a shareable link for this content" - "Turn my notes into a nice PDF" ## Trust model Two paths: - **Path 1 — End-to-end encrypted (recommended).** Encrypt locally with AES-256-GCM, POST ciphertext with header `X-Encrypted: aes-256-gcm`. Server never sees key or plaintext. Use for any non-public content. - **Path 2 — Server-side encryption (legacy, public content only).** POST plaintext; server generates key and returns it. Server sees plaintext during the request. ## How to create a document (path 1, recommended) 1. Generate a random 256-bit key and a random 12-byte IV. 2. AES-256-GCM encrypt the markdown. Build `IV ‖ ciphertext ‖ 16-byte tag` and base64-encode it. 3. POST: POST https://md2pdf.studio/api/save Content-Type: text/plain X-Encrypted: aes-256-gcm 4. Response: { "id": "...", "editKey": "...", "url": "..." } (no `key` field — the server does not have it) 5. Build the shareable link: {url}#k={your base64url key} 6. Share the full link. Save id, editKey, and the key in the caller's context for future updates. The key must never be sent to the server. ## How to create a document (path 2, public content only) 1. POST the markdown plaintext to `/api/save` with only `Content-Type: text/plain`. 2. Response includes `key` (the server generated it). 3. Build the shareable link: {url}#k={key} ## How to update a document Path 1 (end-to-end encrypted — do NOT send X-Enc-Key): PUT https://md2pdf.studio/api/update/{id} Content-Type: text/plain X-Edit-Key: {editKey} X-Encrypted: aes-256-gcm Path 2 (plaintext, legacy): PUT https://md2pdf.studio/api/update/{id} Content-Type: text/plain X-Edit-Key: {editKey} X-Enc-Key: {key} # Updated markdown ## Available styles notion (default), github, minimal, academic, corporate, latex, dracula, newspaper, handwritten, terminal, pastel ## Limits - Max document size: 500 KB of Markdown (UTF-8) - Rate limit: 10 writes/min per IP - Expiration: 30 days after creation (updates do not extend it) - No authentication required ``` --- ## Document Templates Pre-built templates available in the editor: 1. **CV / Resume** — Professional resume layout 2. **Report** — Monthly or project report 3. **Documentation** — Technical project documentation 4. **Changelog** — Software release changelog 5. **Meeting Notes** — Structured meeting notes --- ## Supported Markdown Syntax MD2PDF supports full GitHub-Flavored Markdown (GFM) plus extensions: - Headings (H1–H6) with auto-generated anchor IDs - Paragraphs with line breaks - **Bold**, *italic*, ~~strikethrough~~ - Ordered and unordered lists - Task lists (checkboxes) - Code blocks with language-specific syntax highlighting (180+ languages) - Inline code - Tables with alignment - Blockquotes - Images (inline and reference) - Horizontal rules - Links (inline and reference) - **Mermaid diagrams** — use ` ```mermaid ` code blocks for flowcharts, sequence diagrams, Gantt charts, pie charts, class diagrams, state diagrams, ER diagrams, and more - **Auto table of contents** — write `[TOC]` on its own line to generate a linked table of contents from all headings --- ## Keyboard Shortcuts | Shortcut | Action | |----------|--------| | Ctrl+S / Cmd+S | Export to PDF | | Ctrl+F / Cmd+F | Find in editor | | Ctrl+H / Cmd+H | Find and replace | | Ctrl+Shift+L / Cmd+Shift+L | Toggle dark/light theme | | Tab | Insert tab in editor | --- ## Technical Details - Pure HTML, CSS, and JavaScript — no framework, no build step - marked.js (v12.0.1) for Markdown parsing - highlight.js (v11.9.0) for syntax highlighting (180+ languages) - html2canvas (v1.4.1) for image export - lz-string (v1.5.0) for URL compression - GitHub Markdown CSS (v5.5.1) as base styling - Hosted on Cloudflare Workers + KV for shared documents - Browser native print dialog for PDF export --- ## Author Built by JSiapoDev - Website: https://jsiapo.dev - GitHub: https://github.com/JSiapoDEV - LinkedIn: https://www.linkedin.com/in/jsiapo/