Before you start: there is no CastPDF node yet
One thing first, so nobody is surprised. CastPDF does not have its own n8n node, community node or listing today, and a ready-made CastPDF app for n8n is not available yet. This guide uses the HTTP Request node that ships with every n8n instance. It can call any REST API, and CastPDF is a single endpoint that takes JSON and returns a PDF.
Labels can change
n8n renames fields between versions now and then. The labels below match the HTTP Request node at the time of writing. If one looks different in your instance, pick the closest match: the settings themselves (method, URL, header, JSON body, response format) stay the same.
You need three things before you open the editor:
- An n8n instance, either n8n Cloud or self-hosted.
- A CastPDF API key. Start with a test key (
cpdf_test_...): it is free, adds a watermark and allows 20 requests per minute. - A saved template in the CastPDF dashboard (its ID is on the template page), or a piece of HTML you want to print.
Set up the HTTP Request node, step by step
Keep the key out of the node itself. n8n has an encrypted credential store, and the HTTP Request node reads from it. Anyone who opens the workflow then sees a credential name, never the key. The steps below create that credential on the way.
- Add the node. After your trigger, click the plus button and add an HTTP Request node from the core nodes. Rename it, for example "Create certificate PDF", so the execution log is easy to read.
- Set the method and URL. Set Method to
POSTand URL tohttps://api.castpdf.com/v1/pdf. Leave query parameters switched off. - Create a Header Auth credential. Set Authentication to Generic Credential Type and Generic Auth Type to Header Auth. Create a credential with Name
Authorizationand ValueBearerfollowed by your key. Save it as "CastPDF test key". - Send the body as JSON. Switch on Send Body. Choose Body Content Type JSON and Specify Body Using JSON. Paste the body from the next section, then swap the sample values for expressions.
- Pick the response format. Under Options, add Response. Set Response Format to File when you want the PDF itself. Keep it on JSON when the body asks for
"response": "url". - Raise the timeout. Under Options, add Timeout and enter
60000(milliseconds). A render may take up to 30 seconds, and the extra margin covers the network. - Test the step. Run the node with sample input. You should see a binary
dataproperty holding a PDF, or JSON withurl,pagesandexpires_at.
The JSON body, with n8n expressions
Here is a body for a certificate of completion. An n8n Form Trigger asks for a full name, a course and a completion date. Each answer is pulled into the body with an expression in double curly braces, and the execution ID doubles as a certificate number.
{
"template_id": "8d1f2c3b-4a5e-4f60-9b7a-1c2d3e4f5a6b",
"data": {
"certificate_id": "NT-{{ $execution.id }}",
"completed_on": "{{ $json['Completion date'] }}",
"recipient": { "name": "{{ $json['Full name'] }}" },
"course": { "title": "{{ $json.Course }}", "hours": 12 },
"issuer": { "name": "Northgate Training" }
},
"filename": "certificate-{{ $execution.id }}.pdf",
"response": "url"
}Three details keep this valid. Text values keep their quotes around the expression, so the resolved body is still JSON. Numbers may go in without quotes, but only when the expression always returns a number. A list, such as invoice lines, goes in as {{ JSON.stringify($json.items) }} with no quotes at all.
Prefer raw HTML to a template? Replace template_id with html, and add data only when the HTML uses Liquid tags. With html, CastPDF renders in fast mode unless you add "mode": "print". Print mode is what you want for long tables and page numbers. The Liquid reference lists the filters you can use.
Template ID or raw HTML?
A saved template is easier to live with. You edit the design in the CastPDF dashboard with a live preview, and the workflow never changes. Raw HTML inside a node is fine for a quick test, but long HTML strings in JSON are hard to read and easy to break.
File or link: pick the response that suits the next node
CastPDF can answer in two ways. The right one depends on what the node after the HTTP Request does with the result.
| Body setting | Response Format | What the next node gets | Good for |
|---|---|---|---|
No response field (binary) | File | A binary data property with the PDF | Email attachments, uploads to file storage |
"response": "url" | JSON | url, expires_at, pages, bytes and id | A download link in an email, a chat message or a database row |
The link is signed. It works without an API key until expires_at, then it stops. That time follows your plan’s storage period; with a test key it is 1 day. If people need the file for longer, keep your own copy in a later node.
A binary response also carries the document ID in the x-document-id header and the page count in x-pages. To read them in n8n, switch on Include Response Headers and Status in the Response option.
Example workflow: form, PDF, email with the link
A small training company wants each graduate to get a certificate a minute after filling in a form. The whole workflow is three nodes.
- n8n Form Trigger. Fields: Full name, Email, Course and Completion date. It outputs one item per submission.
- HTTP Request. The node from the steps above, with the certificate body and
"response": "url". It outputs the signedurl. - Send Email. To:
{{ $('n8n Form Trigger').item.json.Email }}. Subject: Your certificate. The message includes{{ $json.url }}as the download link.
The Send Email node needs the address from the trigger. The HTTP Request output only holds the PDF details, so the To field reaches back to the trigger by node name. Want an attachment instead? Switch the HTTP Request node to the binary response and put data in the Send Email Attachments field.
Self-hosted instances need one extra check. The server must be allowed to make outbound HTTPS calls to api.castpdf.com, which strict firewalls and some container setups block. n8n Cloud needs nothing extra.
Making PDFs for many records? Place the HTTP Request node after a node that returns one item per record. n8n runs the request once per item, so ten rows make ten PDFs. Each PDF is its own request here; for large lists, the API also has a batch endpoint that takes many items in one request.
Troubleshooting: the errors you will actually see
When CastPDF rejects a request, it answers with JSON holding a code, a readable message and a docs_url. n8n marks the node as failed and shows that body. These are the ones people hit most.
- 401 invalid_api_key. The header is wrong. Check that the credential Name is exactly
Authorizationand the Value starts withBearerand a space. A key you revoked in the dashboard also returns 401. - 422 template_render_error. The Liquid in your template failed with this data. The
detailsgive a line and a column. The usual cause is an expression that resolved to nothing, so a field the template needs is missing. - 400 invalid_request. The body is not valid JSON, or it contains a field CastPDF does not know. Unknown fields are rejected on purpose, so a typo fails fast instead of being ignored.
- 429 rate_limited. You sent more requests per minute than your key allows. Wait the seconds given in the
Retry-Afterheader. In n8n, turn on Retry On Fail in the node settings, or use the Batching option to space requests out. - Timeouts. A render may take up to 30 seconds, and n8n can give up sooner. Set the Timeout option to at least 60000 ms, then retry with the same
Idempotency-Keyheader.
That last header deserves a minute. Switch on Send Headers and add Idempotency-Key with a value that names the document, such as the certificate number. If a retried request finds a PDF that already finished, CastPDF returns that one instead of rendering it again. The errors reference has every code, including plan limits and oversized documents.
What it costs to run
CastPDF counts one PDF per successful request, however many pages it has. Test keys are free and unlimited, with a watermark, so you can build and debug the whole workflow first. The Free plan includes 100 live PDFs a month, and pricing shows the paid plans.
n8n’s own costs come on top. n8n Cloud plans count workflow executions, and the three-node example uses one execution per form submission. A self-hosted instance has no fee per execution, but you pay for the server it runs on. A replayed request with the same Idempotency-Key is never billed twice by CastPDF.
Where to go next
Start from the certificate template or the invoice template, adjust the design in the dashboard, and copy its ID into the node. The templates docs explain versions, so a design change never touches the workflow.
Building somewhere else? There is a similar walkthrough for a visual scenario builder, and another for internal admin panels.