NetSuite – Gotchas

Service ID: netsuite

NetSuite is the leading integrated cloud business software suite, including business accounting, ERP, CRM and ecommerce software.

⚠️

35 gotchas across 20 resources

These are connector-specific behaviors and limitations to be aware of when integrating.

Attachments1 gotcha

deleteattachmentsDelete

Detaches the file from the parent record. The file itself stays in the File Cabinet.

onebalanceSheetOne

NetSuite date filtering resolves filter[end_date] to accounting period IDs via SuiteQL, then filters the SOAP request by periods up to that date. This requires the SuiteAnalytics Workbook permission for period resolution. If unavailable, returns all-time data as fallback. For Balance Sheet, only filter[end_date] is meaningful (point-in-time snapshot).

Bill Payments3 gotchas

allbillPaymentsAll

In order to read or write the status field, you must enable Approval Routing for Vendor Payments in Netsuite. Navigate to Setup > Accounting Preferences > Approval Routing > Vendor Payments > Approval Routing.

addbillPaymentsAdd

In order to read or write the status field, you must enable Approval Routing for Vendor Payments in Netsuite. Navigate to Setup > Accounting Preferences > Approval Routing > Vendor Payments > Approval Routing.

onebillPaymentsOne

In order to read or write the status field, you must enable Approval Routing for Vendor Payments in Netsuite. Navigate to Setup > Accounting Preferences > Approval Routing > Vendor Payments > Approval Routing.

Bills3 gotchas

allbillsAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

addbillsAdd

For creating or updating a bill in Netsuite, its required to provide the line type.

line_items[].tracking_categories maps to the NetSuite per-line class (Classification), which accepts only one value — entries at index 1 or beyond are dropped silently.

When line_items[].customer is set without an explicit line_items[].rebilling.rebillable, NetSuite defaults rebillable to true. Pass rebilling: { rebillable: false } explicitly if you want a customer-linked line that is not rebillable.

updatebillsUpdate

line_items[].tracking_categories maps to the NetSuite per-line class (Classification), which accepts only one value — entries at index 1 or beyond are dropped silently.

line_items[].rebilling.rebillable cannot be changed after the bill is created — NetSuite rejects updates to isbillable on VendorBill. The field is silently dropped from update requests; create a new bill if you need to change the flag. Additionally, any PATCH that updates a line with customer set will cause NetSuite to reset rebilling.rebillable to its default (true) because the SOAP update omits the field and NetSuite re-applies the default for billable lines.

Credit Notes4 gotchas

allcreditNotesAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

addcreditNotesAdd

Netsuite only supports one tracking category at a time so only the first item in the tracking_categories list will be used.

updatecreditNotesUpdate
  • Netsuite doesn't support voiding credit notes via API. Options: 1) Remove allocations and delete, or 2) Create a reversing invoice for the same amount.
updatecreditNotesUpdate

Netsuite only supports one tracking category at a time so only the first item in the tracking_categories list will be used.

Customers1 gotcha

allcustomersAll

The minimum page size accepted for Netsuite is 5. The cursor for Netsuite expires if it has not been used within 15 minutes after its creation.

The taxable field is read directly from the NetSuite customer.taxable boolean in both Legacy Tax and SuiteTax accounts. Under SuiteTax, customer.taxable continues to be readable but does not reflect per-jurisdiction tax exemptions — the meaningful per-nexus tax state lives in NetSuite's customerTaxRegistration records, which the unified API does not currently surface as first-class fields. Consumers needing per-nexus tax registration data should gate their logic on connection.suitetax_enabled and query customerTaxRegistration via pass-through SuiteQL, e.g. ?pass_through[q]=SELECT entity, nexus, taxRegistrationNumber FROM customerTaxRegistration WHERE entity = {customer_id}.

When filter, sort, or pass_through parameters are applied to GET /accounting/customers, addresses[] returns only the default billing and default shipping addresses, each with type and string (a multi-line formatted address). Structured fields like line1, city, state, postal_code, and country, and any additional custom-labeled addresses, are returned only on unfiltered list calls and on GET /accounting/customers/{id}.

Departments1 gotcha

alldepartmentsAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

addexpenseReportsAdd

When creating expense report line items, the line_items[].account.id field is not written to NetSuite. In NetSuite, the GL account is automatically derived from the expense category. Setting line_items[].account.id has no effect and may trigger an INSUFFICIENT_PERMISSION error in strict tenant configurations. Use line_items[].expense_category.id to specify the category (which implicitly sets the GL account).

The line_items[].reimbursable field maps to the NetSuite corporateCreditCard boolean on each expense line. Setting reimbursable: false sets corporateCreditCard: true, marking the line as a corporate card expense. NetSuite will automatically create an offsetting accounting entry against the corporate card liability account, and the line's amount will not count toward the employee reimbursement total (resulting in total_amount: 0 if all lines are non-reimbursable). Setting reimbursable: true (or omitting the field) leaves corporateCreditCard unset, meaning the employee is expected to be reimbursed out-of-pocket.

The employee record linked to the expense report must have a corporate credit card configured in NetSuite when reimbursable: false is used, otherwise the API will return a validation error.

