Deploy your first customer portal →
SuitePortal/NetSuite ORM

NetSuite Setup

Step-by-step guide to configuring Token-Based Authentication or OAuth 2.0 M2M in NetSuite for SuitePortal.

SuitePortal supports two authentication methods. Choose one based on your needs:

MethodWhen to Use
Token-Based Auth (TBA)Quick setup, existing integrations
OAuth 2.0 M2MCertificate-based, no user tokens, recommended for new integrations

Both methods require enabling a few shared features in NetSuite first.

Shared Prerequisites

Enable Required Features

Navigate to Setup > Company > Enable Features > SuiteCloud and enable:

FeatureRequiredWhy
REST Web ServicesYesSuitePortal uses the REST Record API for mutations and metadata
SuiteQLYesSuitePortal queries NetSuite using SuiteQL
SuiteScriptRecommendedRequired if you plan to use suiteportal pull to download SuiteScript files

Save the page after enabling these features.

After a sandbox refresh, these features may be reset. If you get unexpected authentication errors after a refresh, verify they are still enabled.

Create a Role with Required Permissions

The role assigned to your integration must have specific permissions. You can use an existing role or create a new one.

Navigate to Setup > Users/Roles > Manage Roles and edit your role (or create a new one). Under the Permissions subtab, add these:

Setup tab:

PermissionLevel
Log in using Access TokensFull
REST Web ServicesFull

Reports tab:

PermissionLevel
SuiteQLFull

The REST Web Services permission is critical. Without it, all API calls will return 401 Unauthorized with an INVALID_LOGIN error — even if your credentials are correct.

You may also want to add permissions for the specific record types you plan to query (e.g., Customers, Sales Orders, etc.) under the Transactions, Lists, and Custom Record tabs.

Find Your Account ID

Find your account ID at Setup > Company > Company Information. The Account ID field shows your account identifier.

.env
NETSUITE_ACCOUNT_ID=1234567_SB1

Sandbox accounts include a suffix like _SB1. SuitePortal accepts both underscore and hyphen formats (1234567_SB1 or 1234567-sb1) and normalizes automatically.

Now follow the setup for your chosen authentication method:


Token-Based Authentication (TBA)

TBA uses OAuth 1.0a. You'll create an integration record and an access token.

Enable TBA Feature

Navigate to Setup > Company > Enable Features > SuiteCloud and enable:

FeatureRequired
Token-Based AuthenticationYes

Create an Integration Record

Navigate to Setup > Integration > Manage Integrations > New.

FieldValue
NameSuitePortal (or any name you prefer)
StateEnabled
Token-Based AuthenticationChecked

Click Save. NetSuite will display your Consumer Key and Consumer Secret. Copy both immediately — they are only shown once.

.env
NETSUITE_CONSUMER_KEY=your_consumer_key_here
NETSUITE_CONSUMER_SECRET=your_consumer_secret_here

If you reset the consumer credentials later, all existing access tokens for this integration are invalidated. You must create a new access token after resetting.

Create an Access Token

Navigate to Setup > Users/Roles > Access Tokens > New.

FieldValue
ApplicationSelect the integration you created (e.g., SuitePortal)
UserYour NetSuite user
RoleThe role with the permissions above

Click Save. NetSuite will display your Token ID and Token Secret. Copy both immediately — they are only shown once.

.env
NETSUITE_TOKEN_ID=your_token_id_here
NETSUITE_TOKEN_SECRET=your_token_secret_here

Complete .env for TBA

.env
NETSUITE_AUTH_TYPE=tba
NETSUITE_ACCOUNT_ID=1234567_SB1
NETSUITE_CONSUMER_KEY=abc123...
NETSUITE_CONSUMER_SECRET=def456...
NETSUITE_TOKEN_ID=ghi789...
NETSUITE_TOKEN_SECRET=jkl012...

OAuth 2.0 Machine-to-Machine (M2M)

OAuth 2.0 M2M uses the Client Credentials grant with a JWT signed by your private key. No user-specific tokens are needed — identity is determined by the certificate mapping in NetSuite.

Generate a Key Pair

Create an EC P-256 key pair on your local machine. This is the recommended algorithm — you can also use EC P-384, EC P-521, or RSA-PSS (3072+ bit).

