# How to Integrate NetSuite Bank Feeds Using Apideck

This guide walks a NetSuite administrator through enabling Apideck bank feeds end-to-end. The outcome: when a bank feed statement is POSTed through the Apideck Unify API, its transactions appear in **Banking → Match Bank Data** within the same import cycle.

**Estimated time:** 10–15 minutes.

>
> This guide assumes you already have a working Apideck NetSuite connection (Consumer Key/Secret, Token ID/Secret, Account ID). Bank feeds reuse the same Token-Based Authentication you set up during initial onboarding — there is no new auth flow to configure.

---

## 1. Prerequisites

Before you start, make sure your NetSuite account has the following features, SuiteApp, and role permissions in place.

### Features to enable

Go to **Setup → Company → Enable Features** and confirm the following are turned on.

**SuiteCloud tab:**

- _Client SuiteScript_, _Server SuiteScript_, _Custom Records_
- _Token-Based Authentication_ (already enabled for your existing Apideck connection)

### SuiteApp to install

Install the **Bank Statement Parsers** SuiteApp (bundle ID `293699`, published by Oracle NetSuite, free) from **Customization → SuiteBundler → Search & Install Bundles**. The Apideck bundle relies on the CSV parser this SuiteApp provides.

If this SuiteApp is already installed, skip this step.

### Role permissions

The role attached to your Apideck access token needs these permissions in addition to whatever you already granted for the core NetSuite connection:

| Category | Permission           | Level |
| -------- | -------------------- | ----- |
| Lists    | Custom Record Entries | Full  |
| Setup    | Custom Record Types   | Full  |
| Setup    | SuiteScript           | Full  |
| Setup    | REST Web Services     | Full  |

If you see **INSUFFICIENT_PERMISSION** after setup, start by reviewing this list.

---

## 2. Install the Apideck bundle

1. In NetSuite, go to **Customization → SuiteBundler → Search & Install Bundles**.
2. Enter the bundle ID Apideck provided. Your Apideck contact will share this; it is also listed on the Apideck NetSuite integration page.
3. Click **Install**.

The installer creates:

- Record types: _Apideck Bank Feed Statement_, _Apideck Bank Feed Transaction_
- RESTlet: _Apideck Bank Feed RESTlet_ (with a default deployment)
- Scheduled script: _Apideck Bank Feed Maintenance_
- Plug-in implementation: _Apideck Bank Feed Connectivity_

Verify under **Customization → SuiteBundler → List** that the bundle shows **Installed**.

---

## 3. Create a Format Profile

The Format Profile wires the connectivity plug-in to the specific NetSuite bank accounts you want to feed, and tells NetSuite how to parse the CSV the plug-in emits.

1. Go to **Setup → Accounting → Financial Institution → Format Profiles → New**.
2. Set:
   - **Profile Name**: `Apideck Bank Feed`
   - **Profile Type**: `Bank Reconciliation`
   - **Financial Institution**: `Apideck Bank Feeds` (create if absent)
   - **Connectivity Method**: **Apideck Bank Feed Connectivity**
   - **Transaction Parser**: **CSV Plugin Implementation** (if not in the dropdown, confirm the Bank Statement Parsers SuiteApp from §1 is installed)
3. Save, then open the profile again to configure each tab.

### 3a. Field Mapping

>
> You shouldn't need to change anything on this subtab. NetSuite pre-populates Field Mapping from its default CSV Bank Statement Template (shipped in the Bank Statement Parsers SuiteApp), and the Apideck plug-in is designed to emit exactly those headers so the defaults line up.

Open the **Field Mapping** subtab and verify the pre-populated values match this table. If your account was customised previously, adjust to match:

| NetSuite field        | Expected CSV column header |
| --------------------- | -------------------------- |
| Account Number \*     | `Account Number`           |
| Date \*               | `Date`                     |
| Amount                | `Amount`                   |
| Payee or Payer Name   | `Payee or Payer Name`      |
| Transaction Number    | `Transaction ID`           |
| Amount Currency       | `Currency`                 |
| Memo                  | `Memo`                     |
| Transaction Type \*   | `Transaction Type`         |
| Customer Name         | `NS Customer Name`         |
| Customer ID           | `NS Customer Internal ID`  |
| Invoice Numbers       | `Invoice Numbers`          |

Fields marked `*` are required by NetSuite (red asterisk in the UI).

