At a Glance — HubSpot to NetSuite Sync with n8n
- Two-way sync: HubSpot deal close → NetSuite Sales Order (real-time webhook); NetSuite invoice status → HubSpot contact (scheduled every 5–10 min)
- HubSpot auth: Private App access token — Settings → Integrations → Private Apps; grant crm.objects.contacts/deals/companies.read scopes
- NetSuite auth: Token-Based Authentication — 4 credentials needed: Consumer Key, Consumer Secret, Token ID, Token Secret + your Account ID
- Deal trigger: Subscribe to
deal.propertyChangeondealstage; filter for your Closed Won internal stage value in n8n with an If node - Customer matching: SuiteQL query by email → create NetSuite Customer if not found → store NS Customer ID in HubSpot contact property to skip future lookups
- Key NetSuite endpoints:
/record/v1/salesOrderfor creating orders;/services/rest/query/v1/suiteqlfor data queries
Why HubSpot and NetSuite need to talk
For SaaS and services companies, HubSpot is often the system of record for the entire pre-sales process — contacts, companies, deals, quotes. NetSuite takes over at the point of contract: Sales Orders, fulfillment, invoicing, and revenue recognition. The handoff between these two systems is where manual work accumulates and errors compound.
Without integration, a deal closed in HubSpot triggers an email to finance, who manually creates the NetSuite Sales Order. That process introduces lag, typos, and mismatched customer records. With n8n connecting them, the moment a deal stage changes to Closed Won, a NetSuite Sales Order is created automatically — matched to the right Customer, with correct line items, currency, and billing address.
The sync works in both directions. NetSuite sends invoice status and payment data back to HubSpot so account managers can see whether a customer is paid-up or overdue without logging into NetSuite. This closes the loop between sales and finance without shared logins or manual reporting.
Authentication: connecting n8n to both platforms
HubSpot
Use a HubSpot Private App (Settings → Integrations → Private Apps). Create the app, grant the scopes you need — at minimum crm.objects.contacts.read, crm.objects.deals.read, and crm.objects.companies.read — and copy the access token. In n8n, add HubSpot credentials using this token. The HubSpot node handles authentication automatically once credentials are configured.
NetSuite
NetSuite uses Token-Based Authentication (TBA). In NetSuite, navigate to Setup → Integration → Manage Integrations, create a new integration record, and note the Consumer Key and Consumer Secret. Then create a Token under Setup → Users/Roles → Access Tokens. In n8n, use the HTTP Request node with OAuth 1.0 authentication and these four values: Consumer Key, Consumer Secret, Token ID, Token Secret. Your NetSuite Account ID is also required — find it in Setup → Company → Company Information.
All NetSuite API calls go to https://[accountId].suitetalk.api.netsuite.com/services/rest/record/v1/ for record operations and https://[accountId].suitetalk.api.netsuite.com/services/rest/query/v1/suiteql for SuiteQL queries.
Direction 1: HubSpot deal → NetSuite Sales Order
This is the primary direction and the one with the highest ROI. When a deal closes in HubSpot, you want a Sales Order in NetSuite within seconds.
Step 1 — HubSpot webhook trigger
In HubSpot, go to Settings → Integrations → Webhooks and create a webhook subscription for deal.propertyChange on the dealstage property. Set the target URL to your n8n webhook endpoint. When a deal stage changes, HubSpot fires a POST to n8n with the deal ID.
In n8n, add an If node after the webhook trigger to check whether the new stage value corresponds to Closed Won. Stage values in HubSpot are internal IDs (like closedwon or a pipeline-specific string) — check your HubSpot pipeline settings to find the exact value.
Step 2 — Fetch full deal details from HubSpot
The webhook payload only contains the deal ID and changed property. Use the HubSpot node to fetch the full deal record with all properties you need for the NetSuite order:
- Deal name, amount, close date
- Associated contact ID and company ID
- Line items (if using HubSpot Products)
- Custom properties like billing address, PO number, currency
Also fetch the associated contact to get the email address — you'll use this to look up or create the NetSuite Customer.
Step 3 — Match or create the NetSuite Customer
Query NetSuite via SuiteQL to find an existing Customer by email:
SELECT id, entityId, email FROM customer WHERE email = '[email protected]' LIMIT 1
If a Customer exists, use their id as the entity reference on the Sales Order. If not, POST to /record/v1/customer to create one first. After creating, store the NetSuite Customer internal ID back into a HubSpot contact property (netsuite_customer_id) so future workflows can skip the lookup.
Step 4 — Create the NetSuite Sales Order
POST to /record/v1/salesOrder with the required fields:
entity: NetSuite Customer internal ID (from step 3)tranDate: deal close datecurrency: mapped from HubSpot deal currencyitem.items: array of line items with quantity, rate, and item referencememo: HubSpot deal name (useful for audit trail)custbody_hubspot_deal_id: HubSpot deal ID stored in a custom NetSuite field
The last field is your deduplication key — before creating the Sales Order, query for an existing one with that HubSpot deal ID: SELECT id FROM salesOrder WHERE custbody_hubspot_deal_id = '12345' LIMIT 1. If found, update it; if not, create it.
Custom field setup: Create custbody_hubspot_deal_id as a Free-Form Text field on the Sales Order transaction body in NetSuite Customization before going live. This is your idempotency key — without it, HubSpot stage-change webhooks that fire multiple times will create duplicate Sales Orders.
Direction 2: NetSuite invoice → HubSpot deal
The reverse direction syncs invoice and payment status back to HubSpot so account managers have visibility without leaving their CRM. This is typically polling-based since NetSuite doesn't have a simple outbound webhook system.
Set up a scheduled n8n workflow (every 15–30 minutes) that runs a SuiteQL query for invoices updated recently:
SELECT id, tranId, status, amountRemaining, custbody_hubspot_deal_id FROM invoice WHERE lastModifiedDate >= TO_DATE('2026-08-14 10:00:00', 'YYYY-MM-DD HH24:MI:SS') AND custbody_hubspot_deal_id IS NOT NULL
For each result, update the linked HubSpot deal using the stored deal ID. Map NetSuite invoice status to a HubSpot deal property — for example, a custom Invoice Status property that shows "Invoiced", "Partially Paid", or "Paid in Full". When amountRemaining is 0, mark the deal as fully paid.
Handling line items
The trickiest part of the HubSpot→NetSuite sync is line items. HubSpot's Products library and NetSuite's Items list won't have matching IDs — you need a mapping layer. The practical options are:
- SKU matching: Store the NetSuite Item internal ID in a HubSpot product custom property. When building the Sales Order, look up the NetSuite Item ID from the HubSpot line item's product ID.
- Name matching: Query NetSuite for an Item where
displayNamematches the HubSpot product name. Fragile if names drift between systems. - Fixed mapping table: For businesses with a small, stable product catalog, maintain a JSON mapping object in an n8n Code node that translates HubSpot product IDs to NetSuite Item IDs directly.
If HubSpot deals don't use Products (just a single deal amount), create a single line item on the NetSuite Sales Order using a generic "Services" or "Consulting" item and set the rate to the deal amount.
Error handling
NetSuite's REST API returns detailed error objects — parse the response body on non-2xx responses rather than treating all failures the same. Common errors include invalid item references (Item ID doesn't exist in NetSuite), currency mismatch (deal currency not enabled on the NetSuite subsidiary), and subsidiary not set (required field if your NetSuite account has multiple subsidiaries).
Set up an n8n Error Trigger workflow to notify via Slack when the sync fails, including the HubSpot deal ID, the error response body, and a direct HubSpot deal link. This lets your operations team investigate and manually create the order if needed — a recoverable fallback is better than a silent failure that's discovered at invoice time.
If you'd rather have this built and maintained than debugged step by step, Entech Solutions delivers production-grade n8n HubSpot integrations and NetSuite automation workflows — including full two-way CRM-ERP sync. Most HubSpot↔NetSuite projects go live in 2–4 weeks.