Fill a PDF Form in n8n with FormRail
In n8n, a downloaded PDF lives in binary data, while FormRail expects a JSON request containing base64 PDF bytes. Getting that boundary right is most of this example.
Here's a workflow you can import, run manually and inspect before connecting your own template.
Import the example
Download the sample workflow from the FormRail docs and import its JSON into n8n. It starts with a manual trigger, downloads a sample PDF, builds the request in a Code node, and fills the file through an HTTP Request node.
The workflow is inactive when imported. It doesn't contain credentials and doesn't send anything to an email address. Create a FormRail API key and store it in an n8n Header Auth credential:
- Name:
Authorization - Value:
Bearer YOUR_FORMRAIL_KEY
Select that credential on the fill request. Keep the actual key in the credential store, rather than pasting it into the workflow JSON.
Read the PDF's binary bytes
The download node uses Response Format: File, with the binary property named data. In the Code node, read that property with n8n's binary helper:
const pdf = await this.helpers.getBinaryDataBuffer(0, 'data');
return [{
json: {
pdf: pdf.toString('base64'),
data: {
ProjectName: 'September installation',
Reference: 'JOB-1042',
Service: 'Installation',
Ready: true,
},
flatten: true,
},
}];
This is the helper documented by n8n. Reading the buffer matters because n8n can store binary files separately from the execution JSON. A storage reference isn't the file's base64 content.
The sample processes one PDF. For a workflow with several items, process each item deliberately and give each intended output its own idempotency key. Don't assume the first item represents every file.
Configure the fill request
In the HTTP Request node, use:
- Method:
POST - URL:
https://formrail.voltenworks.com/v1/fill - Authentication: Generic Credential Type, then Header Auth
- Send Body: enabled, JSON, using the expression
{{ $json }} - Header
Idempotency-Key:formrail-{{ $execution.id }}for this single-file example - Response Format: File
Only the PDF bytes are base64. The request itself is JSON, with pdf, data and flatten properties. Don't turn the whole request into a binary attachment.
Run the workflow manually. The last node should return a binary PDF. Download it and check the visible project name, service selection and checkbox. Once that works, connect the binary output to your own storage step.
Replace the sample template
Download your own form from Drive or another source, then inspect it in the FormRail workspace. The PDF needs existing AcroForm fields. Printed text and scans don't become fillable just because they're inside a PDF.
Use the exact field names from inspection. Choice fields accept their listed values, and checkboxes take booleans. Test the data against /v1/validate before sending it to /v1/fill. A validation response can have HTTP 200 and valid: false, so check the flag and the returned issues.
For an existing system with different property names, export a JSON mapping and keep its templateHash with the template. FormRail checks that fingerprint before applying the mapping to a document.
Keep retries attached to the same job
The execution ID is convenient for a manual demonstration. In a production workflow, a whole new execution may have a new ID even when you're retrying the same business job.
Use a stable reference such as your own request ID plus a revision number. Persist it with the input so the PDF bytes, data and key remain the same on retry. FormRail will regenerate a completed request without spending another credit. Changed data needs a new key. A confirmed failed request also keeps its stored error: correct the problem and use a new key. Reuse the original key when the outcome is still unknown, such as a lost response.
The free account includes 25 fills. Inspecting and validating use no credits, within the request limits. Files are limited to 2 MiB, 50 pages and 200 fields. Unsupported templates or values produce errors you can handle before passing a document to the next step.
I'd keep the first run manual until you've reviewed the returned PDF. That's also a useful place to stop when a template changes.