Many document automations generate a new PDF from HTML. That is the right tool for invoices and reports you design yourself. It is the wrong tool when a customer, carrier, government office, or employer requires its existing PDF to keep the same layout. The workflow below handles that second case: n8n receives a PDF and a JSON object. It asks JustFill for a one-time upload URL. It uploads the binary directly, without embedding base64 in the workflow. It opens the PDF and gets its detected or saved fields. It maps the JSON keys to reviewed field names. It fills the PDF and returns a short-lived download URL. I build JustFill, the service used in this example. The workflow JSON is importable and the integration uses normal HTTP Request nodes, so you can inspect every request before running it. Historical n8n execution screenshot, not evidence of the September strict-mapping update. The newer mapping-code test is described below. Why use a reviewed template for recurring forms? An LLM can help interpret an unfamiliar form, but repeated production runs should not have to rediscover the same coordinates. For recurring forms, open the PDF once, review the detected boxes, give them stable names such as customer_name, invoice_number, and total_amount, and save that layout. Every subsequent run can then match JSON keys deterministically. This is easier to test and avoids asking a model to make the same visual decision every time. Import the workflow An earlier reviewed workflow is available free in the official n8n template catalog. You can inspect the complete graph there before copying it into your workspace. For this tutorial, use the current strict-mapping JSON in the public JustFill MCP repository. Download that repository JSON and use Workflows → Import from File in n8n. The catalog copy may lag the repository update: the mapping node must reject unmatched keys and must not use substring matching. The workflow contains 10 executable nodes plus five purpose-specific sticky notes. It starts with an n8n Form Trigger so it can be tested without another integration. For a safe first run, use the repository's synthetic supplier-intake PDF with this JSON: { "company_name": "Northwind LLC", "vendor_reference": "V-1042", "remittance_email": "ap@northwind.example" } The sample contains no customer or restricted data and gives you three visible values to compare with the generated PDF. On September 5, 2026, the actual mapping Code node was tested against production MCP upload, open and fill responses: all three synthetic values reached a clean PDF, while an extra unknown JSON key stopped before filling. The temporary workspace and credential were cleaned up. This checks the production HTTP path and mapping code, not execution inside the n8n engine. Historical watermarked example showing the three field positions. This image is not the clean PDF generated by the September 5 HTTP and mapping-code test. The high-level path is: Form Trigger → Config → request_file_upload → POST the PDF binary to the one-time URL → open_pdf → map JSON keys to reviewed field names → fill_pdf → redirect to the filled PDF For a related integration demo, the uncut 53-second community-node recording shows the separate JustFill community node in n8n 2.34.4, with synthetic values and a masked credential. It does not show this ten-node HTTP workflow or the September strict-mapping update. The watermarked test-account result is visible; this is not a paid export demonstration. Configure the API key Create a JustFill API key under Account → API keys. For a local test, paste it into the workflow's Config node. Before using the workflow in production, move the key to an n8n credential or environment variable: values stored in a normal Code or Set node are part of the workflow definition. The hosted MCP endpoint is: https://justfill.app/api/mcp Calls are JSON-RPC over an HTTP Request node. A simplified tool call looks like this: { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "open_pdf", "arguments": { "upload_token": "TOKEN_FROM_THE_PREVIOUS_STEP" } } } The real imported workflow builds these objects in Code nodes and passes a serialized body to HTTP Request. That avoids an n8n expression-parser edge case around nested object braces. Send only the fields the PDF needs The example accepts JSON such as: { "customer_name": "Northwind LLC", "invoice_number": "INV-1042", "total_amount": "1250.00" } Key matching is exact after case and punctuation normalization, with Unicode letters preserved. There is no partial-name guessing. An unmatched key, ambiguous PDF name, or two keys targeting the same field stops the workflow before filling. Values may be text, finite numbers or booleans; null becomes an empty field. Arrays and nested objects are rejected. Do not pass an entire CRM, HR, or accounting record when the PDF needs only three values. A minimal input reduces accidental data exposure and makes failed mappings obvious. Replace the demo trigger Once the form-trigger version works, replace its first and last steps: Gmail or Outlook attachment → filled PDF link in a draft reply; Google Drive or Dropbox file → completed PDF in an output folder; webhook from an internal app → download URL in the JSON response; one spreadsheet row at a time → one filled PDF per n8n loop iteration. The returned result tells you whether the output is clean or watermarked. Keep that value visible in the workflow instead of silently delivering an unexpected output mode. What about an unfamiliar PDF? The repository also contains fill-pdf-ai-vision.json. It renders every detected page, asks one vision pass to map source values to field IDs, renders the exact proposed result, and asks a second vision pass to review the source and filled pages. A rejection or malformed review stops the workflow before fill_pdf. This automated review is a safety gate, not a replacement for human review of legal, tax, employment, medical, or compliance documents. When a form repeats, save its reviewed layout and switch to the deterministic workflow. Test with non-sensitive data first Before connecting a real data source: Use a public sample PDF and synthetic JSON values. Confirm that every value is visible in the expected box. Test a checkbox, a long value, and an empty optional field. Confirm the download URL expires as expected. Save the reviewed template only for the exact PDF version you tested. The import-ready examples and setup notes are here: https://justfill.app/integrations/n8n-fill-pdf-forms?utm_source=devto&utm_medium=referral&utm_campaign=b2b_pdf_automation_2026q3&utm_content=n8n_existing_pdf_article If your source is already Excel or CSV and you first want to verify the one-row-per-PDF workflow without building n8n, use the guided five-row browser sample: https://justfill.app/solutions/fill-pdf-from-excel?utm_source=devto&utm_medium=referral&utm_campaign=b2b_pdf_automation_2026q3&utm_content=n8n_article_excel_batch Disclosure: I am the solo developer of JustFill. I am sharing the workflow because the “keep this exact PDF layout” case is poorly served by generic HTML-to-PDF tutorials. AI disclosure: this tutorial was drafted and revised by AI coding agents for JustFill, with automated code checks. The linked workflow has executable mapping tests; the recording above is explicitly labeled as historical rather than evidence of the latest revision.