Connect to NetSuite
Pull financial and operational data out of NetSuite into PlaidCloud tables with SuiteQL. This guide takes you from an empty NetSuite integration to a scheduled, typed pull. For the field-by-field reference behind it, see the NetSuite REST Connector.
Prerequisites
Section titled “Prerequisites”You need, in NetSuite:
- OAuth 2.0 and REST Web Services enabled (Setup > Company > Enable Features > SuiteCloud).
- An RSA key pair — the public certificate uploaded to NetSuite, the private key kept for PlaidCloud.
- A certificate id (the JWT
kid, from uploading the public cert), a client id (from the integration record), and your account id (production1234567or sandbox1234567_SB1). - A role with REST Web Services, Log in using OAuth 2.0 Access Tokens, SuiteAnalytics Workbook (if your queries touch analytics), and view access to the records you’ll read.
The full NetSuite-side steps — generating the key pair, uploading the certificate, and creating the integration — are in the reference’s NetSuite-Side Setup. Complete those first; this guide assumes you have the four values in hand.
Create the Connection
Section titled “Create the Connection”-
Open Tools > Connections and click
New Connection. -
Choose NetSuite from the menu.
-
Fill in the fields:
Field Value Name A friendly name, e.g. NetSuite Prod.Oauth2 client id The client id from the integration record. Netsuite certificate id The certificate id ( kid) from the public-cert upload.Netsuite account id Your account id, e.g. 1234567or1234567_SB1.Netsuite private certificate The full private-key PEM block, pasted multi-line. -
Click
Create.
Smoke-Test the Connection
Section titled “Smoke-Test the Connection”Confirm the credentials work before you build anything on top of them.
-
Add a REST Request step to a workflow.
-
On the Request tab, set Connection to your NetSuite connection, Method to
POST, and Endpoint to/services/rest/query/v1/suiteql. -
In the Body, put a tiny bounded query:
{"q": "SELECT id FROM account WHERE ROWNUM <= 1"} -
Click Send Test Request.
Build the Pull Step
Section titled “Build the Pull Step”With the smoke test green, turn the step into a real pull.
-
In the Body, write your SuiteQL query with a deterministic
ORDER BY. For copy-paste starting points — journal entries, trial balance, P&L, balance sheet, open A/R, sales orders, POs, inventory — see NetSuite SuiteQL Query Examples.Financial — GL transaction lines for a period:
{"q": "SELECT tl.transaction AS transaction_id, TO_CHAR(t.trandate, 'YYYY-MM-DD') AS tran_date, a.acctnumber AS account_number, tl.subsidiary AS subsidiary_id, tl.foreignamount AS amount FROM transactionline tl JOIN transaction t ON t.id = tl.transaction JOIN account a ON a.id = tl.expenseaccount WHERE t.trandate BETWEEN TO_DATE('2026-01-01','YYYY-MM-DD') AND TO_DATE('2026-01-31','YYYY-MM-DD') ORDER BY tl.transaction, tl.id"}Operational — open sales orders by customer:
{"q": "SELECT so.tranid AS order_number, so.entity AS customer_id, TO_CHAR(so.trandate, 'YYYY-MM-DD') AS order_date, so.status AS order_status FROM transaction so WHERE so.type = 'SalesOrd' AND so.status = 'SalesOrd:B' ORDER BY so.id"} -
Leave the Pagination & Parsing controls and the
Prefer/Content-Typeheaders alone — the NetSuite connection injects them. -
On the Response tab, keep the destination as Table and define the columns with real types:
Currency/Decimalfor amounts,Date/Datetimefor dates,BooleanforT/Fflags. SuiteQL returns everything as strings; the typed columns tell PlaidCloud how to coerce them.
Verify and Schedule
Section titled “Verify and Schedule”-
Run the step (see Running one step in a workflow) and check the target table — row counts, and that amount/date columns arrived typed, not as text.
-
For an ongoing feed, schedule the workflow.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause |
|---|---|
| Test request 400 with a scope or role message | The role is missing REST Web Services / OAuth 2.0 login / SuiteAnalytics, or the scope array was rejected — the surfaced detail names it. |
| Token exchange fails | Wrong account id form (missing _SB1), wrong certificate id (kid), or a private key that doesn’t match the uploaded public cert. |
| Type/conversion error on import (names the column and value) | A typed column got a value it can’t parse — most often a Date/Datetime column where SuiteQL returned the account’s display format. Wrap the field in TO_CHAR(col, 'YYYY-MM-DD') in the query, or set the column type to Text. |
| Totals don’t tie across subsidiaries | amount is in each transaction’s own currency — use consolidated/converted fields. |
| Duplicate or missing rows across a large pull | No deterministic ORDER BY on an offset-paged query. |
Related
Section titled “Related”- NetSuite SuiteQL Query Examples — ready-to-run queries for journal entries, trial balance, P&L, open A/R, and more.
- NetSuite REST Connector — field and SuiteQL reference.
- REST Request Step — the step this pull is built on.
- Create and Manage a Connection