Every team that writes docs-as-code eventually hits the same wall. Your README lives in Markdown. Your changelog lives in Markdown. Your architecture notes, your onboarding guide, your API reference, all Markdown, all sitting next to the code where version control can track every change. Then someone in legal, procurement, or a client's IT department asks for "the documentation" and means a PDF. Not a GitHub link. Not a rendered HTML page. A file they can attach to an email, print, or archive.
That request used to mean opening a Markdown file in some GUI tool, exporting it by hand, and doing it again next release. Convert Markdown to PDF turns that into a single REST call, which means it turns into a step in a pipeline instead of a chore on someone's calendar.
What the endpoint actually does
The REST API exposes one endpoint for this: POST /api/v2/ConvertMdToPdf against the base URL https://api.pdf4me.com, per the Connect to PDF4me API guide.
Two parameters are required: File Content, the Markdown file encoded as Base64, and File Name, the source filename with its extension, for example document.md. There's one optional parameter, Markdown File Path, which only matters if you're sending a ZIP archive instead of a single file. If your input is a ZIP of Markdown files, this field tells PDF4me which file inside the archive to render, something like docs/readme.md. Leave it empty for a direct .md file.
The JSON payload uses docContent for the Base64 source, docName for the output name, and mdFilePath for the in-archive path when relevant, alongside IsAsync for polling behavior on larger files. Send those fields with your API key in the Authorization header, and the response comes back with the converted file content and name, ready to save, attach, or pipe into the next step.
What actually gets preserved matters more than the endpoint shape. The conversion handles the Markdown syntax that documentation is actually built from: headers from H1 through H6 with correct hierarchy, bold, italic, strikethrough, and inline code, ordered and unordered lists with proper nesting, fenced code blocks with syntax highlighting, links, embedded images, and tables with column alignment intact. That's the difference between a PDF that looks like documentation and one that looks like a wall of plain text with stray asterisks in it.
A minimal working request
Here's the shape of a real call, field names verified against the live docs page and the API Tester's own quick reference:
import base64
import requests
with open("README.md", "rb") as f:
md_base64 = base64.b64encode(f.read()).decode("utf-8")
payload = {
"docContent": md_base64,
"docName": "README.md",
"mdFilePath": "", # only needed when docContent is a ZIP
"IsAsync": False
}
headers = {
"Content-Type": "application/json",
"Authorization": "Basic YOUR_API_KEY"
}
response = requests.post(
"https://api.pdf4me.com/api/v2/ConvertMdToPdf",
json=payload,
headers=headers
)
if response.status_code == 200:
with open("README.pdf", "wb") as out:
out.write(response.content)
elif response.status_code == 202:
# large file, poll the Location header until it returns 200
poll_url = response.headers["Location"]
else:
print(response.status_code, response.text)
A quick note on the docs page itself: the generic payload example shown there (docName: "output.pdf") is boilerplate shared across every Convert endpoint's page and doesn't match this endpoint's own parameter table, which is explicit that File Name is the source Markdown filename, not the output PDF name. The API Tester's quick reference confirms the real field set: api-key, docContent, docName, mdFilePath, IsAsync. Trust the parameter table and the tester over the boilerplate example if you ever see the two disagree.
Status 200 means the PDF came back in the response body immediately. Status 202 means PDF4me accepted the job and is processing it asynchronously. On the API Tester's live page for this endpoint, setting IsAsync to true is exactly how you'd trigger that path for a larger file, then poll the Location header URL until it resolves.
Batch conversion, not just one file at a time
Documentation rarely lives as a single file. A docs folder might hold dozens of .md files: guides, references, changelogs, contributing notes. The endpoint's ZIP support exists for exactly this. Send a ZIP archive as the file content, and use Markdown File Path to point at the specific file inside it you want rendered for that call. To convert an entire folder, you run the endpoint once per file, which is precisely the kind of repetitive step a workflow tool should own instead of a person.
Four ways to wire it into a pipeline
A docs-as-code pipeline generally looks the same regardless of which automation tool sits in the middle: something triggers on a documentation change, the Markdown gets fetched, PDF4me converts it, and the PDF lands somewhere a human or a customer can find it. Here's what that looks like on each platform PDF4me supports.
Make. The Convert Markdown to PDF module takes a Connection, File Name, Document (the binary buffer), and conditionally Markdown File Path for ZIP input. It maps cleanly onto a scenario that triggers on a new GitHub release, downloads the README, converts it, and attaches the result to the release assets. Two things worth knowing before you build this: relative image paths in your Markdown may not resolve when the module renders the PDF, so use absolute URLs for embedded images, and the module converts one file per run, so processing a full docs folder means placing a Repeater or Iterator ahead of it. Make's own docs note the module follows the CommonMark spec, with GitHub-flavored extensions like tables and task lists handled per GitHub's Markdown guide.
Zapier. The Markdown To PDF action takes File Name and File Content as required fields, with Markdown File Path again reserved for ZIP input, and returns a direct URL to the converted PDF alongside the filename and extension. A typical Zap here triggers when documentation updates in a GitHub repository, retrieves the latest Markdown files, converts each one, and can chain into watermarking, packaging, and publishing steps before notifying a channel or customer list that new docs are live.
Power Automate. The Convert Markdown To PDF action fits naturally into a Microsoft 365 flow: File Content and Input File Name are required, Markdown File Path is conditional on ZIP input, and the output comes back as binary File Content plus File Name ready to drop into SharePoint, attach to an Outlook email, or archive in OneDrive. This is the natural home for a flow that watches a SharePoint documentation library, converts new or updated .md files, and routes the PDF to stakeholders without anyone touching Word.
n8n. The Convert Markdown to PDF node is the most flexible of the four on input handling: it accepts Binary Data, a Base64 string, or a public URL as the Markdown source, which matters if your documentation lives somewhere you'd rather point at than download through an extra node. Document Name, Output File Name, and Output Binary Field Name are required; an Advanced Options section adds Custom Profiles for JSON-based configuration like outputDataFormat. The response includes not just the file but a success boolean and a message field, which is the kind of structured signal that makes error handling in a longer workflow far less guesswork.
What a full pipeline looks like end to end
Put the pieces together and a docs-as-code-to-PDF pipeline looks roughly like this: a trigger fires on a documentation change, whether that's a GitHub release, a SharePoint file update, or a scheduled batch job. The relevant Markdown file, or a ZIP of several, gets fetched. PDF4me converts it, preserving headers, code blocks, tables, and links exactly as they were written. From there the PDF can be watermarked with a version number, merged with other converted files into a single package, and pushed to wherever it needs to land: a customer portal, an email attachment, a documentation archive, or all three.
None of this requires anyone to open a Markdown-to-PDF desktop tool ever again. The source of truth stays in version control, in Markdown, exactly where a docs-as-code workflow wants it, and the PDF becomes a generated artifact instead of a manually maintained parallel copy that drifts out of sync the first time someone forgets to update it.
One honest gap worth flagging: PDF4me doesn't yet have a dedicated blog walkthrough for this specific endpoint, so if you're looking for a worked example beyond the reference docs and code samples linked above, the GitHub samples repository is currently the most complete place to start, alongside the interactive API Tester for trying a request before you write any code at all.
Website: pdf4me.com
Documentation: docs.pdf4me.com
Developer portal: dev.pdf4me.com
Top comments (0)