Jotform + QuickBooks invoices, Gmail reminders done
You close the deal, the client fills out the form… and then invoicing turns into a mini project. Copy details into QuickBooks. Double-check the line item. Send the invoice. Then remember to follow up when it goes overdue.
This Jotform QuickBooks invoices setup hits freelancers and service providers hardest, because cash flow is personal. Agency owners feel it too, especially when a “quick reminder” turns into a messy email thread. The outcome is simple: invoices go out automatically, reminders go out on schedule, and you stop leaking time and money.
Below is the exact workflow logic, the real-world results you can expect, and what you’ll need to run it reliably without babysitting it.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Jotform + QuickBooks invoices, Gmail reminders done
flowchart LR
subgraph sg0["Schedule reminders Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Receive form submission"]
n1@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If", pos: "b", h: 48 }
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/quickbooks.svg' width='40' height='40' /></div><br/>Get the product"]
n3["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/quickbooks.svg' width='40' height='40' /></div><br/>Create the invoice"]
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/quickbooks.svg' width='40' height='40' /></div><br/>Send the invoice"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/quickbooks.svg' width='40' height='40' /></div><br/>Check if the customer exists"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/quickbooks.svg' width='40' height='40' /></div><br/>Create the customer"]
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/quickbooks.svg' width='40' height='40' /></div><br/>Update the customer"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Format data"]
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Add customer id"]
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Add item id"]
n11@{ icon: "mdi:swap-vertical", form: "rounded", label: "Add reminders config", pos: "b", h: 48 }
n12@{ icon: "mdi:cog", form: "rounded", label: "Insert invoice id to DB", pos: "b", h: 48 }
n13@{ icon: "mdi:cog", form: "rounded", label: "Get Invoices", pos: "b", h: 48 }
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/quickbooks.svg' width='40' height='40' /></div><br/>Get the invoice"]
n15@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If2", pos: "b", h: 48 }
n16@{ icon: "mdi:robot", form: "rounded", label: "AI Agent", pos: "b", h: 48 }
n17@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model", pos: "b", h: 48 }
n18@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n19@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule reminders trigger", pos: "b", h: 48 }
n20@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop over invoices", pos: "b", h: 48 }
n21@{ icon: "mdi:cog", form: "rounded", label: "Get today's sent reminders", pos: "b", h: 48 }
n22@{ icon: "mdi:cog", form: "rounded", label: "Increase sent reminders", pos: "b", h: 48 }
n23@{ icon: "mdi:cog", form: "rounded", label: "Delete invoice", pos: "b", h: 48 }
n24@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If3", pos: "b", h: 48 }
n25@{ icon: "mdi:message-outline", form: "rounded", label: "Send reminder email", pos: "b", h: 48 }
n26@{ icon: "mdi:message-outline", form: "rounded", label: "Send reminders sent summary", pos: "b", h: 48 }
n1 --> n7
n1 --> n6
n15 --> n12
n15 --> n13
n24 --> n23
n24 --> n20
n18 --> n25
n18 --> n23
n18 --> n20
n16 --> n26
n10 --> n3
n8 --> n5
n13 --> n20
n23 --> n20
n9 --> n2
n14 --> n18
n2 --> n10
n4 --> n11
n17 -.-> n16
n3 --> n4
n20 --> n21
n20 --> n14
n6 --> n9
n25 --> n22
n7 --> n9
n11 --> n15
n22 --> n24
n0 --> n8
n21 --> n16
n19 --> n11
n5 --> n1
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n19 trigger
class n16 ai
class n17 aiModel
class n1,n15,n18,n24 decision
class n0 api
class n8,n9,n10 code
classDef customIcon fill:none,stroke:none
class n0,n2,n3,n4,n5,n6,n7,n8,n9,n10,n14 customIcon
The Problem: Invoices Go Out Late, and Follow-Ups Slip
Manual invoicing breaks in boring, expensive ways. A Jotform submission lands, you tell yourself you’ll “invoice after lunch,” and suddenly it’s tomorrow. Then you need to find the form entry again, retype the customer details into QuickBooks Online, pick the right item, and pray you didn’t fat-finger the email address. After that comes the worst part: chasing. Not because you enjoy it, but because forgetting one reminder can mean waiting an extra week (or longer) to get paid. The work isn’t hard. It’s constant.
It adds up fast. Here’s where it breaks down in day-to-day operations.
- Re-entering customer and order details from Jotform into QuickBooks takes about 15 minutes per invoice when you include checking and corrections.
- Invoices go out later than they should, which quietly pushes payments later too.
- Reminder emails live in someone’s head (or calendar), so follow-ups are inconsistent and easy to miss.
- When a client replies to an old invoice email thread, it becomes a scavenger hunt to confirm status and next steps.
The Solution: Turn Form Submissions Into Invoices (and Reminders) Automatically
This n8n workflow connects Jotform, QuickBooks Online, and Gmail so the “paperwork” side of selling stops depending on your memory. A new Jotform submission triggers the automation, which cleans up the incoming data, checks QuickBooks to see if the customer already exists, and then updates the profile or creates a new one. Next, it pulls the correct product or service item from QuickBooks, generates the invoice, and emails it out right away. After that, it stores key invoice details in an internal table so n8n can keep track of what’s still unpaid. Every morning at 8 AM, it reviews open invoices, decides who should get a reminder today, sends the email via Gmail, and logs that it was sent.
The workflow starts with a form submission (or a daily 8 AM schedule for reminders). In the middle, QuickBooks handles customers, items, and invoice creation while n8n keeps a clean tracking record. At the end, clients receive the invoice and follow-ups automatically, and you receive a short reminder summary email.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you get 15 paid inquiries a week through Jotform and you invoice every one. Manually, it’s maybe 15 minutes to create and send each QuickBooks invoice plus another 10 minutes later to check status and send a follow-up, which is about 6 hours a week. With this workflow, you spend about 5 minutes setting up the form mapping once, then invoicing is automatic and the 8 AM reminder run handles follow-ups. You basically get your afternoons back.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Jotform to collect customer and order details
- QuickBooks Online to create customers, items, invoices
- Gmail to send reminder emails and summaries
- OpenAI API key (get it from the OpenAI API dashboard)
Skill level: Intermediate. You’ll connect accounts, map form fields, and paste a table ID for invoice tracking.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A Jotform submission triggers the invoice path. When the form is submitted, n8n receives the payload through a webhook and quickly checks that the required fields are present.
Customer details get cleaned up and matched in QuickBooks. The workflow normalizes the submission (formatting, missing fields, and naming), then searches QuickBooks Online for an existing customer. If one is found, it updates key fields like billing address; if not, it creates a new customer profile.
The correct item is pulled, then the invoice is created and emailed. Based on the selected product or service, the workflow retrieves the matching QuickBooks item, generates the invoice record, and sends it via QuickBooks email so it looks consistent and professional.
A tracking record is stored so reminders are automatic. Invoice ID, remaining amount, currency, reminder counts, and the last sent time are stored in a data table. Every morning at 8 AM, n8n loops through unpaid invoices, fetches current invoice details from QuickBooks, then sends Gmail reminders when the timing and limits say it’s time.
You can easily modify reminder intervals to match your payment terms based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Webhook Trigger
This workflow starts when a form submission hits the webhook. Configure Incoming Form Webhook to accept incoming POST requests from your form tool.
- Add and open Incoming Form Webhook.
- Set HTTP Method to
POST. - Set Path to
ebee0263-fc61-414f-a9cc-faf3269ce30d. - Copy the production URL and paste it into your form platform’s webhook settings.
Step 2: Configure the Schedule Trigger
Daily reminders are driven by a schedule. Daily Reminder Trigger runs every morning and feeds the reminder processing branch.
- Add and open Daily Reminder Trigger.
- Set the schedule rule to run daily at
8(triggerAtHour). - Confirm it connects to Set Reminder Settings as shown in the workflow.
Step 3: Connect QuickBooks
QuickBooks is the primary system for customer and invoice operations. Multiple nodes use the same OAuth connection.
- Open any QuickBooks node (e.g., Lookup Customer).
- Credential Required: Connect your quickBooksOAuth2Api credentials.
- Apply the same credentials to the following nodes: Fetch Product Item, Generate Invoice Record, Dispatch Invoice Email, Lookup Customer, Create Customer Profile, Revise Customer Profile, and Fetch Invoice Details.
Execution Flow: Incoming Form Webhook → Normalize Payload → Lookup Customer → Validate Submission → Revise Customer Profile or Create Customer Profile → Append Customer ID.
Step 4: Set Up Data Normalization and Customer/Product Linking
This step prepares consistent data for customer creation and invoice creation.
- In Normalize Payload, keep the provided JavaScript Code to extract address and customer fields from
$input.first().json.body. - In Lookup Customer, set the filter query to
=Where PrimaryEmailAddr = '{{ $json.customer.email }}'. - In Validate Submission, ensure the conditions check
{{$json}}and{{$json.Id}}exist. - In Create Customer Profile, map the fields using expressions like
{{ $('Normalize Payload').item.json.customer.name }}and address fields fromNormalize Payload. - In Revise Customer Profile, keep customerId as
{{ $json.Id }}and reuse the same mapped fields. - In Append Customer ID, keep the JS code that merges the customer ID into the normalized payload.
- In Fetch Product Item, keep Resource
item, OperationgetAll, Limit1, and the filter query=WHERE name = '{{ $json.item.name }}'. - In Append Item ID, keep the JS code that merges the item ID into the payload.
Step 5: Configure Invoice Creation and Reminder Storage
This section creates the invoice in QuickBooks, sends it, and stores it for reminders.
- In Generate Invoice Record, set Resource to
invoiceand Operation tocreate. - Set CustomerRef to
{{ $json.customer.id }}and Line → itemId to{{ $json.item.id }}. - In Dispatch Invoice Email, set Email to
{{ $('Append Item ID').item.json.customer.email }}and invoiceId to{{ $json.Id }}. - In Set Reminder Settings, keep the raw JSON output:
{"dataTableId":"","reminderIntervalsInDays":[2,3,5], isInvoiceTrigger: {{ $json["Day of week"] ? false : true }}}. - In Trigger Source Check, confirm the condition checks
{{ $json.isInvoiceTrigger }}to route between invoice storage and reminder retrieval. - In Store Invoice Entry, confirm the data table columns map from Dispatch Invoice Email and the dataTableId uses
{{ $('Set Reminder Settings').item.json.dataTableId }}.
Execution Flow: Append Item ID → Generate Invoice Record → Dispatch Invoice Email → Set Reminder Settings → Trigger Source Check → Store Invoice Entry.
Step 6: Configure Reminder Processing and AI Summary
The reminder engine pulls entries, evaluates if reminders are due, sends emails, and summarizes the day’s activity.
- In Retrieve Invoice Entries, set Operation to
getand Return All totruewith{{ $('Set Reminder Settings').item.json.dataTableId }}. - In Iterate Invoice List, leave default batch settings to cycle through entries.
- In Fetch Invoice Details, set invoiceId to
{{ $json.invoiceId }}. - In Route Reminder Logic, keep the “send now” condition expression:
{{ $json.Balance > 0 && DateTime.fromISO($('Iterate Invoice List').item.json.updatedAt).plus($('Set Reminder Settings').item.json.reminderIntervalsInDays[$('Iterate Invoice List').item.json.remindersSent], 'days').format('yyyy-MM-dd') == $now.format('yyyy-MM-dd') }}. - In Reminder Limit Check, keep the expression
{{ $json.remindersSent >= $('Set Reminder Settings').item.json.reminderIntervalsInDays.length }}to remove or loop invoices. - In Increment Reminder Count, set lastSentAt to
{{ $now.toISO() }}and remindersSent to{{ $('Iterate Invoice List').item.json.remindersSent + 1 }}. - In Pull Today's Reminders, keep the filter
{{ $now.startOf('day').toUTC().toString() }}and return all matching rows. - In Reminder Summary Agent, set Text to
{{ $('Pull Today's Reminders').all() }}. - Open OpenAI Chat Engine and select the model
gpt-4o-mini. - Credential Required: Connect your openAiApi credentials to OpenAI Chat Engine. The Reminder Summary Agent uses this model, so credentials must be added to the parent model node, not the agent.
Execution Flow: Retrieve Invoice Entries → Iterate Invoice List → Fetch Invoice Details → Route Reminder Logic → Send Reminder Notice → Increment Reminder Count → Reminder Limit Check → Remove Invoice Entry or Iterate Invoice List.
Step 7: Configure Email Outputs (Invoices, Reminders, Summary)
Two Gmail nodes handle reminder notifications and daily summaries.
- Open Send Reminder Notice and keep Send To as
{{ $json.BillEmail.Address }}. - Keep the HTML in Message as provided and the subject
Friendly Reminder: Your Invoice is Due Soon – {{ $json.DocNumber }}. - Open Email Reminder Summary and set Send To to your team email (replace
[YOUR_EMAIL]). - Keep Message as
{{ $json.output }}and subjectSummary of today's reminders sent. - Credential Required: Connect your Gmail credentials in both Send Reminder Notice and Email Reminder Summary (these nodes currently have no credentials configured).
Step 8: Test and Activate Your Workflow
Run end-to-end tests for both the webhook and scheduled reminder flows before activating.
- Use Execute Workflow on Incoming Form Webhook and send a real test payload from your form tool.
- Confirm a customer is found or created (Lookup Customer → Validate Submission) and an invoice is created and emailed (Generate Invoice Record → Dispatch Invoice Email).
- Manually run Daily Reminder Trigger to simulate the morning reminder run and confirm Send Reminder Notice emails are sent.
- Verify the AI summary email arrives from Email Reminder Summary with HTML output from Reminder Summary Agent.
- When successful, switch the workflow to Active to enable production use.
Common Gotchas
- QuickBooks Online credentials can expire or need specific permissions. If things break, check your connected app permissions in QuickBooks (and the token status in n8n credentials) first.
- If you’re using scheduled reminders at 8 AM or looping through many invoices, processing times vary. Bump up any waits (or reduce batch size) if downstream QuickBooks checks fail on empty or delayed responses.
- Gmail reminder copy can sound generic if you never touch it. Edit the “Send Reminder Notice” email content early, and keep it consistent with your brand voice so clients don’t ignore it.
Frequently Asked Questions
About an hour if your accounts and invoice items are already set up.
No. You’ll mostly connect accounts and map fields from the form to QuickBooks.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenAI API costs (usually a few dollars a month for light usage).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and you should. Update the “Set Reminder Settings” node to change intervals (the default is 2 days, then 3, then 5), and point it at your own data table ID. Common customizations include adding a “final notice” template, skipping reminders for specific clients, and changing the daily schedule trigger time.
Usually it’s expired credentials in n8n, so reconnect the QuickBooks Online credential and try again. If that’s not it, check that the QuickBooks company file is the right one and the connected user has permission to create customers and invoices. Rate limits can also show up when you process a big backlog, so reducing batch size in the loop often fixes it. Honestly, most “random” failures are just permission scope or token refresh issues.
On n8n Cloud, it depends on your execution limit, but most small teams run hundreds of invoices a month without issue. If you self-host, there’s no fixed execution cap; the practical limit is your server and QuickBooks API responsiveness.
Sometimes. n8n is a better fit when you want a tracking table for reminders, branching logic for “send/skip/delete,” and the option to self-host for high volume without per-task pricing. Zapier or Make can be faster for a basic “form → invoice” push, but chasing logic gets messy. If you want the reminders plus auditability, n8n tends to feel sturdier. Talk to an automation expert if you’re deciding between platforms.
Once this is running, invoicing stops being a task you “get around to.” The workflow handles the repetitive follow-ups, and you keep the relationship (and the cash flow) moving.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.