Description
n8n-nodes-netsuite-v2





A production-grade n8n community node for Oracle NetSuite, built by SolutionLab (Avishai Asaf). Connects to the NetSuite REST API using OAuth 2.0 Client Credentials with Certificate (Machine-to-Machine / JWT PS256) – the most secure, fully automated authentication method available for server-to-server integrations.
3 resources. 11 operations. Polling triggers. SuiteQL templates. Zero user interaction required for authentication.
—
Why This Node?
Standard NetSuite integrations in n8n rely on OAuth 2.0 Authorization Code flow, which requires a browser-based login, manual token refresh, and session management. This creates fragile automations that break when tokens expire or when running in headless environments.
This node was built by SolutionLab to solve three specific production bottlenecks:
Fully Automated M2M Authentication
OAuth 2.0 Client Credentials with Certificate eliminates all user interaction. The node constructs a JWT, signs it with PS256 (RSASSA-PSS + SHA-256), and exchanges it for an access token – entirely in the background. Tokens are cached per credential and automatically refreshed with a 5-minute safety buffer before expiry. No browser sessions. No token expiry surprises. No manual intervention.
Robust Certificate Handling
Real-world NetSuite certificate integrations frequently fail on PEM format edge cases – especially when private keys are pasted through web UIs, environment variables, or secret managers. This node normalizes every variant automatically:
- Standard multi-line PEM with proper 64-character line breaks
- Single-line keys with escaped
ncharacters - Raw base64 content without BEGIN/END headers
- Keys with
PRIVATE KEY,RSA PRIVATE KEY, orEC PRIVATE KEYheaders - Query Templates – Start with built-in templates for common queries (Active Customers, Recent Sales Orders, Open Invoices, Inventory Levels, Employee Directory, Vendor Bills) or write your own
- Automatic Pagination – When “Return All” is enabled, the node paginates through results using NetSuite’s
hasMoreflag and offset-based pagination - Configurable Limit – When “Return All” is disabled, returns up to the specified limit (default: 1000)
- Transient Preferences – Requests include the
Prefer: transientheader for optimized response handling
Enterprise API Coverage with Automatic Pagination
SuiteQL queries and REST Record listings automatically paginate through all results when “Return All” is enabled. NetSuite’s structured error responses (o:errorDetails, o:errorCode) are parsed and surfaced as readable messages instead of raw HTTP errors.
—
Enterprise Features
REST Record Operations
Full CRUD operations on any NetSuite record type via the SuiteTalk REST API.
| Operation | Method | Description |
|———–|——–|————-|
| Create | POST | Create a record with a JSON body |
| Get | GET | Retrieve a single record by internal ID |
| Get Many | GET | List records with filtering, field selection, and sub-resource expansion |
| Update | PATCH | Partial update – only the fields you include are modified |
| Upsert | PUT | Create or update a record by external ID – ideal for syncing data from external systems |
| Delete | DELETE | Remove a record by internal ID |
Dynamic Record Types – The record type dropdown is populated automatically from NetSuite’s metadata catalog (/services/rest/record/v1/metadata-catalog). If the catalog is unavailable, the node falls back to 20 common record types including Customer, Contact, Invoice, Sales Order, Purchase Order, Journal Entry, and more.
Get Many Pagination – Enable “Return All” to automatically follow NetSuite’s rel:next pagination links until all records are retrieved. When disabled, a single page of results is returned up to the configured limit.
Additional Options:
| Option | Available On | Type | Description |
|——–|————-|——|————-|
| Fields | Get | String | Comma-separated list of field names to return (reduces payload size) |
| Expand Sub-Resources | Get | Boolean | Include sublists and line items in the response |
> Tip: Need to filter records or select specific fields? Use the SuiteQL resource — it supports full SQL-like queries with WHERE clauses, JOINs, and field selection.
SuiteQL
Execute SQL-like queries against your NetSuite data using Oracle’s SuiteQL syntax.
Restlet Operations
Call custom SuiteScript Restlet deployments with full HTTP method support.
| Method | Body | Use Case |
|——–|——|———-|
| GET | No | Retrieve data from a custom endpoint |
| POST | JSON | Submit data or trigger server-side logic |
| PUT | JSON | Update resources via a custom endpoint |
| DELETE | No | Remove resources via a custom endpoint |
Each request requires a Script ID and Deploy ID. Additional query string parameters can be passed as key-value pairs. The Restlet URL is constructed as:
https://{accountId}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script={scriptId}&deploy={deployId}
Platform Capabilities
accountId:consumerKey pair in a module-level store. Tokens are reused across workflow executions within the same n8n process and refreshed automatically 5 minutes before expiry.o:errorDetails and o:errorCode fields, providing specific error codes and messages instead of generic HTTP status text.https instead of n8n’s HTTP request helper, avoiding URL encoding issues with the client_assertion parameter.Polling Triggers
The NetSuite Trigger node monitors your NetSuite data for changes and starts workflows automatically. It uses SuiteQL to poll for records that have been created or modified since the last check.
| Event | Behavior |
|——-|———-|
| Record Created | Triggers when new records are created (uses datecreated field) |
| Record Updated | Triggers when existing records are modified, excluding newly created records |
| Record Created or Updated | Triggers on any change (uses lastmodifieddate field) |
Key capabilities:
datecreated and lastmodifieddate for custom records that use different field namesAND subsidiary = 1)SELECT *> Polling interval: Configured in the n8n workflow settings (default: every minute). The trigger establishes a baseline on first activation and only fires for records changed after that point.
—
Installation
Community Nodes (Recommended)
1. In n8n, go to Settings > Community Nodes
2. Enter n8n-nodes-netsuite-v2
3. Click Install
4. Restart n8n if prompted
Manual Installation
cd ~/.n8n/custom
npm install n8n-nodes-netsuite-v2
Then restart n8n.
> Compatibility: Requires n8n with n8n-workflow >= 2.12.0.
—
Quick Start
1. Install the node via Settings > Community Nodes > n8n-nodes-netsuite-v2
2. Configure credentials — follow the NetSuite Setup below to create an M2M integration and certificate
3. Create your first workflow — drag the NetSuite node onto the canvas, select Resource: SuiteQL, pick “Active Customers” template, and execute
That’s it — you’ll see your NetSuite customer list in under 5 minutes.
—
NetSuite Setup – Prerequisites
Before configuring the node in n8n, complete the following steps in your NetSuite account. Administrator access is required for initial setup.
Step 1: Create an Integration Record
Navigate to Setup > Integration > Manage Integrations > New.
| Setting | Value |
|———|——-|
| Name | e.g., “n8n Automation” |
| Client Credentials (M2M) Grant | Enabled |
| Authorization Code Grant | Disable (not used) |
| Token-Based Authentication | Not required |
Click Save, then copy the Consumer Key. The Consumer Secret is not used in the M2M flow.
Step 2: Generate a Certificate Key Pair
Generate an RSA key pair using OpenSSL (4096-bit recommended):
Generate private key
openssl genrsa -out private.pem 4096Generate public certificate (valid for 365 days)
openssl req -new -x509 -key private.pem -out public.pem -days 365
> Security: Keep private.pem secure. Its contents will be pasted into the n8n credential form. Never commit private keys to version control.
Step 3: Configure OAuth 2.0 Client Credentials Mapping
Navigate to Setup > Integration > OAuth 2.0 Client Credentials (M2M) Setup and click Create New.
| Field | Description |
|——-|————-|
| Entity | The user or employee associated with API calls |
| Role | The role that determines API permissions (see Step 4) |
| Integration | The integration record created in Step 1 |
Upload the public certificate (public.pem) from Step 2, then click Save.
Copy the Certificate ID – this is the kid value used in the JWT header for token signing.
Step 4: Configure Role Permissions
The role selected in Step 3 must have the following permissions based on which resources you plan to use:
| Resource | Required Permission | Navigation Path |
|———-|———————|—————–|
| REST Records (SuiteTalk) | REST Web Services | Setup > REST Web Services |
| SuiteQL | SuiteAnalytics Workbook | Reports > SuiteAnalytics Workbook |
| Restlets | SuiteScript | Setup > SuiteScript |
| All Resources | Log in using Access Tokens | Setup > Log in using Access Tokens |
> Tip: For initial testing, use the Administrator role. For production, create a custom role with only the minimum required permissions.
Step 5: Find Your Account ID
Navigate to Setup > Company > Company Information. Your Account ID is displayed at the top of the page.
12345671234567_SB1The node automatically normalizes the Account ID for API URLs (converts to lowercase and replaces underscores with hyphens).
—
Credential Configuration
When creating a new NetSuite Client Credentials (Certificate) credential in n8n, fill in the following fields:
| Field | Description | Where to Find |
|——-|————-|—————|
| Account ID | Your NetSuite Account ID | Setup > Company > Company Information |
| Consumer Key | Integration consumer key | Integration Record (Step 1) |
| Certificate ID | Certificate ID (JWT kid claim) | M2M Setup page (Step 3) |
| Certificate Private Key (PEM) | Full contents of your private key file | private.pem from Step 2 |
Private Key Format
Paste the entire contents of your private.pem file, including the -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- lines.
The node handles multiple formats automatically:
n charactersPRIVATE KEY, RSA PRIVATE KEY, or EC PRIVATE KEY headersTesting the Connection
Click Test in the n8n credential form to verify the connection. The test performs a full authentication cycle (JWT creation, token exchange) and calls GET /services/rest/record/v1/metadata-catalog with the Prefer: transient header. If the test passes, all four credential fields are valid and the certificate is correctly mapped in NetSuite.
—
Usage
Record Operations
Select Resource: Record to perform CRUD operations on NetSuite records.
#### Create a Record
Select Operation: Create, choose the record type, and provide a JSON body:
{
"companyname": "Acme Corp",
"email": "contact@acme.com",
"subsidiary": { "id": "1" }
}
#### Get a Record
Select Operation: Get, choose the record type, and enter the Record ID (internal ID).
Use Additional Options to control the response:
companyname,email,phone – return only specific fields#### Get Many Records
Select Operation: Get Many and choose the record type.
#### Update a Record
Select Operation: Update, choose the record type, enter the Record ID, and provide the fields to update:
{
"email": "new-email@acme.com",
"phone": "555-0100"
}
The update uses HTTP PATCH – only the fields you include will be modified.
#### Delete a Record
Select Operation: Delete, choose the record type, and enter the Record ID.
SuiteQL Queries
Select Resource: SuiteQL and Operation: Execute.
Enter your query using SuiteQL syntax:
SELECT id, companyname, email
FROM customer
WHERE isinactive = 'F'
SuiteQL supports JOIN operations for cross-table queries:
SELECT t.tranid, t.trandate, c.companyname
FROM transaction t
JOIN customer c ON t.entity = c.id
WHERE t.type = 'SalesOrd'
Options:
Restlet Operations
Select Resource: Restlet to call custom SuiteScript Restlet deployments.
| Field | Description |
|——-|————-|
| Script ID | The numeric script ID of the Restlet deployment |
| Deploy ID | The deployment ID (default: 1) |
| Operation | HTTP method: GET, POST, PUT, or DELETE |
| Body (JSON) | Request body for POST and PUT operations |
| Additional Parameters | Extra query string parameters (key-value pairs) |
Example POST body for a custom Restlet:
{
"action": "createRecord",
"recordType": "customrecord_project",
"values": {
"name": "New Project",
"custrecord_status": "1"
}
}
Trigger Setup
Add a NetSuite Trigger node as the first node in your workflow.
1. Select the Record Type to monitor (e.g., Customer, Sales Order, Invoice)
2. Choose the Event type: Created, Updated, or Created or Updated
3. Optionally specify Return Fields (e.g., id, companyname, email) to reduce payload size
4. Optionally add Additional Filters to narrow the scope (e.g., AND subsidiary = 1)
The trigger polls NetSuite at the interval configured in your workflow settings. On first activation, it records the current timestamp as a baseline – only records changed after activation will trigger the workflow.
#### Upsert a Record
Select Operation: Upsert, choose the record type, specify the External ID Field (default: externalid) and its Value, then provide the fields:
{
"companyname": "Acme Corp",
"email": "contact@acme.com",
"subsidiary": { "id": "1" }
}
If a record with the given external ID exists, it will be updated. Otherwise, a new record is created. This is ideal for syncing data from external systems.
—
Common Workflow Examples
These are popular workflows built with this connector. For implementation help, contact SolutionLab.
NetSuite → Google Sheets Daily Sync
Schedule a daily SuiteQL query (e.g., open invoices) and write results to a Google Sheet for reporting.
Shopify Order → NetSuite Sales Order
Use a Shopify trigger to capture new orders, then create NetSuite sales orders with customer lookup and item mapping.
Daily Invoice Aging Report via Email
Run “Open Invoices” SuiteQL template on a schedule, format as HTML table, and send via email to your finance team.
CRM Contact Sync
Use the polling trigger to detect new NetSuite customers, then sync to HubSpot, Salesforce, or your CRM of choice.
Inventory Alerts
Poll inventory levels with SuiteQL and send Slack alerts when stock falls below threshold.
—
Professional Services & Support
This node is developed and maintained by SolutionLab, a team that specializes in NetSuite integrations, SuiteScript development, and n8n workflow automation.
Free vs Professional
| Capability | Free (this connector) | Professional (SolutionLab) |
|—|—|—|
| Record CRUD + Upsert | Included | — |
| SuiteQL queries with templates | Included | — |
| Restlet invocation (all HTTP methods) | Included | — |
| Polling triggers | Included | — |
| Real-time webhook triggers | — | Custom SuiteScript User Event Script deployment |
| Bulk create/update/delete | — | Custom Restlet scripts for batch operations |
| Line item manipulation | — | Complex transaction workflows (invoices, sales orders with lines) |
| Multi-subsidiary configuration | — | NetSuite role, permission, and subsidiary setup |
| Custom field mapping & data transformation | — | Integration consulting and architecture |
What We Build
Contact
Book a consultation | avishai@solutionlabtech.com | LinkedIn
—
How Authentication Works
This section details the OAuth 2.0 Client Credentials with Certificate flow as implemented in this node.
JWT Construction
The node builds a JSON Web Token with the following structure:
Header:
{
"alg": "PS256",
"typ": "JWT",
"kid": ""
}
Payload:
{
"iss": "",
"scope": ["restlets", "rest_webservices"],
"iat": 1710000000,
"exp": 1710003600,
"aud": "https://.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token"
}
| Claim | Description |
|——-|————-|
| iss | The Consumer Key from the Integration Record |
| scope | Fixed scopes: restlets and rest_webservices |
| iat | Issued-at timestamp (current Unix time in seconds) |
| exp | Expiration timestamp (issued-at + 3600 seconds) |
| aud | The token endpoint URL (also the audience) |
| kid | The Certificate ID from the M2M Setup page |
JWT Signing
The JWT is signed using PS256 (RSASSA-PSS with SHA-256):
crypto.sign('sha256', signingInput, { key, padding: RSAPKCS1PSSPADDING, saltLength: RSAPSSSALTLENDIGEST })base64url(header).base64url(payload)header.payload.signatureToken Exchange
The signed JWT is exchanged for an access token via HTTP POST:
POST https://.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token
Content-Type: application/x-www-form-urlencodedgranttype=clientcredentials
&clientassertiontype=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=
The token exchange uses Node.js native https.request instead of n8n’s HTTP helper to avoid URL encoding issues with the client_assertion parameter.
Token Caching
Cache Key: {accountId}:{consumerKey}
Storage: Module-level Map (persists across workflow executions within the same n8n process)
Refresh: 300 seconds (5 minutes) before token expiry
When a cached token is still valid (more than 5 minutes until expiry), it is reused without making a new token exchange request. This minimizes API calls to the NetSuite token endpoint.
Authentication Hooks
Two hooks ensure the Bearer token is attached to every outgoing request:
1. Pre-Authentication – Runs before each httpRequestWithAuthentication call, exchanges credentials for a token, and stores it for the authenticate hook
2. Authenticate – Injects the Authorization: Bearer header into the request. Falls back to a direct token exchange if pre-authentication was skipped (e.g., during credential testing)
—
Troubleshooting
Error Reference
| Error Message | Cause | Solution |
|—————|——-|———-|
| NetSuite credential error: Account ID is empty | Account ID field not filled in | Enter your Account ID from Setup > Company > Company Information |
| NetSuite credential error: Consumer Key is empty | Consumer Key field not filled in | Enter the Consumer Key from the Integration Record |
| NetSuite credential error: Certificate ID is empty | Certificate ID field not filled in | Enter the Certificate ID from the M2M Setup page |
| NetSuite credential error: Certificate Private Key is empty | Private Key field not filled in | Paste the full contents of your private.pem file |
| JWT signing failed (PS256) | Invalid PEM format or unsupported key type | Verify the key is RSA. Run openssl rsa -check -in private.pem to validate. Ensure the full PEM content including BEGIN/END lines is pasted. |
| Token exchange failed (HTTP 400) | Mismatched credentials or key pair | Verify the Consumer Key matches the Integration Record. Verify the Certificate ID from M2M Setup. Ensure the private key corresponds to the uploaded public certificate. |
| Token exchange failed (HTTP 401) | M2M grant not enabled or mapping inactive | Verify the Integration Record has “Client Credentials (M2M) Grant” enabled. Verify the M2M Setup mapping is active. |
| Token exchange network error | DNS resolution failure or network issue | Check the Account ID format. Verify network connectivity to *.suitetalk.api.netsuite.com. |
| Token response is not valid JSON | Unexpected response from token endpoint | The NetSuite token endpoint may be temporarily unavailable. Retry after a few minutes. |
| Token response missing access_token | Token endpoint returned an unexpected payload | Verify the M2M Setup is complete and active. Check that the Integration Record is not disabled. |
| HTTP 403 on API calls | Insufficient role permissions | Add the required permissions to the role mapped in M2M Setup (see Step 4 in Prerequisites). |
Debugging Steps
1. Start with the credential test – Click “Test” in the n8n credential form. The error message indicates exactly which step failed: input validation, JWT signing, token exchange, or the API call itself.
2. Verify the key pair matches – The private key pasted into n8n must correspond to the public certificate uploaded to NetSuite. Both must be generated from the same OpenSSL key pair.
3. Check the M2M Setup status – Navigate to Setup > Integration > OAuth 2.0 Client Credentials (M2M) Setup in NetSuite and confirm your mapping shows as active.
4. Sandbox accounts – If using a sandbox, your Account ID includes _SB1 (or similar suffix). The node normalizes this automatically – no manual formatting required.
—
What’s New in v0.3.0
No breaking changes from v0.2.x. See CHANGELOG.md for full details.
—
Contributing
Clone the repository
git clone https://github.com/avishaiasaf/n8n-netsuite-node-v2.git
cd n8n-nodes-netsuite-v2Install dependencies
npm installBuild
npm run buildLint
npm run lint
Submit issues and pull requests via GitHub.
—
License
MIT