Skip to main content

OAuth 1.0 Token-Based Authentication (TBA) Setup Guide

This comprehensive guide walks you through implementing Token-Based Authentication (TBA) in NetSuite, from initial configuration to testing with Postman.


Overview

What is Token-Based Authentication (TBA)?

Token-Based Authentication (TBA) is NetSuite's implementation of OAuth 1.0. It provides secure API access without requiring user passwords.

┌────────────────────────────────────────────────────────────────────────┐
│ TOKEN-BASED AUTHENTICATION COMPONENTS │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Integration Record ──► Consumer Key + Consumer Secret │
│ │ │
│ ▼ │
│ Access Token ──────► Token ID + Token Secret (per user/role) │
│ │ │
│ ▼ │
│ API Request ───────► OAuth 1.0 Signature (all 4 values) │
│ │
└────────────────────────────────────────────────────────────────────────┘

OAuth 1.0 vs OAuth 2.0

AspectOAuth 1.0 (TBA)OAuth 2.0
ComplexityMore complex (signature required)Simpler (bearer token)
Token ExpiryTokens don't expireTokens expire (need refresh)
Use CaseLong-running integrationsModern M2M integrations
SetupEasier initial setupRequires certificate
PostmanBuilt-in OAuth 1.0 supportRequires JWT generation

TBA Authentication Flow


Prerequisites

Before starting, ensure you have:

  • NetSuite Administrator role or equivalent permissions
  • Access to Setup > Company > Enable Features
  • Access to Setup > Integration > Manage Integrations
  • Postman installed for testing

Step 1: Enable Token-Based Authentication Feature

First, enable TBA in your NetSuite account.

┌──────────────────────────────────────────────────────────────────────────┐
│ ENABLE TBA FEATURE │
└──────────────────────────────────────────────────────────────────────────┘

Navigate to:
Setup → Company → Enable Features → SuiteCloud

Enable:
┌────────────────────────────────────────────────────────────────────┐
│ ☑ Token-Based Authentication │
│ ☑ REST Web Services (for REST API) │
│ ☑ SOAP Web Services (for SOAP API) │
│ ☑ SuiteScript (if using RESTlets) │
└────────────────────────────────────────────────────────────────────┘

Detailed Steps:

  1. Go to Setup → Company → Enable Features
  2. Click on the SuiteCloud subtab
  3. Under Manage Authentication, check:
    • Token-Based Authentication
  4. Under SuiteTalk (Web Services), check:
    • REST Web Services (if using REST API)
    • SOAP Web Services (if using SOAP API)
  5. Click Save
Important

You must have the Administrator role to enable these features. Changes take effect immediately.


Step 2: Create Integration Record

The integration record identifies your external application and provides the Consumer Key and Secret.

┌──────────────────────────────────────────────────────────────────────────┐
│ CREATE INTEGRATION RECORD │
└──────────────────────────────────────────────────────────────────────────┘

Navigate to:
Setup → Integration → Manage Integrations → New

Integration Record Configuration

FieldValueNotes
NameMy TBA IntegrationDescriptive name for your app
StateEnabledMust be enabled to use
Token-Based Authentication☑ CheckedRequired for TBA
TBA: Authorization Flow☑ CheckedEnable token management
OAuth 2.0☐ UncheckedNot needed for TBA

Detailed Steps:

  1. Go to Setup → Integration → Manage Integrations
  2. Click New
  3. Fill in the form:
┌────────────────────────────────────────────────────────────────────────┐
│ INTEGRATION RECORD FORM │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Name: [My TBA Integration ] │
│ │
│ Description: [Token-Based Auth for external API access ] │
│ │
│ State: [● Enabled ○ Blocked] │
│ │
│ ───────────────────────────────────────────────────────────────── │
│ AUTHENTICATION │
│ ───────────────────────────────────────────────────────────────── │
│ │
│ ☑ Token-Based Authentication │
│ └─ ☑ TBA: Authorization Flow │
│ │
│ ☐ OAuth 2.0 │
│ │
└────────────────────────────────────────────────────────────────────────┘
  1. Click Save

After Saving - IMPORTANT!

After saving, NetSuite displays your credentials ONLY ONCE:

┌────────────────────────────────────────────────────────────────────────┐
│ ⚠️ SAVE THESE CREDENTIALS IMMEDIATELY │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Consumer Key: │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0 │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ Consumer Secret: │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0f9e8d7c6b5a4z3y2x1w0 │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ⚠️ Copy these now! They cannot be retrieved later. │
│ │
└────────────────────────────────────────────────────────────────────────┘
Critical

Copy and securely store the Consumer Key and Consumer Secret immediately. They are shown only once and cannot be retrieved later. If lost, you must create a new integration record.


Step 3: Assign Integration to Role

Before users can create access tokens, the integration must be assigned to their role.

