Blog/Integrations

Generate PDFs in n8n with RelayPDF

Official n8n-nodes-relaypdf node for HTML, Markdown, URL, and published Handlebars templates. Binary PDF out for Gmail, Slack, and Drive.

Integrations··3 min read

The generate step is a known quantity

n8n PDF generation is the same four steps: receive data, map it into a document, generate a PDF, then send or store the file. RelayPDF owns Chromium and LibreOffice. n8n owns triggers, mapping, and delivery. The n8n host never runs a browser.

Install n8n-nodes-relaypdf. Add a RelayPDF API credential. Pick an operation. Default output is binary field data, which Gmail, Slack, and Google Drive already know how to attach.

Install

Self-hosted: Settings → Community Nodes → Install n8n-nodes-relaypdf.

n8n Cloud: search RelayPDF in the nodes panel once the node is verified. Until then, self-hosted install still works, and HTTP Request remains the fallback.

Create a RelayPDF API credential. Paste the key from the dashboard (pdf_live_…) with no Bearer prefix. Connection test calls GET /v1/account and is not billed.

Create a PDF

Resource PDF, operation Create. Source is exactly one of:

  • Template — published Handlebars layout. templateId is the dashboard slug or UUID. templateData is the JSON object. Recurring invoices and certificates live here.
  • HTML — markup from a Code or Set node.
  • Markdown — GFM, rendered with Chromium.
  • URL — a page RelayPDF can reach. Private, loopback, and metadata hosts return url_not_allowed. Use waitUntil: networkidle0 for dashboards.

Response modes:

  • Binary (default) — PDF bytes on field data. Use this for email and Drive.
  • URL — JSON with a 24-hour download link.
  • Async202 plus pollUrl. The node can wait and still return bytes, or you can poll GET /v1/jobs/:id yourself.

Failed jobs are not billed.

Office files

Resource Convert, operation Convert File. Point it at an incoming n8n binary (Gmail attachment, Drive download). The node base64-encodes the file and sets sourceFilename from the original name. That is POST /v1/convert, not POST /v1/pdf. A 503 convert_unavailable means the document worker is cold; retry; it is not billed.

Tools

Merge, extract, protect, bookmarks, barcodes, and zip are operations on the same node. Merge and zip accept mixed URL and binary inputs so you do not re-encode files in a Code node.

Signed webhooks

The RelayPDF Trigger node listens for dashboard webhooks. Copy the n8n webhook URL into /dashboard/webhooks. Paste the secret shown once into the trigger. Events: job.completed, job.failed, wallet.topup, wallet.auto_reload, wallet.auto_reload_failed, wallet.payment_required. Signatures are HMAC-SHA256 on {t}.{raw_body}.

Per-request callbackUrl on Create/Convert is unsigned and is a different path.

Example: template invoice to Gmail

  1. Webhook receives templateData, recipientEmail, optional filename.
  2. RelayPDF: Source Template, Template ID invoice, Template Data from the webhook JSON, Response Binary, field data.
  3. Gmail attaches binary property data. Read the recipient from the Webhook node: {{ $('Webhook').item.json.body.recipientEmail }}.
  4. Respond to Webhook with JSON, not PDF bytes.

Importable workflow JSON ships in the node package under workflows/.

HTTP Request fallback

If community nodes are disabled, POST https://api.relaypdf.com/v1/pdf with Header Auth name Authorization and value Bearer pdf_live_…. Body JSON. Options → Response → Response Format File, Put Output in Field data. Autodetect will try to parse PDF bytes as JSON.

curl -X POST https://api.relaypdf.com/v1/pdf \
  -H "Authorization: Bearer pdf_live_…" \
  -H "Content-Type: application/json" \
  -d '{"html":"<h1>Invoice #1042</h1>","filename":"invoice.pdf"}' \
  --output invoice.pdf

Do not put the key in the URL. Query-string keys are rejected.

Common failures

  • PDF generated but not attached: binary field name mismatch, or the recipient was read from $json after a binary response replaced the item.
  • invalid_request: more than one source, or none. Empty strings count.
  • 401: credential missing Bearer on HTTP Request, or extra Bearer in the community-node credential.
  • Missing charts on a URL capture: set waitUntil to networkidle0. There is no wait-for-selector on the live API.
  • url_not_allowed: the URL is not reachable from RelayPDF.
  • payment_required / rate_limited: empty wallet or 429. Neither is billed as a render.

More: n8n integration, POST /v1/pdf, templates.

Ready to generate?

One API for HTML, Markdown, URLs, and Office. REST, SDK, CLI, or MCP.