openssl req -new -x509 -newkey ec \
  -pkeyopt ec_paramgen_curve:prime256v1 \
  -nodes -days 365 \
  -out public.pem -keyout private.pem \
  -subj "/CN=SuitePortal"

This creates two files:

  • public.pem — upload this to NetSuite
  • private.pem — keep this secret, used by SuitePortal to sign JWTs

Maximum certificate validity is 2 years (730 days). You can have up to 5 active certificates per integration.

Create an Integration Record

Navigate to Setup > Integration > Manage Integrations > New.

FieldValue
NameSuitePortal (or any name you prefer)
StateEnabled
Client Credentials (Machine to Machine) GrantChecked

Under Scope, enable the scopes your integration needs:

ScopeWhen to Enable
REST Web ServicesAlways (required for SuitePortal)
RESTletsIf your integration calls RESTlets
SuiteAnalytics ConnectIf using SuiteAnalytics

Click Save. NetSuite will display your Client ID (also called Consumer Key). Copy it immediately.

.env
NETSUITE_CLIENT_ID=your_client_id_here

Create the M2M Certificate Mapping

Navigate to Setup > Integration > OAuth 2.0 Client Credentials (M2M) Setup.

Click Create New and configure:

FieldValue
EntityThe NetSuite user/entity to authenticate as
RoleThe role with the permissions from the prerequisites
ApplicationSelect the integration you created
CertificateUpload your public.pem file

Click Save. NetSuite will display a Certificate ID. Copy it immediately — this is the kid (Key ID) used in the JWT header.

.env
NETSUITE_CERTIFICATE_ID=your_certificate_id_here

Write down the Certificate ID immediately. It is only displayed once after saving. If you lose it, you'll need to create a new certificate mapping.

Add Your Private Key

Add the contents of private.pem to your .env file. Since .env files don't support multiline values, replace newlines with literal \n:

# Convert the key to a single line
cat private.pem | tr '\n' '\\' | sed 's/\\/\\n/g'

Then paste the result:

.env
NETSUITE_PRIVATE_KEY=-----BEGIN EC PRIVATE KEY-----\nMHQCAQEE...base64...==\n-----END EC PRIVATE KEY-----

Alternatively, you can load the key from a file in your code when using the programmatic API:

privateKey: fs.readFileSync('./private.pem', 'utf8')

Complete .env for OAuth 2.0 M2M

.env
NETSUITE_AUTH_TYPE=oauth2
NETSUITE_ACCOUNT_ID=1234567_SB1
NETSUITE_CLIENT_ID=abc123...
NETSUITE_CERTIFICATE_ID=xyz789...
NETSUITE_PRIVATE_KEY=-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----

Optional variables:

VariableDefaultDescription
NETSUITE_ALGORITHMES256Must match your key type (EC → ES256, RSA-PSS → PS256)
NETSUITE_SCOPESrestlets,rest_webservicesComma-separated scopes

Verify Your Connection

Run a quick test to confirm everything is working:

npx suiteportal introspect

If you see your account ID and records being discovered, you're all set.

Troubleshooting

401 Unauthorized / INVALID_LOGIN

This is almost always one of these:

  1. Role missing REST Web Services permission — the most common issue. Edit the role under Setup > Users/Roles > Manage Roles and add "REST Web Services" with Full access under the Setup permissions tab.
  2. (TBA) Consumer credentials were reset after the access token was created — create a new access token.
  3. (OAuth 2.0) Certificate ID is wrong — verify the certificate ID matches the one shown during M2M setup.
  4. (OAuth 2.0) Private key doesn't match the uploaded certificate — regenerate the key pair and re-upload.
  5. Sandbox was refreshed — all integrations, tokens, and M2M mappings are wiped. Recreate from scratch.
  6. Wrong credentials in .env — double-check all values have no extra whitespace.

OAuth 2.0: invalid_grant

This usually means:

  • The JWT exp is more than 60 minutes from iat
  • The certificate has expired (check the -days value used during generation)
  • The algorithm in your .env doesn't match your key type (e.g., ES256 with an RSA key)

Login Audit Trail

To debug authentication failures, check Setup > Users/Roles > User Management > View Login Audit Trail. Look for recent "Failure" entries matching your IP address.

For a detailed comparison of both auth methods and when to use each, see the Authentication guide.

On this page