OAuth 2.0 is the modern standard for API authentication. NetSuite supports OAuth 2.0 through the Client Credentials flow (machine-to-machine) and the Authorization Code Grant flow (user-facing apps). This tutorial covers both flows and how to get a Bearer token to use with the NetSuite REST APIs.
OAuth 2.0 vs. TBA: Which Should You Use?
- TBA (OAuth 1.0a) β older standard, works great, widely supported for RESTlets and REST API
- OAuth 2.0 Client Credentials β best for server-to-server integrations (no user login required)
- OAuth 2.0 Authorization Code β best for apps where users log in with their NetSuite credentials
Step 1: Enable OAuth 2.0 in NetSuite
- Go to Setup > Company > Enable Features.
- Click the SuiteCloud tab.
- Check OAuth 2.0 under Manage Authentication.
- Click Save.
Step 2: Create an Integration Record for OAuth 2.0
- Go to Setup > Integration > Manage Integrations > New.
- Enter a Name (e.g., “My OAuth 2.0 App”).
- Under Authentication:
β For Client Credentials flow: check Client Credentials (Machine to Machine)
β For Authorization Code flow: check Authorization Code Grant and enter your Redirect URI - Click Save.
- Copy the Client ID and Client Secret (shown only once).
Flow 1: Client Credentials (Machine-to-Machine)
This is the recommended flow for server integrations where no user interaction is needed.
Step 3a: Assign a Certificate (Required for Client Credentials)
NetSuite’s Client Credentials flow requires a JWT signed with a private key certificate instead of using the client secret directly.
- Generate a private/public key pair:
openssl req -x509 -newkey rsa:4096 -keyout private.pem -out certificate.pem -days 365 -nodes
- In NetSuite, go to Setup > Integration > OAuth 2.0 Client Credentials Setup.
- Click Create New, select your Integration, choose the Role, and upload your certificate.pem.
- Save and copy the Certificate ID.
Step 3b: Get an Access Token (Python)
import jwt
import time
import uuid
import requests
ACCOUNT_ID = 'your_account_id' # e.g., 1234567
CLIENT_ID = 'your_client_id'
CERTIFICATE_ID = 'your_certificate_id'
with open('private.pem', 'r') as f:
private_key = f.read()
# Build JWT assertion
now = int(time.time())
payload = {
'iss': CLIENT_ID,
'scope': 'restlets rest_webservices',
'aud': f'https://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token',
'exp': now + 3600,
'iat': now,
'jti': str(uuid.uuid4())
}
headers = {'kid': CERTIFICATE_ID}
assertion = jwt.encode(payload, private_key, algorithm='RS256', headers=headers)
# Request access token
token_url = f'https://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token'
response = requests.post(token_url, data={
'grant_type': 'client_credentials',
'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
'client_assertion': assertion
})
token_data = response.json()
access_token = token_data['access_token']
print(f'Access token: {access_token[:20]}...')
Step 3c: Use the Token to Call the REST API
# Call the REST Record API with Bearer token
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
customer_url = f'https://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/record/v1/customer/12345'
response = requests.get(customer_url, headers=headers)
print(response.json())
Flow 2: Authorization Code Grant (User Login)
Use this flow when users need to authenticate with their own NetSuite credentials.
Step 4: Redirect User to Authorization URL
https://[account-id].app.netsuite.com/app/login/oauth2/authorize.nl ?response_type=code &client_id=[CLIENT_ID] &redirect_uri=[YOUR_REDIRECT_URI] &scope=restlets%20rest_webservices &state=[RANDOM_STATE]
The user logs in and NetSuite redirects back to your redirect URI with a code parameter.
Step 5: Exchange Code for Token
POST https://[account-id].suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token Body (form-urlencoded): grant_type=authorization_code code=[AUTHORIZATION_CODE] redirect_uri=[YOUR_REDIRECT_URI] client_id=[CLIENT_ID] client_secret=[CLIENT_SECRET]
Response includes access_token, refresh_token, and expires_in.
Step 6: Refresh Tokens
POST https://[account-id].suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token Body: grant_type=refresh_token refresh_token=[YOUR_REFRESH_TOKEN] client_id=[CLIENT_ID] client_secret=[CLIENT_SECRET]
Available OAuth 2.0 Scopes
- restlets β access to SuiteScript RESTlets
- rest_webservices β access to REST Record API
- suite_analytics β access to SuiteAnalytics workbooks
OAuth 2.0 Security Best Practices
- Store tokens securely β never in browser localStorage or client-side code.
- Use short-lived access tokens (NetSuite tokens expire in 60 minutes by default).
- Implement token refresh logic to avoid re-authenticating constantly.
- Validate the
stateparameter in the Authorization Code flow to prevent CSRF attacks. - Use HTTPS for all token requests and API calls.
- Scope tokens to the minimum permissions needed.
Congratulations β Series Complete!
You’ve completed the NetSuite RESTlet & REST API Tutorial Series. You now know how to:
- Create and deploy a RESTlet in NetSuite
- Call RESTlets from Postman, Python, and Node.js
- Use the REST Record API for CRUD operations
- Secure your integrations with TBA and OAuth 2.0
Return to the NetSuite RESTlet & REST API Tutorials series index for more resources.