Note: corporateCreditCard is the current NetSuite SOAP field for this purpose. The legacy isNonReimbursable field was removed in NetSuite 18.2 for accounts that did not use it prior to that version.

Important read limitation: The list endpoint (GET /expense-reports) reads line_items[].reimbursable from the NetSuite SuiteQL transactionline table, which exposes only the legacy isNonReimbursable column. Because writing reimbursable: false sets corporateCreditCard (not isNonReimbursable), the list endpoint will always return reimbursable: true for lines created with reimbursable: false via this API. To get accurate reimbursable values for corporate card lines, use the single record endpoint (GET /expense-reports/{id}), which reads directly from the NetSuite SOAP API where corporateCreditCard is available.

updateexpenseReportsUpdate

When updating expense report line items, the line_items[].account.id field is not written to NetSuite. In NetSuite, the GL account is automatically derived from the expense category. Setting line_items[].account.id has no effect and may trigger an INSUFFICIENT_PERMISSION error in strict tenant configurations. Use line_items[].expense_category.id to specify the category (which implicitly sets the GL account).

The line_items[].reimbursable field maps to the NetSuite corporateCreditCard boolean on each expense line. Setting reimbursable: false sets corporateCreditCard: true, marking the line as a corporate card expense. NetSuite will automatically create an offsetting accounting entry against the corporate card liability account, and the line's amount will not count toward the employee reimbursement total (resulting in total_amount: 0 if all lines are non-reimbursable). Setting reimbursable: true (or omitting the field) leaves corporateCreditCard unset, meaning the employee is expected to be reimbursed out-of-pocket.

The employee record linked to the expense report must have a corporate credit card configured in NetSuite when reimbursable: false is used, otherwise the API will return a validation error.

Note: corporateCreditCard is the current NetSuite SOAP field for this purpose. The legacy isNonReimbursable field was removed in NetSuite 18.2 for accounts that did not use it prior to that version.

Important read limitation: The list endpoint (GET /expense-reports) reads line_items[].reimbursable from the NetSuite SuiteQL transactionline table, which exposes only the legacy isNonReimbursable column. Because writing reimbursable: false sets corporateCreditCard (not isNonReimbursable), the list endpoint will always return reimbursable: true for lines created with reimbursable: false via this API. To get accurate reimbursable values for corporate card lines, use the single record endpoint (GET /expense-reports/{id}), which reads directly from the NetSuite SOAP API where corporateCreditCard is available.

Expenses2 gotchas

addexpensesAdd

line_items[].tracking_categories maps to the NetSuite per-line class (Classification), which accepts only one value — entries at index 1 or beyond are dropped silently.

When line_items[].customer is set without an explicit line_items[].rebilling.rebillable, NetSuite defaults rebillable to true. Pass rebilling: { rebillable: false } explicitly if you want a customer-linked line that is not rebillable.

updateexpensesUpdate

line_items[].tracking_categories maps to the NetSuite per-line class (Classification), which accepts only one value — entries at index 1 or beyond are dropped silently.

allinvoiceItemsAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

Invoices3 gotchas

allinvoicesAll

The minimum page size accepted for Netsuite is 5. The cursor for Netsuite expires if it has not been used within 15 minutes after its creation. When using filters or sort parameters (which trigger the SuiteQL path), quantity and unit_price on line items may reflect base-unit values (e.g., days) rather than selling-unit values (e.g., years) for items with Units of Measure (UOM) enabled. total_amount is always accurate regardless. Use the GET one endpoint for selling-unit quantities.

addinvoicesAdd

Netsuite only supports one tracking category at a time so only the first item in the tracking_categories list will be used. While creating an invoice, revenue start date and revenue end date should be passed in the custom fields object inside the line items.

updateinvoicesUpdate

Netsuite only supports one tracking category at a time so only the first item in the tracking_categories list will be used.

alljournalEntriesAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

addjournalEntriesAdd

Netsuite only supports one tracking category at a time so only the first item in the tracking_categories list will be used.

updatejournalEntriesUpdate

Netsuite only supports one tracking category at a time so only the first item in the tracking_categories list will be used.

allledgerAccountsAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

addledgerAccountsAdd

The currency field is supported only when Multi-Currency is enabled in NetSuite. It applies mainly to Bank and Credit Card accounts and becomes read-only after creation.

Locations1 gotcha

alllocationsAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

Payments2 gotchas

allpaymentsAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

addpaymentsAdd

The number property could be used to override the Netsuite tranId property.

oneprofitAndLossOne

NetSuite date filtering resolves filter[start_date] and filter[end_date] to accounting period IDs via SuiteQL, then filters the SOAP request by those periods. This requires the SuiteAnalytics Workbook permission for period resolution. If the permission is unavailable, the report returns all-time data as a fallback. For best results, keep date ranges under 16 years (200 monthly periods).

allpurchaseOrdersAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

Subsidiaries1 gotcha

allsubsidiariesAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

Suppliers1 gotcha

allsuppliersAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation.

Tax Rates1 gotcha

alltaxRatesAll

The minimun page size accepted for Netsuite is 5. The cursor for Netsuite expires if they have not been used within 15 minutes after its creation. NetSuite supports compound taxes through the components array, allowing multi-tier tax structures (e.g., state + county taxes).