AutomationFlowsData & Sheets › Create Hubspot Companies & Tasks From Jotform Submissions with Google Sheets

Create Hubspot Companies & Tasks From Jotform Submissions with Google Sheets

ByRahi Uppal @rahiuppal on n8n.io

Automatically create or update HubSpot companies and generate follow-up tasks whenever a Jotform is submitted. All logs are stored to Google Sheets for traceability, transparency, and debugging. Capture marketing queries from your website’s Jotform form and immediately create…

Event trigger★★★★☆ complexity13 nodesJot Form TriggerHTTP RequestHubSpotGoogle Sheets
Data & Sheets Trigger: Event Nodes: 13 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #9394 — we link there as the canonical source.

This workflow follows the Google Sheets → 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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "0293a49f-3721-456a-9951-3c0c0fc8ba5d",
      "name": "JotForm Trigger",
      "type": "n8n-nodes-base.jotFormTrigger",
      "position": [
        640,
        416
      ],
      "parameters": {
        "form": "252808415357461"
      },
      "credentials": {
        "jotFormApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b85baa2e-77ed-4939-8158-be4da9c49b30",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1360,
        416
      ],
      "parameters": {
        "amount": 10
      },
      "typeVersion": 1.1
    },
    {
      "id": "f4ac75b3-4578-4134-a3da-0d5420d3f578",
      "name": "Create HubSpot Task",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1584,
        416
      ],
      "parameters": {
        "url": "https://api.hubapi.com/crm/v3/objects/tasks",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "neverError": true,
              "responseFormat": "json"
            }
          }
        },
        "jsonBody": "={\n  \"properties\": {\n    \"hs_task_subject\": \"{{ $('Format Jotform Data').item.json.hubspot_task_title || 'Jotform Marketing Query' }}\",\n    \"hs_task_body\": \"{{ \n        'Company: ' + ($('Format Jotform Data').item.json.company_name || 'Unknown Company') + '\\\\n' + \n        'Person: ' + ($('Format Jotform Data').item.json.full_name || 'Unknown') + '\\\\n' + \n        'Email: ' + ($('Format Jotform Data').item.json.email || 'N/A') + '\\\\n' + \n        'LinkedIn: ' + ($('Format Jotform Data').item.json.linkedin_profile || 'N/A') + '\\\\n' + \n        'Domain: ' + ($('Format Jotform Data').item.json.domain || 'N/A') + '\\\\n' + \n        'Marketing Budget (USD): ' + ($('Format Jotform Data').item.json.marketing_budget_usd || 'N/A') + '\\\\n' + \n        'Specific Query: ' + ($('Format Jotform Data').item.json.specific_query || 'No query provided.')\n    }}\",\n    \"hs_task_status\": \"NOT_STARTED\",\n    \"hs_task_priority\": \"HIGH\",\n    \"hs_task_type\": \"CALL\",\n    \"hs_timestamp\": \"{{ $('Format Jotform Data').item.json.task_timestamp || (new Date().toISOString()) }}\",\n    \"hubspot_owner_id\": \"{{ $('Format Jotform Data').item.json.assigned_owner_id || '82654288' }}\"\n  },\n  \"associations\": [\n    {\n      \"to\": {\n        \"id\": \"{{ $('Format Jotform Data').item.json.company_id || '' }}\"\n      },\n      \"types\": [\n        {\n          \"associationCategory\": \"HUBSPOT_DEFINED\",\n          \"associationTypeId\": 192\n        }\n      ]\n    }\n  ]\n}\n",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer <your pat token>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "2b7fc36d-c4ca-485a-88ca-cfa47a5da226",
      "name": "Create a company1",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        912,
        416
      ],
      "parameters": {
        "name": "={{ $json.CompanyName }}",
        "resource": "company",
        "additionalFields": {}
      },
      "credentials": {
        "hubspotApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2,
      "alwaysOutputData": true
    },
    {
      "id": "c17f50ae-ee93-4687-bb76-f9448775e7a0",
      "name": "Formating Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1184,
        416
      ],
      "parameters": {
        "jsCode": "const inputData = $input.all();\nconst formattedData = [];\n\nconst ownerAssignments = {\n  owner1: \"82654288\",\n  owner2: \"944860204\", // Replace with actual ID\n};\n\n// helper: safely unescape quotes if Jotform encodes them\nconst unescapeQuotes = (v) =>\n  typeof v === 'string'\n    ? v.replace(/\\\\'/g, \"'\").replace(/\\\\\"/g, '\"')\n    : v;\n\nfor (const { json: item } of inputData) {\n  // Extract and sanitize fields\n  const firstName       = unescapeQuotes(item[\"First Name\"] || item.first_name || '');\n  const lastName        = unescapeQuotes(item[\"Last Name\"] || item.last_name || '');\n  const fullName        = `${firstName} ${lastName}`.trim() || 'Unknown';\n  const email           = unescapeQuotes(item.Email || item.email || '');\n  const linkedinProfile = unescapeQuotes(item[\"Linkedin Profile\"] || item.linkedin || '');\n  const companyName     = unescapeQuotes(item[\"Company Name\"] || item.company_name || 'Unknown Company');\n  const marketingBudget = unescapeQuotes(item[\"Marketing Budget ( in USD )\"] || item.marketing_budget || '');\n  const domain          = unescapeQuotes(item.Domain || item.domain || '');\n  const specificQuery   = unescapeQuotes(item[\"Any Specific querry ?\"] || item.query || '');\n\n  // Task title\n  const taskTitle = `(Jotform) Marketing Query from ${fullName} (${companyName})`;\n\n  // Owner assignment (basic hash)\n  const companyHash = (companyName || '').length % 2;\n  const assignedOwnerId = companyHash === 0 ? ownerAssignments.owner1 : ownerAssignments.owner2;\n\n  // Timestamp (24 hrs from now)\n  const futureDate = new Date();\n  futureDate.setHours(futureDate.getHours() + 24);\n  const taskTimestamp = futureDate.toISOString();\n\n  // Final formatted structure\n  const formattedItem = {\n    first_name: firstName,\n    last_name: lastName,\n    full_name: fullName,\n    email: email,\n    linkedin_profile: linkedinProfile,\n    company_name: companyName,\n    marketing_budget_usd: marketingBudget,\n    domain: domain,\n    specific_query: specificQuery,\n    hubspot_task_title: taskTitle,\n    task_timestamp: taskTimestamp,\n    assigned_owner_id: assignedOwnerId,\n  };\n\n  formattedData.push({ json: formattedItem });\n}\n\nreturn formattedData;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "da057d1b-4a6e-4e28-8aee-b3636c16831c",
      "name": "Storel Logs",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2240,
        416
      ],
      "parameters": {
        "columns": {
          "value": {
            "Notes": "=This was created at {{ $json.createdAt }} & was updated at {{ $json.updatedAt }}",
            "domain": "={{ $json.properties.domain }}",
            "company": "={{ $json.properties.name }}",
            "HubspotCompanyID": "={{ $json.id }}"
          },
          "schema": [
            {
              "id": "company",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "company",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "No. of Stores",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "No. of Stores",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "domain",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "HubspotCompanyID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "HubspotCompanyID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "domain"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1117410898,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ETTxIAb6Kj69V7xInvYEdYqvKcV8mjE3BoT1a7ER5tE/edit#gid=1117410898",
          "cachedResultName": "AlreadyExistingHC"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1ETTxIAb6Kj69V7xInvYEdYqvKcV8mjE3BoT1a7ER5tE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ETTxIAb6Kj69V7xInvYEdYqvKcV8mjE3BoT1a7ER5tE/edit?usp=drivesdk",
          "cachedResultName": "Linkedin2Hubspot"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "a479a00e-a33e-4123-9887-ef98144d0ec3",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        16
      ],
      "parameters": {
        "width": 416,
        "height": 624,
        "content": "## \ud83e\uddfe JOTFORM TRIGGER\n\nThis workflow begins with a JotForm submission trigger.  \nIt captures the following fields submitted through the form:\n\n- **Name**\n- **First Name**\n- **Last Name**\n- **Email**\n- **LinkedIn Profile**\n- **Company Name**\n- **Marketing Budget (in USD)**\n- **Domain**\n- **Any Specific Query**\n\nEach submission is automatically passed to the next step for HubSpot company creation and task generation.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ce5c50c0-18f6-45d8-a74b-13c500fb3777",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        16
      ],
      "parameters": {
        "color": 6,
        "width": 416,
        "height": 624,
        "content": "## \ud83c\udfe2 HUBSPOT COMPANY CREATION & FORMATTER\n\nThis section uses the submitted **Company Name** to create a new company record in HubSpot (if it doesn\u2019t already exist).  \nThe **Formatter** node then processes all JotForm inputs into a structured, standardized format \u2014 ready for task creation in HubSpot.\n\nKey functions performed here:\n- Sanitizes all JotForm fields (name, email, domain, etc.)\n- Generates a follow-up task title automatically\n- Assigns a HubSpot owner based on company data\n- Prepares timestamps for scheduling tasks\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3231a6ce-d8f8-434b-af2b-fcb08d4a00ba",
      "name": "Set Company Domain",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        2016,
        416
      ],
      "parameters": {
        "url": "=https://api.hubapi.com/crm/v3/objects/companies/{{ $('Loop Over Items3').item.json.company_id }}",
        "method": "PATCH",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "jsonBody": "={\n  \"properties\": {\n    \"domain\": \"{{ $('Loop Over Items3').item.json.domain}}\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer < PAT >"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "968e7fc6-65fa-4385-aba8-2933bac8ed02",
      "name": "Wait10",
      "type": "n8n-nodes-base.wait",
      "position": [
        1808,
        416
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "565fce0c-493d-4171-a095-b16d9993b3a3",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1328,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 640,
        "content": "## \ud83d\udd01 HUBSPOT TASK CREATION\n\nThis section loops through the formatted data and sends HTTP requests to HubSpot to create tasks.  \nEach task includes all relevant submission details, such as company, contact, LinkedIn profile, and marketing query.\n\nCore logic:\n- Wait node prevents rate limit collisions\n- HubSpot API is called using a structured payload\n- Tasks are linked with their associated company records\n- Task priority, status, and owner are assigned automatically\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a332ddf0-e435-4371-b213-8699c3cf066f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1744,
        0
      ],
      "parameters": {
        "color": 3,
        "width": 400,
        "height": 640,
        "content": "## \ud83c\udf10 LOOP OVER & DOMAIN SETTING\n\nAfter the tasks are created, this section updates each HubSpot company with its corresponding **Domain** value using the id generating while creating company.  \nIt ensures that all newly created companies in HubSpot have their website field populated correctly.\n\nDetails:\n- Wait node ensures proper sequencing\n- The \u201cSet Company Domain\u201d HTTP request updates the HubSpot company record\n- Prevents duplicate or unlinked company entries\n"
      },
      "typeVersion": 1
    },
    {
      "id": "62fd01c6-f579-4fb3-9807-f414c2312bed",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        0
      ],
      "parameters": {
        "color": 2,
        "width": 256,
        "height": 624,
        "content": "## \ud83d\udcca STORING LOGS\n\nLogging is critical for transparency and debugging.  \nThis section safely records all processed submissions and API responses in a connected **Google Sheet**.\n\nBenefits:\n- Provides a full audit trail of workflow executions\n- Helps monitor form activity and HubSpot sync status\n- Simplifies debugging in case of failed API calls\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Create HubSpot Task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait10": {
      "main": [
        [
          {
            "node": "Set Company Domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Formating Data": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "JotForm Trigger": {
      "main": [
        [
          {
            "node": "Create a company1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create a company1": {
      "main": [
        [
          {
            "node": "Formating Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Company Domain": {
      "main": [
        [
          {
            "node": "Storel Logs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create HubSpot Task": {
      "main": [
        [
          {
            "node": "Wait10",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automatically create or update HubSpot companies and generate follow-up tasks whenever a Jotform is submitted. All logs are stored to Google Sheets for traceability, transparency, and debugging. Capture marketing queries from your website’s Jotform form and immediately create…

Source: https://n8n.io/workflows/9394/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Automatically enrich company records with comprehensive firmographic data by pulling domains from Google Sheets, setting up custom HubSpot fields, enriching through Sona API, and syncing complete prof

HTTP Request, Google Sheets, HubSpot
Data & Sheets

This template is ideal for solo store owners, eCommerce marketers, automation beginners, or anyone using Shopify and Gmail who wants to recover lost revenue without coding.

HTTP Request, Gmail, Twilio +3
Data & Sheets

PCN. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 60 nodes.

Google Sheets, HTTP Request, @N Octo N/N8N Nodes Json Database +3
Data & Sheets

The workflow automates the process of gathering extensive keyword data for a "Main Keyword." It starts by reading initial parameters from a Google Sheets template, creates a new dedicated Google Sheet

Google Sheets, Google Drive, HTTP Request
Data & Sheets

🔥 March Sale – n8n Community Members Get ideoGener8r for Just $27! (Reg. $47) Use Coupon Code: (Valid until 3/31/2025 for n8n community members)

HTTP Request, Google Drive, Google Sheets