If you’ve searched for “NetSuite integration” lately, you’re not alone β it’s one of the fastest-growing searches among NetSuite professionals right now. Businesses everywhere are connecting NetSuite to Shopify, Salesforce, custom apps, and third-party platforms. The key that unlocks all of this? The NetSuite REST API.
In this guide, you’ll learn exactly what the NetSuite REST API is, how authentication works, and how to make your first real API call β step by step, with no fluff. By the end, you’ll be able to pull, create, and update NetSuite records from any external system.
What Is the NetSuite REST API?
NetSuite offers several ways to connect with the outside world. The REST API (also called the NetSuite REST Web Services) is the modern, standards-based approach. It uses plain HTTP requests β the same technology powering every website β which means you can call it from virtually any programming language: Python, JavaScript, PHP, Java, C#, or even a simple tool like Postman.
With the REST API you can:
- Read records β fetch customers, invoices, sales orders, items, and any other NetSuite record type.
- Create records β add new customers, sales orders, or any supported record directly into NetSuite.
- Update records β modify an existing record’s fields using a PATCH or PUT request.
- Delete records β remove records when needed.
- Run SuiteQL queries β execute powerful SQL-style queries through the REST API endpoint.
NetSuite REST API vs. SOAP API vs. SuiteScript: Which Should You Use?
NetSuite has multiple integration options. Here’s a quick comparison so you know when to choose the REST API:
| Method | Best For | Skill Required |
|---|---|---|
| REST API | External system integrations, modern apps, any language | HTTP basics, JSON |
| SOAP API | Legacy integrations, older enterprise systems | XML, WSDL knowledge |
| SuiteScript | Server-side automation inside NetSuite | JavaScript |
| SuiteFlow (Workflow) | No-code automation within NetSuite | None |
| CSV Import | One-time or scheduled bulk data loads | Basic file handling |
Choose the REST API when you need to connect an external application (e.g., your website, a mobile app, or a third-party service) to NetSuite in real-time.
Step 1: Set Up OAuth 2.0 Authentication in NetSuite
The NetSuite REST API uses OAuth 2.0 with Client Credentials (machine-to-machine) for server-to-server integrations. This is the most common setup for automated integrations. Here’s how to set it up:
1.1 Create an Integration Record in NetSuite
- In NetSuite, go to Setup > Integration > Manage Integrations > New.
- Give your integration a name (e.g., “My App Integration”).
- Under Authentication, check OAuth 2.0 and select Client Credentials (Machine to Machine).
- Click Save. NetSuite will generate a Client ID and Client Secret. Save these immediately β the secret is shown only once.
1.2 Assign a Role to the Integration
Your integration needs permissions to access NetSuite data. You assign this by mapping a NetSuite role to your integration:
- Go to Setup > Integration > OAuth 2.0 Client Credentials (M2M) Setup.
- Click New and select your integration, a user (a dedicated API user is recommended), and the role you want that user to use.
- Click Save.
Make sure the role you assign has the appropriate permissions for the records you’ll be accessing (e.g., View/Create/Edit on Customer, Sales Order, etc.).
Step 2: Get an Access Token
Before you can call the NetSuite REST API, you need an access token. You get one by sending a token request to NetSuite’s token endpoint. Here’s the format:
Token Request (HTTP)
POST https://{accountId}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token
Headers:
Content-Type: application/x-www-form-urlencoded
Body (form-encoded):
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Replace {accountId} with your NetSuite account ID (visible in the URL when you log in, e.g., 1234567).
Token Request in Python
Here is a complete Python example that gets an access token and then uses it to fetch a customer record:
import requests
# βββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Configuration β replace these with your real values
# βββββββββββββββββββββββββββββββββββββββββββββββββββββ
ACCOUNT_ID = "1234567" # Your NetSuite Account ID
CLIENT_ID = "your_client_id" # From the Integration record
CLIENT_SECRET = "your_client_secret"
# Step 1: Build the token URL using your account ID
TOKEN_URL = f"https://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token"
# Step 2: Request an access token
token_response = requests.post(
TOKEN_URL,
data={
"grant_type": "client_credentials",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
},
headers={"Content-Type": "application/x-www-form-urlencoded"}
)
# Step 3: Parse the token from the response
token_data = token_response.json()
access_token = token_data["access_token"]
print(f"β
Access token received! Expires in {token_data['expires_in']} seconds.")
A successful response looks like this:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
"token_type": "Bearer",
"expires_in": 3600
}
The token is valid for 60 minutes. After it expires, simply request a new one using the same credentials.
Step 3: Make Your First REST API Call β Fetch a Customer Record
Now that you have a token, you can call the NetSuite REST API. Let’s fetch a customer record. The base URL for REST API record operations follows this pattern:
https://{accountId}.suitetalk.api.netsuite.com/services/rest/record/v1/{recordType}/{internalId}
For a customer with internal ID 42, the URL would be:
https://1234567.suitetalk.api.netsuite.com/services/rest/record/v1/customer/42
Full Python Example: Get a Customer
import requests
ACCOUNT_ID = "1234567"
access_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6..." # From Step 2
# The internal ID of the customer record you want to fetch
CUSTOMER_ID = 42
# Build the API URL
api_url = (
f"https://{ACCOUNT_ID}.suitetalk.api.netsuite.com"
f"/services/rest/record/v1/customer/{CUSTOMER_ID}"
)
# Make the GET request with the Bearer token in the Authorization header
response = requests.get(
api_url,
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
)
# Parse and print the customer data
customer = response.json()
print("Customer Details:")
print(f" Name: {customer.get('companyName', 'N/A')}")
print(f" Email: {customer.get('email', 'N/A')}")
print(f" Phone: {customer.get('phone', 'N/A')}")
print(f" Internal ID: {customer.get('id', 'N/A')}")
Sample Output
Customer Details:
Name: Acme Corporation
Email: billing@acme.com
Phone: +1 (555) 123-4567
Internal ID: 42
Step 4: Create a New Record via REST API
Creating a new record is just as straightforward β you send a POST request with the record data as a JSON body. Here’s how to create a new Customer record:
import requests
import json
ACCOUNT_ID = "1234567"
access_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6..."
api_url = f"https://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/record/v1/customer"
# The new customer data in JSON format
new_customer = {
"companyName": "BlueSky Technologies",
"email": "hello@bluesky.com",
"phone": "555-987-6543",
"subsidiary": {"id": "1"}, # Required: your primary subsidiary's internal ID
"isPerson": False
}
response = requests.post(
api_url,
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
},
data=json.dumps(new_customer)
)
# A 204 status code means the record was created successfully
if response.status_code == 204:
# The new record's internal ID is in the Location header
new_record_url = response.headers.get("Location", "")
new_id = new_record_url.split("/")[-1]
print(f"β
Customer created! New Internal ID: {new_id}")
else:
print(f"β Error {response.status_code}: {response.text}")
NetSuite returns an HTTP 204 No Content on successful creation, with the new record’s URL in the Location response header. That’s where you can extract the new internal ID.
Step 5: Run a SuiteQL Query via REST API
One of the most powerful features of the NetSuite REST API is the ability to run SuiteQL queries β SQL-like queries that can fetch and aggregate data across multiple record types. This is done through the /suiteql endpoint:
import requests
import json
ACCOUNT_ID = "1234567"
access_token = "eyJhbGciOiJSUzI1NiIsInR5cCI6..."
suiteql_url = f"https://{ACCOUNT_ID}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql"
# SuiteQL query: get all customers with their name and email
suiteql_query = {
"q": """
SELECT
id,
companyname AS company_name,
email
FROM
customer
WHERE
isinactive = 'F'
ORDER BY
companyname ASC
LIMIT 10
"""
}
response = requests.post(
suiteql_url,
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
"Prefer": "transient" # Required for SuiteQL endpoint
},
data=json.dumps(suiteql_query)
)
results = response.json()
print(f"Total records returned: {results.get('count', 0)}")
print()
for row in results.get("items", []):
print(f"ID: {row['id']} | Company: {row['company_name']} | Email: {row['email']}")
Sample Output
Total records returned: 10
ID: 42 | Company: Acme Corporation | Email: billing@acme.com
ID: 87 | Company: BlueSky Technologies | Email: hello@bluesky.com
ID: 105 | Company: Orion Retail Group | Email: orders@orionretail.com
...
Common Mistakes and How to Avoid Them
Here are the most frequent issues developers run into when getting started with the NetSuite REST API:
1. Wrong Account ID Format
Your NetSuite account ID may contain underscores (e.g., 1234567_SB1 for a sandbox). In the API URL, replace the underscore with a hyphen: 1234567-sb1.suitetalk.api.netsuite.com. Sandbox URLs also use all lowercase letters.
2. Missing the “Prefer: transient” Header for SuiteQL
The SuiteQL endpoint requires the header Prefer: transient on every request. Without it, you’ll receive a 400 error. It’s easy to miss β don’t forget it.
3. Insufficient Role Permissions
If you get a 403 Forbidden error, it almost always means the role mapped to your integration doesn’t have permission for the record type or operation you’re attempting. Go back to your role in NetSuite and add the required permissions (e.g., “Customers: Full” or “Sales Orders: View”).
4. Token Expiry
Tokens expire after 60 minutes. For long-running integrations, build a simple token refresh mechanism: check if the token is expired before each request, and if so, fetch a new one automatically.
Key REST API Endpoints Quick Reference
| Action | HTTP Method | Endpoint |
|---|---|---|
| Get a record | GET | /record/v1/{type}/{id} |
| List records | GET | /record/v1/{type} |
| Create a record | POST | /record/v1/{type} |
| Full update | PUT | /record/v1/{type}/{id} |
| Partial update | PATCH | /record/v1/{type}/{id} |
| Delete a record | DELETE | /record/v1/{type}/{id} |
| Run SuiteQL query | POST | /query/v1/suiteql |
| Get OAuth token | POST | /auth/oauth2/v1/token |
Summary
The NetSuite REST API is one of the most powerful and versatile ways to integrate NetSuite with any external system. Once you have OAuth 2.0 set up, making API calls is straightforward β just an HTTP request with a Bearer token.
Here’s a quick recap of what we covered today:
- The NetSuite REST API lets you read, create, update, and delete any NetSuite record from any language or platform.
- Authentication uses OAuth 2.0 Client Credentials β set it up once in the Integration record and the M2M setup screen.
- Request an access token by POSTing your Client ID and Secret to the token endpoint.
- Use GET to fetch records, POST to create, PATCH to partially update, and DELETE to remove.
- Use the
/suiteqlendpoint with thePrefer: transientheader to run powerful SQL-style queries. - Watch out for sandbox URL formatting, role permissions, and token expiry.
Now you have everything you need to build your first NetSuite REST API integration. Start with Postman to test your calls, then move them into your preferred language. Happy integrating!
Discover more from The NetSuite Pro
Subscribe to get the latest posts sent to your email.
Leave a Reply