┌──────────────────────────────────────────────────────────────────────────┐
│ ASSIGN INTEGRATION TO ROLE │
└──────────────────────────────────────────────────────────────────────────┘

Navigate to:
Setup → Users/Roles → Manage Roles → [Select Role]

Detailed Steps:

  1. Go to Setup → Users/Roles → Manage Roles
  2. Click Edit on the role that will use TBA (e.g., Administrator, or a custom role)
  3. Scroll down to the Setup subtab
  4. Find the Access Token Management section
  5. Set permissions:
┌────────────────────────────────────────────────────────────────────────┐
│ ROLE PERMISSIONS - SETUP SUBTAB │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Permission Level │
│ ───────────────────────────────────────────────────────────────── │
│ Access Token Management [Full ▼] │
│ Log in using Access Tokens [Full ▼] │
│ User Access Tokens [Full ▼] │
│ │
└────────────────────────────────────────────────────────────────────────┘
  1. Click Save

Alternative: Quick Role Setup

If creating a new role for API access:

PermissionLevelPurpose
Access Token ManagementFullManage access tokens
Log in using Access TokensFullAllow API authentication
User Access TokensFullCreate/view own tokens
REST Web ServicesFullAccess REST API
SuiteQLFullRun SuiteQL queries

Step 4: Create Access Token

Each user who needs API access must create their own access token.

┌──────────────────────────────────────────────────────────────────────────┐
│ CREATE ACCESS TOKEN │
└──────────────────────────────────────────────────────────────────────────┘

Navigate to:
Setup → Users/Roles → Access Tokens → New

Access Token Flow

Detailed Steps:

  1. Go to Setup → Users/Roles → Access Tokens
  2. Click New
  3. Fill in the form:
┌────────────────────────────────────────────────────────────────────────┐
│ ACCESS TOKEN FORM │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Application: [My TBA Integration ▼] │
│ (Select the integration created in Step 2) │
│ │
│ User: [John Developer ▼] │
│ (Select the user for this token) │
│ │
│ Role: [Administrator ▼] │
│ (Select role - determines permissions) │
│ │
│ Token Name: [API Access - Production ] │
│ (Optional descriptive name) │
│ │
└────────────────────────────────────────────────────────────────────────┘
  1. Click Save

After Saving - IMPORTANT!

After saving, NetSuite displays the token credentials ONLY ONCE:

┌────────────────────────────────────────────────────────────────────────┐
│ ⚠️ SAVE THESE TOKEN CREDENTIALS IMMEDIATELY │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Token ID: │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t1u2v3w4x5y6z7a8b9c0d │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ Token Secret: │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ 9z8y7x6w5v4u3t2s1r0q9p8o7n6m5l4k3j2i1h0g9f8e7d6c5b4a3z2y1x0w │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ⚠️ Copy these now! They cannot be retrieved later. │
│ │
└────────────────────────────────────────────────────────────────────────┘
Critical

Copy and securely store the Token ID and Token Secret immediately. They are shown only once and cannot be retrieved later. If lost, you must revoke the token and create a new one.


Step 5: Gather All Credentials

At this point, you should have collected 4 credential values:

┌────────────────────────────────────────────────────────────────────────┐
│ TBA CREDENTIALS SUMMARY │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ From Integration Record (Step 2): │
│ ───────────────────────────────────────────────────────────────── │
│ 1. Consumer Key: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6... │
│ 2. Consumer Secret: z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4... │
│ │
│ From Access Token (Step 4): │
│ ───────────────────────────────────────────────────────────────── │
│ 3. Token ID: 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p... │
│ 4. Token Secret: 9z8y7x6w5v4u3t2s1r0q9p8o7n6m5l4k... │
│ │
│ Account Information: │
│ ───────────────────────────────────────────────────────────────── │
│ 5. Account ID: 1234567 (or 1234567_SB1 for sandbox) │
│ 6. Realm: 1234567 (same as Account ID, no underscore) │
│ │
└────────────────────────────────────────────────────────────────────────┘

Finding Your Account ID

Your Account ID can be found:

  1. URL: Look at your NetSuite URL - https://1234567.app.netsuite.com/...
  2. Company Info: Setup → Company → Company Information
Realm vs Account ID

For OAuth 1.0, the Realm is your Account ID but without any underscore suffix:

  • Account ID: 1234567_SB1 → Realm: 1234567
  • Account ID: 1234567 → Realm: 1234567

Step 6: Test with Postman

Now let's test the TBA authentication using Postman.

Configure OAuth 1.0 in Postman

  1. Open Postman and create a new request
  2. Click on the Authorization tab
  3. Select OAuth 1.0 from the Type dropdown