These fields must be **blank** (they will already be blank by default — our plug-in doesn't emit them):

**Credit Amount**, **Debit Amount**, **Amount Indicator**, **Financial Institution ID**, **Account Closing Balance**, **Closing Balance Date**.

We use a single signed **Amount** column rather than split Credit/Debit columns, so NetSuite applies the sign directly without needing an Amount Indicator.

### 3b. Formatting Preferences

NetSuite pre-populates this subtab from your account's user preferences (**Home → Set Preferences → Formatting**). If the account is on a US English locale, the defaults will already match what the Apideck plug-in emits. Open the **Formatting Preferences** subtab and verify the values match; if any differ, set them to:

- **Date Format**: `MM/DD/YYYY`
- **Number Format**: `1,000,000.00`
- **Negative Number Format**: `-100`
- **CSV Column Delimiter**: `Comma`
- **Text Qualifier**: `"`
- **Footer Lines**: `0`

These fields must be **blank** — do not fill them in even if you see them listed in NetSuite's template examples:

- **Credit Indicator**
- **Debit Indicator**

They only apply when a CSV uses a separate _Amount Indicator_ column, which ours doesn't (our single Amount column carries the sign). Filling them in can cause NetSuite to mis-interpret row signs.

>
> If your NetSuite account uses a non-US locale and changing the profile's formatting would disrupt other bank feeds in the same account, reach out to Apideck support — we can produce a locale-aware build of the plug-in.

### 3c. Account Linking

On first open this tab will be empty because the plug-in hasn't run yet.

1. Save the profile as-is and click **Update Imported Bank Data** once from the profile's action bar. This triggers the plug-in's `getAccounts()` step and populates the list with every active Bank / Credit Card account in your NetSuite instance.
2. Re-open the profile and go to the **Account Linking** subtab.
3. For each account you want to feed, set **Linked GL Account** to the matching NetSuite GL account and an **Earliest Transaction Date for Import** (dates before this are ignored).
4. Save.

### 3d. Import Schedule (optional)

- Set a schedule (every 6 hours is a common default) if you want NetSuite to pull automatically.
- Leave it off if your orchestration will click **Update Imported Bank Data** on demand.

---

## 4. Connect Apideck Unify

1. In the **Apideck Vault**, open your NetSuite connection.
2. In NetSuite, go to **Customization → Scripting → Scripts → Apideck Bank Feed RESTlet**. On the **Deployments** tab, each row shows an **External URL** containing `script=<numeric>` and `deploy=<numeric>` — note these two numeric IDs.
3. In the Unify connection settings, enter:
   - **Bank Feed RESTlet Script ID** — the numeric `script` value.
   - **Bank Feed RESTlet Deploy ID** — the numeric `deploy` value.
4. Save.

Your NetSuite connection is now ready to receive bank feed statements through the Apideck Unify API. See the [Accounting API reference](/apis/accounting/reference#tag/Bank-Feed-Statements) for the `bank-feed-statements` endpoint used to push transactions.

### Verify with a test statement

To confirm the full pipe works end-to-end, POST a small statement and then check that the transactions show up under **Banking → Match Bank Data**.

**POST**

`https://unify.apideck.com/accounting/bank-feed-statements`

[API Reference](/apis/accounting/reference#tag/Bank-Feed-Statements/operation/bankFeedStatementsAdd)

**Request body example:**

```json
{
  "bank_feed_account_id": "{your-bank-feed-account-id}",
  "start_date": "2026-04-01T00:00:00.000Z",
  "end_date": "2026-04-22T23:59:59.000Z",
  "start_balance": 10000.0,
  "start_balance_credit_or_debit": "debit",
  "end_balance": 10300.0,
  "end_balance_credit_or_debit": "debit",
  "transactions": [
    {
      "posted_date": "2026-04-05T00:00:00.000Z",
      "amount": 500.0,
      "credit_or_debit": "credit",
      "source_transaction_id": "apideck-test-001",
      "description": "Customer payment — Acme Corp",
      "counterparty": "Acme Corp",
      "reference": "INV-2026-042",
      "transaction_type": "payment"
    },
    {
      "posted_date": "2026-04-10T00:00:00.000Z",
      "amount": 100.0,
      "credit_or_debit": "debit",
      "source_transaction_id": "apideck-test-002",
      "description": "Office supplies — Globex Inc",
      "counterparty": "Globex Inc",
      "reference": "PO-1234",
      "transaction_type": "payment"
    },
    {
      "posted_date": "2026-04-15T00:00:00.000Z",
      "amount": 100.0,
      "credit_or_debit": "debit",
      "source_transaction_id": "apideck-test-003",
      "description": "SaaS subscription — Initech",
      "counterparty": "Initech SaaS",
      "reference": "SUB-APR-2026",
      "transaction_type": "payment"
    }
  ]
}
```

>
> Replace <code>{'{your-bank-feed-account-id}'}</code> with the ID of a bank feed account that maps to one of the GL accounts you linked in §3c. Start and end balances must reconcile with the transactions: <code>start_balance</code> + sum of credits − sum of debits = <code>end_balance</code>. In this example: 10,000 + 500 − 100 − 100 = 10,300.

After a successful POST, trigger an import in NetSuite (or wait for the scheduled run from §3d). The three transactions should appear on the linked GL account, ready to reconcile.

---

## 5. Day-to-day operations

- **Import history**: Banking → Banking Import History.
- **Failed imports**: click a failed row; NetSuite provides a downloadable `CSV_Import_*.csv` with per-row error reasons. Contact Apideck support and include that CSV if the error is unclear.
- **Retention**: the scheduled maintenance script marks stale _Pending_ staging records as _Error_ after 7 days and deletes _Success_ records after 30 days. Contact Apideck support if you need different retention.

---

## Conclusion

Integrating with NetSuite's bank feeds via Apideck gives your customers an automated, reconciliation-ready flow from your platform straight into **Match Bank Data** — no CSV uploads, no manual entry, and no separate auth flow beyond the Token-Based Authentication you already set up.

Once the bundle is installed, the Format Profile is configured, and the RESTlet IDs are saved in Vault, every statement you POST through the Accounting API lands in NetSuite on the next import cycle, ready for your users to reconcile.

---

## Related Resources

- [Apideck NetSuite Connector](https://www.apideck.com/connectors/netsuite)
- [Apideck Accounting API — Bank Feed Statements](/apis/accounting/reference#tag/Bank-Feed-Statements)
- [Apideck Accounting API — Bank Feed Accounts](/apis/accounting/reference#tag/Bank-Feed-Accounts)
- [How to Integrate Xero Bank Feeds Using Apideck](/guides/bank-feeds-xero)
- [Accounting Data Model](/guides/accounting-data-model)
