> For the complete documentation index, see [llms.txt](https://docs.harmony.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.harmony.io/integrations/saas-applications/netsuite.md).

# NetSuite

Sync software contracts, vendor details, and spend from NetSuite, plus NetSuite user, role, and license insights

This guide walks you through setting up Token-Based Authentication (TBA) in NetSuite so Harmony can securely read your vendor, contract, and procurement data.

> **What you'll do:** Create a dedicated role with minimal permissions, generate authentication tokens, and collect the 5 values needed to complete the Harmony integration setup.

{% hint style="warning" %}
**Token-Based Authentication is being retired for new integrations.** Oracle states that "as of 2027.1, no new integrations using TBA can be created for SOAP web services, REST web services, and RESTlets. Existing integrations will continue working." Harmony's NetSuite integration currently supports Token-Based Authentication only. Connections created before the 2027.1 release keep working - if you are setting up NetSuite for the first time after that release, contact Harmony support before you begin.
{% endhint %}

{% hint style="info" %}
**Already connected ZipHQ?** Harmony flags NetSuite and ZipHQ as conflicting procurement integrations. Connecting both may result in duplicate contract and spend data appearing in the Contracts page, since both systems track overlapping vendor and purchase information. You can still connect both and manage the duplicates manually.
{% endhint %}

***

#### 1. Prerequisites - Enable Features

**Navigation:** Setup › Company › Setup Tasks › Enable Features

*SuiteCloud tab:*

* ✅ **REST Web Services**
* ✅ **Token-Based Authentication**

*Analytics tab:*

* ✅ **SuiteAnalytics Workbook**

Accept the SuiteCloud Terms of Service if prompted. Save.

{% hint style="warning" %}
**SuiteAnalytics Workbook is not optional.** Harmony reads all NetSuite data through SuiteQL queries. If the account-level **SuiteAnalytics Workbook** feature is off, every query fails - even when the SuiteAnalytics Workbook *permission* is granted on the role in Step 2. The account feature and the role permission are two separate settings and you need both.
{% endhint %}

***

#### 2. Create the Role

**Navigation:** Setup › Users/Roles › Manage Roles › New

**General settings:**

| Field                   | Value                                                                   |
| ----------------------- | ----------------------------------------------------------------------- |
| Name                    | Harmony Integration Role (or any descriptive name)                      |
| Subsidiary Restrictions | All (so the token sees vendors/purchase orders across all subsidiaries) |
| Authentication          | Leave all unchecked (Two-Factor: Not required)                          |

**Permissions - Minimal Required Set**

Add the following permissions to the role. These are the minimum permissions required for Harmony to read your vendor, contract, and procurement data.

*Setup tab:*

| Permission                 | Level | Notes                                                   |
| -------------------------- | ----- | ------------------------------------------------------- |
| Log in using Access Tokens | Full  |                                                         |
| REST Web Services          | Full  |                                                         |
| SOAP Web Services          | Full  | Optional - only required for **Attachment Sync**\*\*    |
| View Login Audit Trail     | View  | Only required for the **Native App Integration**\* flow |

*Reports tab:*

| Permission              | Level | Why                                         |
| ----------------------- | ----- | ------------------------------------------- |
| SuiteAnalytics Workbook | Edit  | Unlocks SuiteQL query execution             |
| Transaction Detail      | View  | Enables transaction table access in SuiteQL |

*Lists tab:*

| Permission                          | Level | Notes                                                   |
| ----------------------------------- | ----- | ------------------------------------------------------- |
| Contacts                            | View  |                                                         |
| Documents and Files                 | View  | Optional - only required for **Attachment Sync**\*\*    |
| Employees                           | View  | Only required for the **Native App Integration**\* flow |
| Employee Record                     | View  | Only required for the **Native App Integration**\* flow |
| Items                               | View  |                                                         |
| System Notes for Analytics and REST | View  | Only required for the **Native App Integration**\* flow |
| Vendors                             | View  |                                                         |

*Transactions tab:*

| Permission       | Level |
| ---------------- | ----- |
| Bills            | View  |
| Find Transaction | View  |
| Purchase Order   | View  |

> \* **Native App Integration** is the flow where Harmony surfaces per-user NetSuite activity and license usage alongside vendor and contract data - treating NetSuite itself as a SaaS app in your inventory. It reads employee records, role assignments, the login audit trail, and system notes. If you only need vendor/contract/spend sync, you can skip the four permissions marked with an asterisk.

> \*\* **Attachment Sync** lets Harmony also sync contract attachments (e.g. invoice PDFs attached to Purchase Orders or Vendor Bills). If SOAP Web Services is not yet enabled on your account, enable it first: **Setup › Company › Enable Features › SuiteCloud tab › SuiteTalk (Web Services) › check "SOAP Web Services" › Save**. Without these permissions, contracts still sync normally - just without their attached documents.

***

#### 3. Assign the Role to a User

**Navigation:** Lists › Employees › Employees (find the user who will own the integration)

We recommend using a dedicated service account rather than a personal employee account, so the integration is not affected if the employee leaves.

1. Open the employee/user record
2. Go to the **Access** subtab
3. In the **Roles** section, click **Add**
4. Select the role you created (e.g. Harmony Integration Role)
5. Save

> **Tip:** If you cannot see the user in the Access Token dropdown later, it means this step was not completed - the role is not assigned to the user, or the role is missing the "Log in using Access Tokens" permission.

***

#### 4. Create the Integration Record

**Navigation:** Setup › Integration › Manage Integrations › New

| Field                      | Value                                         |
| -------------------------- | --------------------------------------------- |
| Name                       | Harmony Integration (or any descriptive name) |
| State                      | Enabled                                       |
| Token-based Authentication | ✅ Checked                                     |
| TBA: issuetoken Endpoint   | ⬜ Unchecked                                   |
| TBA: Authorization Flow    | ⬜ Unchecked                                   |
| OAuth 2.0 section          | Leave all unchecked                           |

Click **Save**.

> ⚠️ **IMMEDIATELY** copy the two values shown - they appear **only once** and cannot be retrieved later:
>
> * **Consumer Key**
> * **Consumer Secret**
>
> These may be labeled as *Client ID* and *Client Secret* in other documentation.

***

#### 5. Create the Access Token

**Navigation:** Setup › Users/Roles › Access Tokens › New

| Field            | Value                                  |
| ---------------- | -------------------------------------- |
| Application Name | Select your integration record         |
| User             | Select the user with the role assigned |
| Role             | Select the role you created            |

Click **Save**.

> ⚠️ **IMMEDIATELY** copy the two values - shown **only once**:
>
> * **Token ID**
> * **Token Secret**

***

#### 6. The 5 Values You Need

Once you have completed the steps above, enter these 5 values in the Harmony integration setup screen to complete the connection:

| # | Value               | Where to find it                                                  |
| - | ------------------- | ----------------------------------------------------------------- |
| 1 | **Account ID**      | Setup › Company › Company Information (see the format note below) |
| 2 | **Consumer Key**    | From Step 4 (Integration Record save)                             |
| 3 | **Consumer Secret** | From Step 4 (Integration Record save)                             |
| 4 | **Token ID**        | From Step 5 (Access Token save)                                   |
| 5 | **Token Secret**    | From Step 5 (Access Token save)                                   |

> **Account ID format:** 5-10 digits, optionally followed by `_SB` and a number for a sandbox account - for example `1234567` or `1234567_SB1`. Release Preview accounts (the `_RP` suffix) are not supported and are rejected by the setup form.

> **Note:** When you open the NetSuite integration setup form in Harmony, a "For more details, visit our documentation" link at the top of the form brings you directly back to this guide if you need a reference while filling in your credentials.

***

#### 7. Choose Which Transaction Types to Sync

After entering your credentials, you can control which NetSuite transaction types Harmony pulls in as part of your contracts integration. Two toggles are available in your NetSuite integration settings:

| Toggle                   | Default                   | When to use it                                                                                             |
| ------------------------ | ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Sync Purchase Orders** | On (enabled by default)   | Standard purchasing workflow - most organizations use this                                                 |
| **Sync Vendor Bills**    | Off (disabled by default) | Enable this if your team books vendor contracts directly as Vendor Bills with no associated Purchase Order |

Both toggles can be enabled at the same time if your organization records spend through both transaction types. Existing NetSuite tenants retain their current behavior - Sync Purchase Orders remains on and Sync Vendor Bills remains off unless you explicitly enable it.

***

#### 8. Optional (Strongly Recommended) - Service Start / End Date Columns

NetSuite does not have a single, standard "contract start date" or "contract end date" field. Instead, most customers track the service period on **transaction lines** (the individual lines of a Bill or Purchase Order) using **custom transaction column fields**

* typically named something like `custcol_service_start_date` and `custcol_service_end_date`.

Harmony uses these two columns to populate the **contract start date** and **contract end date** for each vendor contract it derives from your NetSuite data. Without them, those fields will be left `NULL` in Harmony, which significantly reduces the value of renewal tracking, expiring-contract alerts, and spend-by-period reporting.

> ✅ **We strongly recommend providing these two column IDs.** If your organization tracks service periods on transaction lines under different field names, use those instead - the important thing is that the field is a **transaction line column** holding a **date**.

**8.1 Supported column types**

The `service_start_date_column` and `service_end_date_column` fields accept either of the following:

* **A custom column ID** - any `custcol_*` field of type Date that your organization uses to record service periods (e.g. `custcol_service_start_date`).
* **A NetSuite native amortization column** - if your organization uses NetSuite's built-in amortization schedule instead of custom fields, you can enter one of these two reserved values:

| Value                 | What it maps to                                  |
| --------------------- | ------------------------------------------------ |
| `amortizstartdate`    | NetSuite's native amortization start date column |
| `amortizationenddate` | NetSuite's native amortization end date column   |

This is an explicit, per-credential choice. There is no automatic fallback - Harmony uses exactly the column ID you provide.

**8.2 Where these fields live in NetSuite**

* **Transaction Line Fields** (a.k.a. transaction column fields) - custom fields that appear on each line of a transaction (Bill, Purchase Order, Invoice, etc.), not on the transaction header.
* Their **internal ID** is what Harmony needs. Internal IDs almost always start with the prefix `custcol_` (for example `custcol_service_start_date`).

**8.3 How to find the exact column IDs**

**Option A - Browse the Transaction Line Fields list (recommended)**

1. In NetSuite, go to **Customization › Lists, Records, & Fields › Transaction Line Fields**.
2. In the list, look for fields whose **Label** describes a service period, contract period, subscription term, or similar - common names include:
   * *Service Start Date* / *Service End Date*
   * *Contract Start* / *Contract End*
   * *Coverage Start* / *Coverage End*
   * *Subscription Start* / *Subscription End*
3. Confirm the **Type** column shows **Date** (not Free-Form Text, List/Record, etc.).
4. Copy the value from the **ID** column - this is the internal ID you enter in Harmony (for example `custcol_service_start_date`). If the ID column is not visible, click the field name to open it - the ID is shown at the top of the record.

**Option B - Inspect a real transaction**

If you're not sure which custom fields your organization actually populates, open a representative Bill or Purchase Order that has the service period filled in:

1. Open the transaction and go to the **Items** subtab (line items).
2. Click a line to edit it, or expand the line detail.
3. Hover the label of the start-date / end-date field - most browsers will show the underlying field ID in a tooltip. You can also right-click and choose **Inspect** - the field's HTML `id` attribute contains the internal ID (look for `custcol_<something>`).

**Option C - Ask your NetSuite administrator**

If you don't have permission to access **Customization**, your NetSuite admin can tell you the internal IDs of the service-period fields your organization uses.

**8.4 Enter the IDs in Harmony**

Paste the internal IDs (including the `custcol_` prefix, or the native amortization column name) into the last two fields of the Harmony NetSuite setup screen:

| Field                         | Example values                                      |
| ----------------------------- | --------------------------------------------------- |
| **Service start date column** | `custcol_service_start_date` or `amortizstartdate`  |
| **Service end date column**   | `custcol_service_end_date` or `amortizationenddate` |

Leave either field blank to skip it - the corresponding contract date will remain `NULL` in Harmony.

> ⚠️ **Common pitfalls**
>
> * The value must be the **internal ID** (e.g. `custcol_service_start_date`), **not** the display label ("Service Start Date") - unless you are using one of the two native amortization column names listed above.
> * Custom fields must be **Transaction Line Fields**, not Transaction Body Fields or Item Fields.
> * Custom fields must be of type **Date**. Free-form text fields containing dates as strings are not supported.
> * The role you created in Step 2 must have **View** access to the transactions (Bills, Purchase Orders) whose lines carry these fields - the minimal permissions listed above already cover this.
> * Harmony validates your configured column IDs against your NetSuite instance at connection time. If a column ID contains a typo, references a non-date field, or points to the wrong table, you will receive a clear error message immediately so you can correct it before your first sync runs.

***

#### 9. Native App Integration - User and License Insights

In addition to contract and spend sync, you can connect NetSuite as a **native application integration** in Harmony. This gives IT admins direct visibility into NetSuite user activity, roles, and license utilization from the Applications page - treating NetSuite itself as a managed SaaS app in your inventory.

Once connected, Harmony syncs your NetSuite data daily, with a manual refresh option available. The same Token-Based Authentication credentials used for contract sync power this integration. On first connection Harmony backfills up to 90 days of activity, processing one calendar day at a time.

**What Harmony surfaces:**

* **User inventory** - employees synced with name, email, status, assigned NetSuite roles, and a license class derived from each role's center type: **Full User**, **Employee Center**, **External Center** (customer, vendor, partner and shopper centers), **Licensed User** (has login access but no readable role center type), **Employee Record** (a directory-only employee with no NetSuite login), or **Unknown**
* **Activity metrics** - per-user, per-day counts of successful NetSuite sign-ins, record edits, and transactions created or edited - derived from the login audit trail, system notes, and transaction records
* **License utilization** - how your users split across those license classes, helping you identify unused or over-provisioned NetSuite seats
* **Role visibility** - the NetSuite roles assigned to each user, useful for access reviews and offboarding checks

To enable this flow, make sure the role you created in Step 2 includes the four permissions marked with an asterisk in that section:

* **View Login Audit Trail** (Setup tab) - sign-in activity
* **Employees** (Lists tab) - the employee list and role assignments
* **Employee Record** (Lists tab) - employee details
* **System Notes for Analytics and REST** (Lists tab) - record-edit activity

{% hint style="warning" %}
**These four permissions are not verified when you connect.** Harmony validates your credentials against the contract tables only - vendors, contacts, transactions, transaction lines, and items. If your role is missing any of the permissions above, the connection still succeeds and no error is shown; the user, role, and activity data simply stays empty. If you connected NetSuite as a native app and see no users, re-check these role permissions first.
{% endhint %}

***

#### 10. What Harmony Syncs from NetSuite

| Data                       | Description                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Vendor contracts           | Purchase Orders and/or Vendor Bills as contracts - document number, memo, status, currency, total amount, and payment terms |
| Contract dates             | Service-period start and end dates, taken from the transaction line columns you configure in Step 8                         |
| Line items                 | The individual transaction lines behind each contract, including their service-period dates                                 |
| Vendors and contacts       | Vendor company name, email, phone, and website, plus the contacts associated with the vendor                                |
| Departments                | The department on the contract's header line                                                                                |
| Users (native app)         | Employees with name, email, status, entity ID, job title, subsidiary, hire date, and assigned NetSuite roles                |
| License class (native app) | The seat class derived from each user's role center types, plus whether the employee has NetSuite login access at all       |
| Activity (native app)      | Per-user, per-day counts of successful sign-ins, record edits, and transactions created or edited                           |

***

#### 11. Disconnect NetSuite from Harmony

1. Log into your Harmony dashboard
2. Navigate to **Settings** > **Integrations**
3. Find **NetSuite** and click the integration card
4. Click **Disconnect**
5. Confirm the disconnection when prompted

Once disconnected, Harmony stops syncing data from NetSuite. Previously synced data remains available in Harmony. To fully revoke access on the NetSuite side, delete or disable the Access Token at Setup › Users/Roles › Access Tokens.

***

#### 12. Troubleshooting

<details>

<summary>Connection fails with a missing-permissions error</summary>

**Possible causes:**

* The role is missing one of the contract-table permissions Harmony probes at connection time - Vendors, Contacts, Find Transaction / Purchase Order / Bills, Transaction Detail, or Items
* The **SuiteAnalytics Workbook** account feature (Step 1, Analytics tab) is off, so every SuiteQL query fails
* The role is missing **REST Web Services** or **Log in using Access Tokens**

**Solutions:**

1. The error message names the exact NetSuite permissions to add - add them to the role from Step 2, then retry
2. Confirm both the SuiteAnalytics Workbook *feature* and *permission* are enabled

</details>

<details>

<summary>Connection fails saying NetSuite rate-limited the validation probes</summary>

NetSuite limits how many concurrent API requests an account can serve, and sandbox accounts throttle aggressively. Wait a minute and try connecting again.

</details>

<details>

<summary>Contracts appear but have no start or end dates</summary>

**Possible causes:**

* No service start/end date columns were configured (Step 8) - Harmony leaves both dates `NULL` rather than guessing
* The configured column exists but is not populated on the transaction lines
* Your organization records spend as Vendor Bills, but only **Sync Purchase Orders** is enabled (Step 7)

**Solutions:**

1. Configure the service start/end date columns as described in Step 8
2. Enable **Sync Vendor Bills** if your team books vendor contracts directly as Vendor Bills with no associated Purchase Order

</details>

<details>

<summary>NetSuite users, roles, or activity are empty</summary>

**Possible causes:**

* The role is missing one or more of the four Native App Integration permissions - these are not checked at connection time, so the connection succeeds silently
* The integration was connected for contract sync only

**Solutions:**

1. Add **View Login Audit Trail**, **Employees**, **Employee Record**, and **System Notes for Analytics and REST** to the role from Step 2
2. Wait for the next daily sync, or trigger a manual refresh

</details>

***

#### 13. Data & Privacy

<details>

<summary>Key privacy principles</summary>

For information about how Harmony handles your data, see our [Privacy Policy](https://harmony.io/privacy).

* Harmony reads NetSuite data through read-only SuiteQL queries and does not create, modify, or delete anything in your NetSuite account
* Access is scoped to the dedicated role you create in Step 2 - Harmony sees only what that role can see
* Access can be revoked at any time by disconnecting in Harmony, or by deleting the Access Token in NetSuite

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.harmony.io/integrations/saas-applications/netsuite.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