┌────────────────────────────────────────────────────────────────────────┐
│ POSTMAN AUTHORIZATION SETTINGS │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Type: [OAuth 1.0 ▼] │
│ │
│ ───────────────────────────────────────────────────────────────── │
│ Add authorization data to: [Request Headers ▼] │
│ │
│ Consumer Key: [your_consumer_key_here ] │
│ Consumer Secret: [your_consumer_secret_here ] │
│ Access Token: [your_token_id_here ] │
│ Token Secret: [your_token_secret_here ] │
│ │
│ Signature Method: [HMAC-SHA256 ▼] │
│ Timestamp: [Auto ] │
│ Nonce: [Auto ] │
│ Version: [1.0 ] │
│ │
│ Realm: [1234567 ] │
│ (Account ID without _SB suffix) │
│ │
└────────────────────────────────────────────────────────────────────────┘

OAuth 1.0 Settings

FieldValueNotes
TypeOAuth 1.0Select from dropdown
Add auth data toRequest HeadersRequired for NetSuite
Consumer KeyFrom Step 2Integration consumer key
Consumer SecretFrom Step 2Integration consumer secret
Access TokenFrom Step 4Token ID
Token SecretFrom Step 4Token secret
Signature MethodHMAC-SHA256NetSuite requires SHA256
RealmAccount IDWithout _SB suffix
Signature Method

NetSuite requires HMAC-SHA256 signature method. Using HMAC-SHA1 will result in authentication errors.


Step 7: Test REST API Call

Test 1: SuiteQL Query

Let's run a simple SuiteQL query to verify authentication.

Request Configuration:

SettingValue
MethodPOST
URLhttps://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql
HeadersContent-Type: application/json, Prefer: transient

Request Body:

{
"q": "SELECT id, companyname, email FROM customer WHERE rownum <= 5"
}

Full Request Example:

