NetSuite Integration
The NetSuite integration is a read-only SuiteQL connection for order-to-cash, receivables, payables, inventory movement, and general-ledger lines. It uses NetSuite OAuth 2.0 machine-to-machine authentication with a JWT client assertion signed by your integration certificate.
The NetSuite integration does not run through the Resplendent Sync Agent.
Before you begin
Section titled “Before you begin”You need:
- A NetSuite account ID (production or sandbox), such as
1234567or1234567-sb1. - A dedicated Integration record configured for OAuth 2.0 Client Credentials (Machine to Machine).
- A certificate uploaded to that integration, plus the matching private key (PEM).
- A NetSuite role with read access to the Datasets you plan to sync.
- The Client ID and Certificate ID from NetSuite.
The integration never creates, updates, or deletes records in NetSuite.
Permissions
Section titled “Permissions”Grant the integration role only the SuiteQL/record permissions needed for the Datasets you plan to sync.
| Dataset | Required for connection? | Source |
|---|---|---|
| Customers | Yes (connection test) | customer |
| Contacts | No | contact |
| Customer Contact Roles | No | CustomerContactRole |
| Customer Addresses | No | customerAddressbook |
| Items | No | item |
| Ship Items | No | shipitem |
| Estimates | No | transaction filtered to estimates/quotes |
| Estimate Lines | No | transactionline joined to estimate transactions |
| Invoices | No | invoice |
| Invoice Lines | No | transactionline filtered to invoices |
| Sales Orders | No | salesorder |
| Sales Order Lines | No | transactionline filtered to sales orders |
| Item Fulfillments | No | transaction (type = 'ItemShip') |
| Transaction Links | No | NextTransactionLineLink |
| Transaction Statuses | No | TransactionStatus |
| Vendors | No | vendor |
| Employees | No | employee |
| Accounts | No | account |
| Subsidiaries | No | subsidiary |
| Locations | No | location |
| Departments | No | department |
| Classes | No | classification |
| Credit Memos | No | creditmemo |
| Credit Memo Lines | No | transactionline filtered to credit memos |
| Customer Payments | No | customerpayment |
| Customer Deposits | No | customerdeposit |
| Deposit Applications | No | depositapplication |
| Customer Refunds | No | customerrefund |
| Cash Sales | No | cashsale |
| Cash Sale Lines | No | transactionline filtered to cash sales |
| Vendor Bills | No | vendorbill |
| Vendor Bill Lines | No | transactionline filtered to vendor bills |
| Vendor Credits | No | vendorcredit |
| Vendor Credit Lines | No | transactionline filtered to vendor credits |
| Vendor Payments | No | vendorpayment |
| Purchase Orders | No | purchaseorder |
| Purchase Order Lines | No | transactionline filtered to purchase orders |
| Item Receipts | No | itemreceipt |
| Item Receipt Lines | No | transactionline filtered to item receipts |
| Return Authorizations | No | returnauthorization |
| Return Authorization Lines | No | transactionline filtered to return authorizations |
| Transfer Orders | No | transferorder |
| Transfer Order Lines | No | transactionline filtered to transfer orders |
| Transaction Accounting Lines | No | transactionaccountingline joined to transaction |
Estimates expose quote headers, including the external ID used to link a Salesforce Quote, customer ID, status, expiration date, and total in transaction currency. Join Estimate Lines to Estimates using transaction = id, and to Items using item = id. Lines exclude the transaction main/header row; use taxline to distinguish tax lines. Quantities and amounts retain their SuiteQL signs, and base-currency and transaction-currency amounts are labeled separately. Both Datasets use the existing one-minute incremental cadence, bounded history pages, UTC modification timestamps, and nightly resync for deletions. The NetSuite role needs permission to view estimates.
Missing permission for an optional Dataset does not break the connection. Resplendent shows a warning on the affected Dataset instead.
Custom fields returned by SuiteQL (custentity_*, custbody_*, custitem_*, custcol_*) are discovered automatically. Table requirements supply human-readable column aliases for discovered SuiteQL fields (curated labels for core columns, plus automatic Title Case labels for glued identifiers and custom fields). Each Dataset pre-selects a small curated default column set; you can still include any other discovered column.
Column types
Section titled “Column types”Previews and sync batches use the same column types, including when selected fields are null or absent from the response:
- Amounts, rates, and quantities are numbers; declared integer fields are integers.
- Checkboxes are booleans (
true/false). - Calendar fields are dates. Timestamp fields are UTC datetimes with microsecond precision.
- IDs, record references, custom segments, postal codes, and text fields remain text, preserving leading zeroes.
Standard fields use the connector’s explicit type catalog. Custom fields use the account’s CustomField.fieldvaluetype declarations, including custom checkboxes, numbers, dates, and datetimes. The integration role must have read access to that metadata when custom fields are selected. Missing or unsupported custom type metadata stops the pull with an error. Unmapped standard fields remain text; values are never guessed from a small preview sample.
Create the NetSuite integration credentials
Section titled “Create the NetSuite integration credentials”- In NetSuite, create or select a dedicated Integration for Resplendent.
- Enable OAuth 2.0 Client Credentials (Machine to Machine).
- Generate or upload a certificate and download/retain the private key PEM.
- Assign a read-only role with access to the records listed above.
- Copy the Client ID, Certificate ID, and Account ID.
Connect NetSuite to Resplendent Data
Section titled “Connect NetSuite to Resplendent Data ”- In Resplendent Data, go to Settings → Integrations.
- Find NetSuite and select Connect.
- Enter:
- Account ID: your NetSuite account id (sandbox IDs often end in
-sb1). - Client ID: the OAuth 2.0 integration client id.
- Certificate ID: the certificate id used as the JWT
kid. - Private key (PEM): paste or upload the matching private key.
- Account ID: your NetSuite account id (sandbox IDs often end in
- Test and save the connection.
- Select the Datasets and columns you want to sync.
The connection test mints an access token and runs a tiny Customers SuiteQL read. A successful test proves authentication works and the role can read core customer data.
Datasets
Section titled “Datasets”Resplendent syncs typed Datasets rather than one giant Transactions dump:
- Customers, Contacts, Customer Contact Roles, and Customer Addresses for customer master data.
- Items for product/SKU context.
- Ship Items for shipping method names. Join a Sales Order
shipmethodto Ship Itemsid. Ship Name is the method name on the order; Display Name is the display name or code. - Estimates and Estimate Lines for quotes and their line items.
- Invoices and Invoice Lines for AR reporting. Invoices include Sales Rep by default.
- Credit Memos, Customer Payments, Customer Deposits, Deposit Applications, Customer Refunds, and Cash Sales complete receivables. Credit Memos and Cash Sales include Sales Rep.
- Sales Orders, Sales Order Lines, and Item Fulfillments for order-to-cash flow. Sales Orders include Sales Rep.
- Vendors, Vendor Bills, Vendor Credits, Vendor Payments, Purchase Orders, and Item Receipts for payables. Bill, credit, order, and receipt lines are separate Datasets.
- Return Authorizations and Transfer Orders, with their lines, for inventory movement.
- Employees, Accounts, Subsidiaries, Locations, Departments, and Classes so transactions can be named and grouped.
- Transaction Accounting Lines for debits and credits, including COGS. Each row includes a posting flag so a report can keep or drop non-posting lines. The line follows the parent transaction’s last modified time.
- Transaction Links for relationships such as order-to-invoice and invoice-to-payment links.
- Transaction Statuses for readable status labels.
Sales Orders includes Tracking Numbers (tracking_numbers) by default. It resolves NetSuite’s linkedtrackingnumberlist references with BUILTIN.DF and returns the actual carrier tracking numbers as a text string, preserving multiple numbers in NetSuite’s list format. Orders without tracking numbers return null. Existing Sales Orders Datasets must select the new column and resync to populate existing rows. This derived value follows the Sales Order sync lifecycle; fulfillment changes that do not update the order’s modification timestamp are reconciled by the nightly resync.
Estimates are read from the transaction record, which does not include sales rep. Use Invoices, Sales Orders, Cash Sales, or Credit Memos when a report needs sales rep.
Sync behavior
Section titled “Sync behavior”- Customers, Contacts, Customer Addresses, Items, Estimates, Estimate Lines, Invoices, Invoice Lines, Sales Orders, Sales Order Lines, Item Fulfillments, Transaction Links, and the finance and inventory Datasets (vendors, employees, accounts, subsidiaries, locations, departments, classes, receivables, payables, return authorizations, transfer orders, their lines, and transaction accounting lines) use incremental sync, with a default and minimum interval of 1 minute. This is a polling interval; API latency, rate limits, and queued processing add to delivery time.
- The first pull loads one configured batch (default 1,000 rows). Later history ticks load the next batch using the modified timestamp and record identity together, including when many records share a timestamp. Manual and nightly resync replace the warehouse with the first batch and repeat this history crawl.
- Incremental polls fetch changes since the latest stored timestamp, with a two-minute overlap. Overlapping records are upserted by primary key. Timestamp filters include an explicit UTC offset; they do not depend on the account’s date format or time zone.
- Created and last-modified timestamps are explicitly projected by SuiteQL in UTC, retaining fractional seconds, for example
2026-09-08T19:12:32.000000Z. Calendar dates such as transaction dates, due dates, and ship dates stayYYYY-MM-DD; they have no time or timezone to convert. - Customer Contact Roles, Ship Items, and Transaction Statuses have no reliable modified timestamp. They remain daily snapshots, with a minimum interval of 6 hours. Contact Roles and Ship Items fetch the complete list; Transaction Statuses honors its configured batch size. Ship Items is the
shipitemrecord, which has no last-modified column. - Transaction Statuses uses the standard Batch Size setting as the maximum rows fetched per scheduled snapshot (default 1,000; maximum 100,000). Incremental syncing is disabled; scheduled daily syncing remains enabled. Each successful refresh replaces the previous snapshot, with no generated primary key.
trantype,trancustomtype, andiddistinguish status definitions when joining; custom transaction types can share the same status code. Internal pagination retains all three fields, including null custom type IDs for standard transactions. - Transaction Links uses the required Transaction Link Key,
transaction_link_key, generated from previous document, previous line, next document, next line, and link type. The key is a JSON-encoded list of these components. Link type participates in both identity and pagination so different relationships between the same lines are preserved. - Nightly resync reconciles hard deletions. Incremental timestamp polling does not detect deleted records, guarantee every intermediate edit is observed, or guarantee that a parent timestamp changes for every edit to a related record. Sync Customer Addresses separately when its changes matter.
- Item Fulfillments preview reads transaction headers from the last 90 days to avoid sorting the full history; that preview window does not limit the Dataset’s historical crawl.
- History and changed-page pulls use keyset cursors with REST offset zero, avoiding NetSuite’s deep-offset limit. Timestamp and primary-key columns are always included in sync queries, even if omitted from the selected columns.
Replace existing Dataset state
Section titled “Replace existing Dataset state”This version replaces the old date-only cursors and rolling-scan settings. There is no database migration or compatibility conversion. After deploying, save each existing NetSuite Dataset with the new requirements (incremental strategy, 1-minute interval, and nightly resync for timestamped Datasets), then resync it. Old timestamps, historical cursors, and text-only warehouse column types must be discarded. Resync reloads the first configured batch immediately; remaining history follows in subsequent ticks. Keep the existing Dataset identity if Workflows or Widgets reference it.
Related links
Section titled “Related links”Update existing transaction Datasets
Section titled “Update existing transaction Datasets”After deploying this change, edit Transaction Links to disable Use Virtual Primary Key, select transaction_link_key as its Unique Key, and retain lastmodifieddate as its Sorting Column. Edit Transaction Statuses to disable Use Virtual Primary Key, select None for Unique Key and Sorting Column, and choose its Batch Size and daily schedule. Save and resync these Datasets so old generated keys and collapsed link rows are replaced. Preserve their Dataset IDs when Workflows or Widgets reference them. Item Fulfillments is unchanged.