10 documents a month, free, no card

HTML, Markdown or a URL in.
PDF bytes out.

PDFMint is a PDF generation API and an n8n community node. One POST with the content you already have — no template editor to learn, no template ID to paste, no second request to fetch the file.

Every plan includes password protection, headers and footers, page numbers, custom sizes and the n8n node.

# Markdown in, a real PDF file out.
curl -X POST https://pdf.mintapis.com/v1/pdf \
  -H "Authorization: Bearer pm_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "markdown": "# Invoice 1042\n\nThanks for your business.",
    "options": { "margin": "18mm", "pageNumbers": true }
  }' \
  --output invoice.pdf
HTTP 200 content-type: application/pdf x-pdfmint-pages: 1 x-pdfmint-duration-ms: 328
328 ms
A one-page Markdown document, rendered through the live public API.
128 MB
Peak memory for 8 concurrent renders, in a 512 MB container.
$0.0018
Per document on the $9 Starter plan — 5,000 documents a month.

Measured on the live service on 23 August 2026. PDFMint is new — these are the only numbers we have, so they are the only ones we quote.

One endpoint, four inputs

Send what you already have

POST /v1/pdf takes exactly one of these four fields. Send two and it tells you which two, instead of quietly picking one.

"html"

Your own markup

Full CSS control. printBackground is on by default, so your colours and shading survive the print pipeline.

"markdown"

Markdown, print-ready

Rendered with a stylesheet built for paper: table rows never split across a page break, headings never orphan, code blocks wrap.

"url"

A public page

Wait for a delay, a CSS selector or networkidle before capture. Private and link-local addresses are refused.

"template"

A saved template

Addressed by name"template": "invoice", not a hex id. Get the name wrong and the error lists the names you do have.

n8n community node

The file comes back on the node

Install n8n-nodes-pdfmint, paste your API key once, and the PDF arrives as binary data on the PDFMint node itself. Self-hosted n8n for now — n8n Cloud does not permit unverified community nodes, and ours is still in review. On Cloud, use the HTTP API with an HTTP Request node in the meantime.

  • No second HTTP Request node. The node calls prepareBinaryData, so the file is attached to the item and ready for Gmail, Drive, S3 or Slack.
  • Templates are a dropdown. The node loads the templates on your account, so you pick a name instead of pasting an id.
  • usableAsTool: true. An n8n AI Agent can call PDFMint directly as a tool. Neither the CraftMyPDF nor the pdforge node declares this.
  • Four operations. Generate PDF, Generate Image, Merge PDFs and Get Usage — the same account, the same credential.
PDFMint generate pdf
CredentialPDFMint account
OperationGenerate PDF
SourceTemplate
Template Nameinvoice ▾
Data{{ $json }}
OutputFile (Binary)
File Nameinvoice-1042.pdf
invoice-1042.pdf pages: 1 durationMs: 328 creditsRemaining: 4999

The node also puts pages, durationMs, creditsRemaining and any warning on the item’s JSON, next to the binary — so a downstream IF node can act on them.

The details that usually bite

Chrome’s sharp edges, filed down

Most of what goes wrong with headless-Chrome PDFs goes wrong silently. These are handled in the renderer, not left in your lap.

Page numbers that fit

Chrome clips a footer that does not fit inside the page margin. Set pageNumbers: true and the bottom margin is widened for you, so “Page 2 of 7” is actually on the page.

Headers that are not blank

Chrome renders header and footer templates in their own document at font-size 0, which is why they so often come out empty. Your markup is wrapped in a readable container aligned to the page margins — and laid out in the renderer first, so the margin is sized to the header you actually wrote and a letterhead with a logo in it does not print over your first paragraph.

Placeholders that speak up

A placeholder your data does not fill is reported in X-PDFMint-Warning, or refused outright with "strict": true. A key typo never ships as a blank invoice.

Passwords on every plan

Send "password" and the PDF comes back AES-256 encrypted via qpdf, with separate owner password and print/copy permissions. Included on the free tier too.

Type that renders

Inter, JetBrains Mono, Noto CJK and Noto Color Emoji ship inside the container. Chinese, Japanese, Korean and emoji come out as glyphs, not tofu boxes.

Renders that wait

waitFor takes milliseconds, a CSS selector or "networkidle" — so a chart that draws itself after load is in the PDF instead of half-painted.

SSRF-guarded fetches

Every URL you hand to url or merge has its DNS resolved before we fetch it, so a hostname pointing at 169.254.169.254 is caught too. Private, loopback and link-local addresses are refused, as are file: and data:.

Errors you can act on

Every error carries a machine code, a plain-English message, a hint and a link to the exact docs anchor. A failed render is refunded, so you are not billed for it.

Paper you control

A0–A6, Letter, Legal, Tabloid, Ledger or an exact width and height. Landscape, per-side margins, scale, page ranges, screen media and @page sizes.

The rest of the API

Five endpoints, one key

The same pm_live_… bearer token everywhere. Every response tells you what it cost you.

POST /v1/pdf

Generate a PDF

Bytes by default. Or "output": "url" for an expiring hosted link (one hour by default, up to seven days), or "base64" when your platform insists on JSON.

POST /v1/image

Generate a PNG or JPEG

The same inputs, rendered as an image. Full-page or a fixed viewport, retina scale factor, optional transparent background.

POST /v1/merge

Merge up to 50 PDFs

Public URLs, base64, or a mix of both. Optionally rewrite the title and author metadata on the joined document.

/v1/templates · GET /v1/me

Templates and usage