┌────────────────────────────────────────────────────────────────────────┐
│ POSTMAN REQUEST │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ POST ▼ https://1234567.suitetalk.api.netsuite.com/services/rest/ │
│ query/v1/suiteql │
│ │
│ ───────────────────────────────────────────────────────────────── │
│ Authorization Headers Body ... │
│ ───────────────────────────────────────────────────────────────── │
│ │
│ Headers: │
│ ┌──────────────────────┬────────────────────────────────────────┐ │
│ │ Content-Type │ application/json │ │
│ ├──────────────────────┼────────────────────────────────────────┤ │
│ │ Prefer │ transient │ │
│ └──────────────────────┴────────────────────────────────────────┘ │
│ │
│ Body (raw - JSON): │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ { │ │
│ │ "q": "SELECT id, companyname, email FROM customer │ │
│ │ WHERE rownum <= 5" │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘

Expected Response (200 OK):

{
"links": [...],
"count": 5,
"hasMore": true,
"items": [
{
"links": [],
"id": "123",
"companyname": "ABC Company",
"email": "contact@abc.com"
},
...
],
"offset": 0,
"totalResults": 1250
}

Test 2: Get Record

Retrieve a specific customer record.

Request Configuration:

SettingValue
MethodGET
URLhttps://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/record/v1/customer/123

Expected Response (200 OK):

{
"links": [...],
"id": "123",
"companyName": "ABC Company",
"email": "contact@abc.com",
"phone": "555-1234",
...
}

Complete TBA Flow Diagram


Troubleshooting

Common Errors

Error: "Invalid login attempt"

{
"type": "https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2",
"title": "Unauthorized",
"status": 401,
"o:errorDetails": [
{
"detail": "Invalid login attempt.",
"o:errorCode": "INVALID_LOGIN"
}
]
}

Solutions:

CheckSolution
Consumer Key/SecretVerify copied correctly from Integration record
Token ID/SecretVerify copied correctly from Access Token
Signature MethodMust be HMAC-SHA256 (not SHA1)
RealmUse Account ID without _SB suffix
Token StatusEnsure token is not revoked

Error: "Invalid signature"

{
"o:errorDetails": [
{
"detail": "Invalid signature",
"o:errorCode": "INVALID_SIGNATURE"
}
]
}

Solutions:

  1. Ensure Signature Method is set to HMAC-SHA256
  2. Ensure Add authorization data to is set to Request Headers
  3. Check that no extra spaces in credentials
  4. Regenerate the signature (Postman does this automatically)

Error: "Permission denied"

Solutions:

  1. Check user's role has required permissions
  2. Verify the Access Token was created with correct role
  3. Ensure role has access to the record type you're querying

API Endpoints Reference

Common NetSuite REST API Endpoints

EndpointMethodDescription
/services/rest/query/v1/suiteqlPOSTRun SuiteQL queries
/services/rest/record/v1/{recordType}GETList records
/services/rest/record/v1/{recordType}/{id}GETGet single record
/services/rest/record/v1/{recordType}POSTCreate record
/services/rest/record/v1/{recordType}/{id}PATCHUpdate record
/services/rest/record/v1/{recordType}/{id}DELETEDelete record

URL Format

https://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/...
EnvironmentAccount ID FormatExample URL
Production1234567https://1234567.suitetalk.api.netsuite.com/...
Sandbox1234567_SB1https://1234567-sb1.suitetalk.api.netsuite.com/...
URL Format for Sandbox

Note that sandbox URLs use a hyphen (-sb1) instead of underscore (_SB1) in the subdomain.


Security Best Practices

┌────────────────────────────────────────────────────────────────────────┐
│ TBA SECURITY BEST PRACTICES │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ ✅ DO: │
│ ├─► Store credentials in secure vault (not code) │
│ ├─► Use environment variables for credentials │
│ ├─► Create separate tokens for each application/environment │
│ ├─► Use roles with minimum required permissions │
│ ├─► Regularly audit active tokens │
│ └─► Revoke unused tokens immediately │
│ │
│ ❌ DON'T: │
│ ├─► Hardcode credentials in source code │
│ ├─► Share tokens between applications │
│ ├─► Use Administrator role for integrations │
│ ├─► Commit credentials to version control │
│ └─► Share credentials via email/chat │
│ │
└────────────────────────────────────────────────────────────────────────┘

Token Management

ActionWhen to Use
Create new tokenNew application, new environment, new user
Revoke tokenSecurity incident, user leaves, app decommissioned
Create separate tokensEach environment (dev, staging, prod)

Postman Collection Export

Save this as a Postman collection for easy import:

{
"info": {
"name": "NetSuite TBA API",
"description": "NetSuite REST API with Token-Based Authentication",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"auth": {
"type": "oauth1",
"oauth1": [
{ "key": "consumerKey", "value": "{{consumer_key}}", "type": "string" },
{ "key": "consumerSecret", "value": "{{consumer_secret}}", "type": "string" },
{ "key": "token", "value": "{{token_id}}", "type": "string" },
{ "key": "tokenSecret", "value": "{{token_secret}}", "type": "string" },
{ "key": "signatureMethod", "value": "HMAC-SHA256", "type": "string" },
{ "key": "realm", "value": "{{realm}}", "type": "string" },
{ "key": "addParamsToHeader", "value": true, "type": "boolean" }
]
},
"variable": [
{ "key": "base_url", "value": "https://{{account_id}}.suitetalk.api.netsuite.com" },
{ "key": "account_id", "value": "YOUR_ACCOUNT_ID" },
{ "key": "realm", "value": "YOUR_REALM" },
{ "key": "consumer_key", "value": "YOUR_CONSUMER_KEY" },
{ "key": "consumer_secret", "value": "YOUR_CONSUMER_SECRET" },
{ "key": "token_id", "value": "YOUR_TOKEN_ID" },
{ "key": "token_secret", "value": "YOUR_TOKEN_SECRET" }
],
"item": [
{
"name": "SuiteQL Query",
"request": {
"method": "POST",
"header": [
{ "key": "Content-Type", "value": "application/json" },
{ "key": "Prefer", "value": "transient" }
],
"body": {
"mode": "raw",
"raw": "{\n \"q\": \"SELECT id, companyname FROM customer WHERE rownum <= 10\"\n}"
},
"url": {
"raw": "{{base_url}}/services/rest/query/v1/suiteql",
"host": ["{{base_url}}"],
"path": ["services", "rest", "query", "v1", "suiteql"]
}
}
},
{
"name": "Get Customer",
"request": {
"method": "GET",
"url": {
"raw": "{{base_url}}/services/rest/record/v1/customer/123",
"host": ["{{base_url}}"],
"path": ["services", "rest", "record", "v1", "customer", "123"]
}
}
}
]
}

How to Import:

  1. Copy the JSON above
  2. In Postman, click Import
  3. Select Raw Text and paste
  4. Update the variables with your actual credentials
  5. Start testing!

Summary

┌────────────────────────────────────────────────────────────────────────┐
│ TBA SETUP CHECKLIST │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ ☑ Step 1: Enable TBA feature in NetSuite │
│ ☑ Step 2: Create Integration Record → Consumer Key/Secret │
│ ☑ Step 3: Configure role permissions for TBA │
│ ☑ Step 4: Create Access Token → Token ID/Secret │
│ ☑ Step 5: Collect all 4 credentials + Account ID │
│ ☑ Step 6: Configure Postman OAuth 1.0 (HMAC-SHA256) │
│ ☑ Step 7: Test API calls │
│ │
│ Required Credentials: │
│ ├─► Consumer Key (from Integration) │
│ ├─► Consumer Secret (from Integration) │
│ ├─► Token ID (from Access Token) │
│ ├─► Token Secret (from Access Token) │
│ └─► Realm (Account ID without suffix) │
│ │
└────────────────────────────────────────────────────────────────────────┘