This workflow corresponds to n8n.io template #9404 — we link there as the canonical source.
This workflow follows the Emailsend → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "Ov0kAaToP65xgc5h",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Landingpage -> PDF Form Fillout -> Email",
"tags": [],
"nodes": [
{
"id": "0ddb247e-85b8-4cf6-afd7-03853a8053c4",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
-672,
-48
],
"parameters": {
"url": "https://community.adobe.com/havfw69955/attachments/havfw69955/acrobat-reader/109709/1/EDIT%20OoPdfFormExample.pdf",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "2f4803e6-999e-4c7f-b782-3ea8ab5042cf",
"name": "PDF Form Fill (Fill PDF Fields)",
"type": "@custom-js/n8n-nodes-pdf-toolkit.PdfFormFill",
"position": [
-352,
-48
],
"parameters": {
"fields": {
"field": [
{
"name": "Given Name Text Box",
"value": "={{ $json.body.firstName }}"
},
{
"name": "Family Name Text Box",
"value": "={{ $json.body.lastName }}"
},
{
"name": "Address 1 Text Box",
"value": "={{ $json.body.address }}"
},
{
"name": "House nr Text Box",
"value": "={{ $json.body.houseNo }}"
},
{
"name": "Postcode Text Box",
"value": "={{ $json.body.postalCode }}"
},
{
"name": "City Text Box",
"value": "={{ $json.body.city }}"
},
{
"name": "Country Combo Box",
"value": "={{ $json.body.country }}"
},
{
"name": "Language 1 Check Box",
"value": "X"
}
]
}
},
"credentials": {
"customJsApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "eb6759e3-b65f-4d1a-9893-c1e3ad1386c3",
"name": "Get PDF Form Fields",
"type": "@custom-js/n8n-nodes-pdf-toolkit.GetFormFieldNames",
"position": [
-208,
416
],
"parameters": {},
"credentials": {
"customJsApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "9887ca8e-b5ca-4661-86b4-da496203d326",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-384,
272
],
"parameters": {
"width": 480,
"height": 320,
"content": "## Form Field Names (Optional)\nYou can use this module to read the names of the form fields."
},
"typeVersion": 1
},
{
"id": "a6cc6187-da30-4a93-a10e-81748e625d8f",
"name": "Send email",
"type": "n8n-nodes-base.emailSend",
"position": [
-80,
-48
],
"parameters": {
"text": "Hello,\n\nHere is the completed PDF form.\n\nBest\nHenrik",
"options": {
"attachments": "data"
},
"subject": "Filled PDF Form",
"toEmail": "user@example.com",
"fromEmail": "user@example.com",
"emailFormat": "text"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "dc31be04-a1f7-479b-85f6-0218e7f51cb5",
"name": "FormData Endpoint",
"type": "n8n-nodes-base.webhook",
"position": [
-944,
-48
],
"parameters": {
"path": "db534064-7845-44c2-abdd-3f2189772a27",
"options": {
"responseData": "<h1>Hello World</h1>"
},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "ed2c79aa-eb59-4bee-ad06-e97bbda13992",
"name": "HTML for Landingpage",
"type": "n8n-nodes-base.html",
"position": [
-416,
-448
],
"parameters": {
"html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Request a Quote</title>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n</head>\n<body class=\"bg-gray-50 min-h-screen flex flex-col items-center justify-center p-6\">\n\n <div class=\"w-full max-w-md bg-white shadow-xl rounded-2xl p-8\">\n <h1 class=\"text-2xl font-semibold text-gray-800 mb-4 text-center\">\n Request a Quote\n </h1>\n <p class=\"text-gray-500 text-center mb-6\">\n Fill in your personal details to receive your insurance quote.\n </p>\n\n <!-- Success Message -->\n <div id=\"success-message\" class=\"hidden bg-green-50 border border-green-200 text-green-700 p-4 rounded-xl text-center mb-4\">\n \u2705 Your request has been successfully submitted!\n </div>\n\n <!-- Error Message -->\n <div id=\"error-message\" class=\"hidden bg-red-50 border border-red-200 text-red-700 p-4 rounded-xl text-center mb-4\">\n \u274c Something went wrong. Please try again.\n </div>\n\n <!-- Form -->\n <form id=\"quote-form\" class=\"space-y-4\">\n <div>\n <label class=\"block text-gray-700 font-medium mb-1\">First Name</label>\n <input\n type=\"text\"\n name=\"firstName\"\n required\n class=\"w-full border border-gray-300 rounded-xl px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none\"\n />\n </div>\n\n <div>\n <label class=\"block text-gray-700 font-medium mb-1\">Last Name</label>\n <input\n type=\"text\"\n name=\"lastName\"\n required\n class=\"w-full border border-gray-300 rounded-xl px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none\"\n />\n </div>\n\n <div>\n <label class=\"block text-gray-700 font-medium mb-1\">Address</label>\n <input\n type=\"text\"\n name=\"address\"\n required\n class=\"w-full border border-gray-300 rounded-xl px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none\"\n />\n </div>\n\n <div>\n <label class=\"block text-gray-700 font-medium mb-1\">House No.</label>\n <input\n type=\"text\"\n name=\"houseNo\"\n required\n class=\"w-full border border-gray-300 rounded-xl px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none\"\n />\n </div>\n\n <div>\n <label class=\"block text-gray-700 font-medium mb-1\">Postal Code</label>\n <input\n type=\"text\"\n name=\"postalCode\"\n required\n class=\"w-full border border-gray-300 rounded-xl px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none\"\n />\n </div>\n\n <div>\n <label class=\"block text-gray-700 font-medium mb-1\">City</label>\n <input\n type=\"text\"\n name=\"city\"\n required\n class=\"w-full border border-gray-300 rounded-xl px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none\"\n />\n </div>\n\n <div>\n <label class=\"block text-gray-700 font-medium mb-1\">Country</label>\n <input\n type=\"text\"\n name=\"country\"\n required\n class=\"w-full border border-gray-300 rounded-xl px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none\"\n />\n </div>\n\n <button\n type=\"submit\"\n id=\"submit-btn\"\n class=\"w-full bg-blue-600 text-white py-3 rounded-xl hover:bg-blue-700 transition-all\"\n >\n Submit Request\n </button>\n </form>\n </div>\n\n <footer class=\"mt-6 text-gray-400 text-sm\">\n \u00a9 <span id=\"year\"></span> SecureQuote Insurance Co.\n </footer>\n\n <script>\n document.getElementById('year').textContent = new Date().getFullYear();\n\n const form = document.getElementById('quote-form');\n const successMsg = document.getElementById('success-message');\n const errorMsg = document.getElementById('error-message');\n const submitBtn = document.getElementById('submit-btn');\n\n form.addEventListener('submit', async function (e) {\n e.preventDefault();\n successMsg.classList.add('hidden');\n errorMsg.classList.add('hidden');\n submitBtn.disabled = true;\n submitBtn.textContent = \"Submitting...\";\n\n const formData = {\n firstName: form.firstName.value,\n lastName: form.lastName.value,\n address: form.address.value,\n houseNo: form.houseNo.value,\n postalCode: form.postalCode.value,\n city: form.city.value,\n country: form.country.value,\n };\n\n try {\n const response = await fetch(\"{{ $json.FormEndpoint }}\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(formData),\n });\n\n if (response.ok) {\n form.reset();\n successMsg.classList.remove('hidden');\n } else {\n throw new Error(\"Response not OK\");\n }\n } catch (err) {\n console.error(\"Form submit error:\", err);\n errorMsg.classList.remove('hidden');\n }\n\n submitBtn.disabled = false;\n submitBtn.textContent = \"Submit Request\";\n });\n </script>\n</body>\n</html>\n"
},
"typeVersion": 1.2
},
{
"id": "2e846775-2f6d-416a-bb3d-28ee09b70622",
"name": "Landingpage Endpoint",
"type": "n8n-nodes-base.webhook",
"position": [
-928,
-448
],
"parameters": {
"path": "db534064-7845-44c2-abdd-3f2189772a27",
"options": {},
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "af372421-70db-4286-9d04-12f144bf4da1",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-96,
-448
],
"parameters": {
"options": {},
"respondWith": "text",
"responseBody": "={{ $json.html }}"
},
"typeVersion": 1.4
},
{
"id": "92e309c6-0ad8-4c47-a3ad-126eb2f13ba7",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-992,
-560
],
"parameters": {
"width": 1088,
"height": 320,
"content": "## Landingpage Server\nYou can access the landing page at the webhook address."
},
"typeVersion": 1
},
{
"id": "a415ac7c-230d-4839-8ccf-38ecfb4cfffd",
"name": "Set Form Endpoint",
"type": "n8n-nodes-base.set",
"position": [
-672,
-448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "509804fc-dbfa-472d-87d3-1f683e146856",
"name": "FormEndpoint",
"type": "string",
"value": "={{ $json.webhookUrl }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "39063a8c-2114-432e-89da-7847747257bb",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-992,
-144
],
"parameters": {
"width": 1088,
"height": 320,
"content": "## FormData Endpoint\nThe data for the form is received here from the landing page."
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "3817dfcd-3a8b-4c27-89cb-a801860141d1",
"connections": {
"HTTP Request": {
"main": [
[
{
"node": "PDF Form Fill (Fill PDF Fields)",
"type": "main",
"index": 0
},
{
"node": "Get PDF Form Fields",
"type": "main",
"index": 0
}
]
]
},
"FormData Endpoint": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Set Form Endpoint": {
"main": [
[
{
"node": "HTML for Landingpage",
"type": "main",
"index": 0
}
]
]
},
"HTML for Landingpage": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Landingpage Endpoint": {
"main": [
[
{
"node": "Set Form Endpoint",
"type": "main",
"index": 0
}
]
]
},
"PDF Form Fill (Fill PDF Fields)": {
"main": [
[
{
"node": "Send email",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
customJsApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
> ⚠️ Notice: > Community nodes like @custom-js/n8n-nodes-pdf-toolkit-v2 can be installed on both self-hosted and Cloud instances of n8n. Just search for it via CustomJS.
Source: https://n8n.io/workflows/9404/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
세미나 데모 용 워크플로우. Uses httpRequest, emailSend. Webhook trigger; 17 nodes.
worklow_doc. Uses httpRequest, readBinaryFile, n8n-nodes-docxtemplater, emailSend. Webhook trigger; 15 nodes.
WF2 - Upload Manual | JurisAI. Uses httpRequest, emailSend. Webhook trigger; 15 nodes.
Deliver personalized files instantly after PayPal transactions using n8n – without writing a single backend line.
This workflow automates real-time student tracking using iOS Shortcuts and geolocation data, notifying both teachers and parents based on geofenced logic.