Store reusable HTML under a name you choose, with its own default page options. GET /v1/me returns your plan, credits used and remaining, and the reset date.

Documented service limits
LimitValueWhat happens at the edge
Request body12 MB413 with the size in the message
Rendered HTML10 MBRefused, with a hint about inline base64 images
Render timeout30 s default, 120 s maxSet "timeout" per request
Merge inputs50 filesRefused with the count you sent
Hosted file20 MB, 7 days maxBinary output has no size limit

How it compares

Measured against the alternatives

Everything below is taken from the vendors’ own published specs, pricing pages and n8n node source. Check it yourself — the sources are named under the table.

  PDFMint CraftMyPDF pdforge
Raw HTML → PDF endpoint Yes — html, markdown, url or template None. Every PDF endpoint in their OpenAPI spec requires a template_id Yes — a separate /html-to-pdf endpoint alongside its templates
Documents for $29/month 50,000  ($0.00058 each) 1,200  ($0.0242 each) 1,000 for $35  ($0.035 each)
n8n node returns the file Binary on the same node Yes, when export_type is set to file URL only — the node never calls prepareBinaryData
Callable by an n8n AI Agent usableAsTool: true Not declared Not declared
Max payload 12 MB 4 MB
Max render timeout 120 s 100 s

Scroll the table sideways to see every column.

Sources: CraftMyPDF’s published OpenAPI specification (craftmypdf_api.yaml) and pricing page; pdforge’s pricing page and the source of its n8n node; PDFMint’s own source and plan table. Dashes mean we did not find a published figure and would rather leave the cell empty than guess. These are good products with a different bet — a hosted drag-and-drop template designer. If that is what you want, buy that. PDFMint is for people who already have the HTML.

Pricing

One credit per document

A PDF, an image or a merge costs one credit. Failed renders are refunded automatically. Credits reset on the first of the month.

Free
$0 /month
10 documents
no card required

Enough to paste the first curl, wire up the n8n node and see a real PDF. Not enough to run a workflow on.

Start free
Starter
$9 /month
5,000 documents
$0.0018 per document

For a live product: order confirmations, invoices, weekly reports.

Choose Starter
Pro
$29 /month
50,000 documents
$0.00058 per document

For batch runs — a statement per customer, on the first of every month.

Choose Pro
Scale
$99 /month
250,000 documents
$0.000396 per document

For pipelines that generate documents as a matter of routine.

Choose Scale
Every plan has every feature. Password protection, headers and footers, page numbers, custom page sizes, templates, images, merging, hosted links and the n8n node are on the free tier too. The only thing that changes is how many documents you get.

Start on Free with no card; 10 documents a month is the whole of it, so a workflow that runs daily needs Starter. Checkout runs on Stripe, where you can add a VAT ID if you need one on the invoice — optional, and ignorable if you do not. Upgrade or cancel from the dashboard whenever you like.

Questions

Before you sign up

Do I have to build a template first?

No. Templates are optional and exist only so you can stop pasting the same HTML. POST /v1/pdf with html, markdown or url works on the first call, before you have saved anything.

How big is the free tier?

10 documents a month, permanently, with no card. It is sized to prove the thing works — the first curl, the n8n node, a real PDF on disk — not to run a workflow on. Anything recurring needs Starter at $9 for 5,000 documents. It is a smaller free tier than several competitors give: CraftMyPDF and PDFShift both give 50 a month.

What exactly counts as one document?

One credit per successful call to /v1/pdf, /v1/image or /v1/merge, regardless of page count. If the render fails, the credit is refunded before the error reaches you. GET /v1/me and the templates endpoints are free.

How do I fill a document with data?

Put placeholders in your HTML, Markdown or template and send a data object: {{name}}, nested {{customer.city}}, loops with {{#items}}…{{/items}}, inverted sections with {{^items}}…{{/items}} and unescaped output with {{{html}}}. Values are HTML-escaped by default.

What happens if my data is missing a placeholder?

You are told. The response carries an X-PDFMint-Warning header naming each unresolved placeholder, and "strict": true turns that into a 4xx error instead. A blank document is never returned silently.

Can I get a URL instead of the bytes?

Yes — "output": "url" returns a hosted link that expires after an hour by default, and up to seven days if you ask. The default is "binary", because in n8n and in most scripts the file is what you actually wanted.

Where do I install the n8n node?

Self-hosted n8n only, for now. n8n does not allow unverified community nodes on n8n Cloud. PDFMint's node is submitted for verification and sitting in n8n's automated review; until that clears, Cloud cannot install it. On a self-hosted instance: Settings → Community nodes → Install, enter n8n-nodes-pdfmint, add a PDFMint credential with your API key, and the node appears in the node panel. It is published with an npm provenance attestation, and the source is on GitHub. On n8n Cloud the HTTP API works today — an HTTP Request node pointed at /v1/pdf returns the same PDF bytes.

Your first PDF is about 30 seconds away

Create an account, copy the key off the dashboard, paste the curl above. 10 documents a month, free, no card.

Who runs this, and what it is not

PDFMint is built and run by Florian Standhartinger. It launched in August 2026, so there are no customer logos and no uptime history to show you — instead there is a status page that reads the service's own request log: documents produced, success rate, median and 95th-percentile render time, and a bar per hour for the last day. It also lists, in plain words, what PDFMint does not have.

There is no SLA and no SOC 2 report. It runs as one service in Frankfurt, and a deploy restarts it. Failed renders refund the credit automatically. The API source and the node source are both public, so you can read exactly what happens to the HTML you send. Problems go to GitHub issues.