> ## Documentation Index
> Fetch the complete documentation index at: https://control-dev.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# NetSuite

> Connect NetSuite directly to Control using a dedicated read-only role and OAuth 2.0 certificate authentication.

<Warning>
  The native NetSuite connector is being prepared for pilot use. Complete setup with the Control team and reconcile the
  first import before relying on its reports.
</Warning>

Control connects directly to NetSuite's REST API. This connection does not use Nango.
Each Control entity connects to one NetSuite subsidiary and the **primary accounting book**.
Set the Control entity currency to the subsidiary's base currency. The connection test and imports reject a mismatch to prevent reporting amounts in the wrong currency.
For a group with several subsidiaries, create a separate connection for each entity.

## Before you start

A NetSuite administrator must configure the connection. You need:

* REST Web Services and OAuth 2.0 enabled under **Setup → Company → Enable Features → SuiteCloud**.
* SuiteAnalytics Workbook enabled under **Enable Features → Analytics**, with the role's **Reports → SuiteAnalytics Workbook** permission set to **Edit**. Financial record and transaction permissions should remain read-only.
* A dedicated integration user and role with access to the intended subsidiary.
* Read access to the transaction, transaction line, transaction accounting line, account, subsidiary, currency, accounting period, accounting book, department, class and location records used by the connector.
* The **REST Web Services** and **Log in using OAuth 2.0 Access Tokens** permissions. Review the role's Records Catalog to confirm that the required SuiteQL records and fields are available. Transaction permissions must cover every posting transaction type you want reported.

Use a dedicated role with the minimum necessary access; do not give Control an Administrator role. An apparently successful query can still omit records hidden by role or subsidiary restrictions. Reconciliation is required to detect incomplete access.

## 1. Create the integration application

In NetSuite, open **Setup → Integration → Manage Integrations → New**.
Give the application a recognizable name, enable OAuth 2.0 **Client Credentials (Machine to Machine)** and the **REST Web Services** scope, and save it.
Record the **Client ID**. This flow does not require a client secret, callback URL or recurring interactive sign-in.

## 2. Create a certificate and private key

On a trusted computer, generate a P-256 key and an X.509 certificate:

```bash theme={null}
umask 077
openssl req -new -x509 -newkey ec \
  -pkeyopt ec_paramgen_curve:prime256v1 -pkeyopt ec_param_enc:named_curve \
  -nodes -days 365 -out netsuite-public.pem -keyout netsuite-private.pem
```

Follow the prompts to identify your organization. Upload only the public certificate to NetSuite. The private key is uploaded through Control's secure integration setup and stored in its secret store. Never send it through email, Slack, a support ticket or a chat assistant.

Control supports EC P-256 (ES256) and RSA 3072/4096-bit (PS256) private keys. The public certificate must match the private key. NetSuite certificates have a maximum validity of two years; the example above uses one year.

## 3. Map the certificate in NetSuite

Open **Setup → Integration → Manage Authentication → OAuth 2.0 Client Credentials (M2M) Setup**.
Create a mapping for the integration application, dedicated user and role. Upload `netsuite-public.pem` and save the mapping.
Record the generated **Certificate ID**.

Sandbox mappings are separate from production mappings. A sandbox refresh does not preserve the production OAuth setup; verify and recreate the mapping as needed after refreshes.

## 4. Connect the entity in Control

In **Entities & Data sources**, select the entity and add the native **NetSuite** integration. Enter:

| Field | Where to find it |
| - | - |
| Account ID | NetSuite **Setup → Company → Company Information**. Use the account ID, not a URL. Sandbox IDs can look like `1234567_SB1`. |
| Client ID | The integration application created in step 1. |
| Certificate ID | The certificate mapping created in step 3. |
| Private key | Upload the matching `netsuite-private.pem` file. |
| Subsidiary ID | The internal ID of the subsidiary corresponding to this Control entity. |
| Accounting book ID | The internal ID of the primary accounting book. Do not assume a particular value. |

Run the credential test. It checks the selected subsidiary/book, reference-data access and a sample GL transaction when one is available. A successful test confirms API access; it does not prove complete financial coverage.

## What is imported

* Posted GL entries, with debit and credit amounts in the subsidiary's base currency.
* Transaction and line identifiers, document numbers/types, dates, accounting periods and descriptions.
* Chart of accounts, counterparties referenced by postings, and department/class/location dimensions.
* The subsidiary and accounting-period reference data needed for reporting, including a conservative closed-through date that stops at reopened periods.

The connector reads the full accessible posting history on the first import. Refreshes compare transaction modification versions across that history, fetch changed transactions in full, and reconcile removed transactions and lines. Historical corrections are not limited to a recent posting-date window. Full reloads re-read every transaction. Financial amounts retain decimal precision. Reporting uses the posting period when a transaction date falls outside it.

The pilot does not import invoice attachments, open AR/AP ageing, inventory movements, payroll details or custom segments, and does not write back to NetSuite. Secondary accounting books are rejected to prevent applying an incorrect base currency.

## Validate the first import

With the Control team, compare a closed period's trial balance and P\&L with NetSuite using the same subsidiary, primary book, currency and posting periods. Include balance-sheet opening balances, journals, invoices, credits and any period-end adjustments. Check department/class/location splits and counterparty labels.

In a sandbox, verify that changing an old transaction, removing a line, voiding/deleting a transaction and rerunning a refresh produces the expected result without duplicates. Do not modify production transactions merely to test the connector.

## Rotate or revoke access

Before the certificate expires, create a new key/certificate, add a new NetSuite mapping, and replace the connection credentials in Control. Test the new credentials before revoking the previous mapping. Update each Control entity using the old mapping.

To stop access, disable the Control integration and revoke the certificate mapping or integration application in NetSuite. Disabling sync in Control alone does not revoke the credential in NetSuite.

## Troubleshooting

* **OAuth/401 error:** check the account, Client ID, Certificate ID, matching private key, expiry and user/role/application mapping. Sandbox and production account IDs and mappings differ.
* **Permission/403 error or missing fields:** have an administrator check the dedicated role and Records Catalog. Confirm access to all posting transaction types and the subsidiary.
* **Secondary-book error:** select the primary book. A secondary book can have a different base currency and is not supported in this pilot.
* **Transactions changed during extraction:** Control rechecks changed transactions up to three times. If posting activity still prevents a complete extraction, retry after it settles. The previous incremental checkpoint is preserved.
* **Totals differ:** compare posting periods, opening balances, subsidiary/book selection and role restrictions before changing account mappings in Control.

## Oracle references

* [OAuth 2.0 client credentials setup](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_162686838198.html)
* [Certificate requirements](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/subsect_162755332391.html)
* [SuiteQL over REST](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157909186990.html)
* [REST and SuiteAnalytics role prerequisites](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_5085602973.html)
* [Transaction and accounting-line joins](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_1548805090.html)
