Skip to main content
NewNetSuite 2026.1 — What's new
NetSuite

NetSuite REST API: Complete Developer Guide (2026)

Guide to the NetSuite REST API — authentication, CRUD operations, SuiteQL queries, record types, error handling, rate limits, and REST vs SOAP comparison.

··9 min read

What is the NetSuite REST API?

The NetSuite REST API — officially named SuiteTalk REST Web Services — is Oracle NetSuite's modern HTTP/JSON interface for reading and writing records programmatically. Unlike the legacy SOAP API, it uses standard REST conventions: GET to read, POST to create, PATCH to update, and DELETE to remove records. SuiteQL (a SQL-like query language) is also exposed through the same REST endpoint, making it the single integration surface for most use cases.

NetSuite provides two APIs for external integration: the legacy SOAP-based web services and the newer REST API. The REST API is the recommended approach for new integrations — it's simpler, more performant, and better documented.

TL;DR: The NetSuite REST API provides RESTful CRUD operations on all standard and custom record types, SuiteQL for SQL-like queries, and JSON payloads. Authentication uses OAuth 2.0 (or OAuth 1.0 / Token-Based Authentication for backward compatibility). The REST API browser at https://{accountId}.suitetalk.api.netsuite.com/rest/platform/v1/metadata-catalog provides interactive documentation for all available record types and fields. Rate limits apply — 10 concurrent requests per account for REST API, with additional throttling at high volumes.


Authentication

Token-Based Authentication (TBA)

The most common authentication method for server-to-server integrations:

  1. Create an integration record: Setup > Integration > Manage Integrations > New

    • Enable Token-Based Authentication
    • Record the Consumer Key and Consumer Secret
  2. Create a token: Setup > Users/Roles > Access Tokens > New

    • Select the application (integration record)
    • Select the user and role
    • Record the Token ID and Token Secret
  3. Sign requests: Use OAuth 1.0 signature with:

    • Consumer Key + Consumer Secret (application level)
    • Token ID + Token Secret (user level)
    • Account ID
    • Nonce and timestamp

Each request includes an Authorization header with the OAuth 1.0 signature.

OAuth 2.0

For web applications and scenarios requiring delegated authorization:

  1. Register the application: Create an integration record with OAuth 2.0 enabled
  2. Authorization flow: User is redirected to NetSuite login, grants access, and receives an authorization code
  3. Token exchange: Exchange the authorization code for access and refresh tokens
  4. API requests: Include the access token in the Authorization header as a Bearer token
  5. Token refresh: Access tokens expire — use the refresh token to obtain new ones

OAuth 2.0 is preferred for applications where users authenticate interactively, while TBA is preferred for background integrations.


Need a custom NetSuite integration built?

REST API, RESTlets, SuiteTalk, OAuth setup — we've shipped 150+ integrations since 2017. Senior devs, no junior hand-offs.

Scope my integration

Making API requests

Base URL

Example: base URL pattern for all REST API requests

https://{accountId}.suitetalk.api.netsuite.com/services/rest/

Replace {accountId} with your NetSuite account ID (e.g., 1234567 or 1234567_SB1 for sandbox).

Record operations (CRUD)

Create a record (POST):

Example: create a new customer record

POST /services/rest/record/v1/customer
Content-Type: application/json
 
{
  "companyName": "Acme Corp",
  "email": "info@acme.com",
  "subsidiary": {"id": "1"}
}

Read a record (GET):

Example: get a single customer by internal ID

GET /services/rest/record/v1/customer/123

Returns JSON with all accessible fields for the record.

Update a record (PATCH):

Example: update specific fields on an existing customer

PATCH /services/rest/record/v1/customer/123
Content-Type: application/json
 
{
  "phone": "555-0123",
  "email": "new@acme.com"
}

PATCH updates only the specified fields. PUT replaces the entire record.

Delete a record (DELETE):

Example: permanently delete a customer record

DELETE /services/rest/record/v1/customer/123

Sublists (line items)

Records with sublists (e.g., sales order lines, vendor bill lines) include nested arrays:

Example: POST body for a sales order with two line items

{
  "entity": {"id": "123"},
  "item": {
    "items": [
      {
        "item": {"id": "456"},
        "quantity": 10,
        "rate": 25.00
      },
      {
        "item": {"id": "789"},
        "quantity": 5,
        "rate": 50.00
      }
    ]
  }
}

Filtering and querying records

List records with filters:

Example: get all customers whose company name contains "Acme"

GET /services/rest/record/v1/customer?q=companyName CONTAIN "Acme"

Pagination:

Example: retrieve the first 100 customer records

GET /services/rest/record/v1/customer?limit=100&offset=0

Default page size is 1000 records. Use limit and offset for pagination through large result sets.


SuiteQL

SuiteQL is NetSuite's SQL-like query language, accessible through the REST API. It's the most powerful way to extract data.

Endpoint:

Example: run a SuiteQL query to retrieve customers created in 2026

POST /services/rest/query/v1/suiteql
Content-Type: application/json
Prefer: transient
 
{
  "q": "SELECT id, companyname, email FROM customer WHERE datecreated > '2026-01-01'"
}

SuiteQL capabilities

  • JOIN across related tables
  • Aggregate functions (SUM, COUNT, AVG, MAX, MIN)
  • GROUP BY and HAVING
  • Subqueries
  • Built-in functions (TO_DATE, NVL, CASE)

Example queries

Top 10 customers by revenue:

Example: SuiteQL query — top 10 customers by invoiced revenue in 2026

SELECT
  c.companyname,
  SUM(tl.netamount) as total_revenue
FROM transaction t
JOIN transactionline tl ON t.id = tl.transaction
JOIN customer c ON t.entity = c.id
WHERE t.type = 'CustInvc'
  AND t.trandate >= '2026-01-01'
GROUP BY c.companyname
ORDER BY total_revenue DESC
FETCH FIRST 10 ROWS ONLY

Open purchase orders by vendor:

Example: SuiteQL query — count and total open purchase orders grouped by vendor

SELECT
  v.companyname as vendor,
  COUNT(t.id) as open_pos,
  SUM(t.foreigntotal) as total_amount
FROM transaction t
JOIN vendor v ON t.entity = v.id
WHERE t.type = 'PurchOrd'
  AND t.status = 'PurchOrd:B'
GROUP BY v.companyname
ORDER BY total_amount DESC

SuiteQL vs. saved searches

SuiteQL is more flexible than saved searches for complex queries:

  • JOINs across any tables (saved searches have limited join paths)
  • Subqueries and CTEs
  • Union queries
  • Better performance on large data sets
  • Programmatic access through the API

Saved searches are better for:

  • Scheduled reports and email alerts
  • Dashboard portlets
  • User-facing interfaces where non-developers need to modify criteria

REST API Browser

The REST API browser is your interactive documentation:

Example: REST API browser URL for your NetSuite account

https://{accountId}.suitetalk.api.netsuite.com/rest/platform/v1/metadata-catalog

For each record type, it shows:

  • All available fields with data types
  • Required vs. optional fields
  • Sublist structures
  • Available operations (GET, POST, PATCH, DELETE)
  • Field-level help text

Use the browser to explore record schemas before writing integration code. It's more reliable than documentation sites because it reflects your actual NetSuite configuration, including custom fields and custom record types.


RESTlets vs. REST API

NetSuite has two REST-related features that are often confused:

REST API (SuiteTalk REST): The standard API for CRUD operations on records. No custom code required. Works with any standard or custom record type.

RESTlets: Custom SuiteScript endpoints that you write and deploy. RESTlets are SuiteScript 2.x scripts that handle HTTP requests and can execute any business logic — not just CRUD operations.

When to use REST API: Standard operations — create records, read records, update records, query data with SuiteQL.

When to use RESTlets: Custom business logic — calculate pricing, validate data against custom rules, execute workflows, aggregate data across multiple record types in a single API call, or any operation that doesn't map to a simple CRUD action.


Rate limits and performance

Concurrency limits

  • REST API: 10 concurrent requests per account (can be increased with additional licenses)
  • RESTlets: Shared concurrency with REST API
  • SuiteQL: Counted within REST API concurrency

Request throttling

NetSuite throttles requests when you exceed limits:

  • HTTP 429 (Too Many Requests) response
  • Retry-After header indicates when to retry

Performance tips

Use SuiteQL for bulk reads. A single SuiteQL query returning 1,000 records is much faster than 1,000 individual GET requests.

Use PATCH, not PUT. PATCH updates only the fields you specify. PUT replaces the entire record, which is slower and riskier.

Batch operations. For creating or updating multiple records, consider the REST API's batch endpoint or process records in parallel (within concurrency limits).

Minimize round trips. Use expandSubResources=true to include sublists in a single GET request instead of fetching the record and then each sublist separately.

Cache the metadata catalog. Don't query the metadata catalog on every request — cache it and refresh periodically.


Common error codes and fixes

Understanding the HTTP status codes returned by the REST API speeds up debugging significantly.

HTTP statusMeaningCommon causeFix
400 Bad RequestInvalid payload or field valueWrong field name, missing required field, wrong data typeCheck the REST API Browser for required fields and field IDs
401 UnauthorizedAuthentication failureWrong Consumer Key, Token ID, or OAuth signatureRegenerate tokens; verify account ID in base URL matches the token
403 ForbiddenPermission deniedRole missing permission for the record type or operationAdd the required permission in Setup > Users/Roles > Roles
404 Not FoundRecord does not existWrong internal ID or wrong account (sandbox vs. production)Confirm the record ID and that you're hitting the right account URL
429 Too Many RequestsRate limit exceededMore than 10 concurrent requestsBack off and retry after the Retry-After response header value (seconds)
500 Internal Server ErrorServer-side errorMalformed SuiteQL query, locked record, scripting conflictCheck the error message body; SuiteQL syntax errors appear as 500s

Handling 429 errors in code

When you receive a 429, read the Retry-After header before retrying:

Example: retry logic for 429 rate limit responses (Python)

import time
import requests
 
def request_with_retry(url, headers, max_retries=5):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)
        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 5))
            time.sleep(retry_after)
            continue
        response.raise_for_status()
        return response
    raise Exception("Max retries exceeded")

REST API vs. SOAP API

FeatureREST APISOAP API
ProtocolHTTP + JSONSOAP + XML
AuthenticationOAuth 1.0 / 2.0TBA or OAuth
Query languageSuiteQLSaved search criteria
Payload sizeSmaller (JSON)Larger (XML)
DocumentationREST API BrowserWSDL + records browser
Learning curveLowerHigher
Custom recordsSupportedSupported
Bulk operationsSuiteQL, batchSearch, getList
PerformanceGenerally fasterSlower (XML overhead)

Recommendation: Use the REST API for all new integrations. Use SOAP only if you're maintaining an existing integration that was built on SOAP, or if you need a specific feature only available in SOAP (increasingly rare).


Sources and references

  • Oracle NetSuite SuiteTalk REST Web Services Documentation — NetSuite Help Center (login required). Covers record types, field definitions, authentication flows, and the REST API browser.
  • Oracle NetSuite SuiteQL Reference — NetSuite Help Center. Documents supported tables, joins, aggregate functions, and built-in functions available through the SuiteQL endpoint.
  • Oracle NetSuite SuiteScript 2.x Developer Guide — NetSuite Help Center. Reference for writing RESTlets and other server-side scripts that extend the REST API.
  • Oracle NetSuite Token-Based Authentication Guide — NetSuite Help Center. Step-by-step instructions for generating Consumer Key/Secret and Token ID/Secret pairs.
  • OAuth 2.0 Authorization Code Flow for NetSuite — NetSuite Help Center. Details the authorization code grant flow, token endpoints, and refresh token handling.
  • SuiteCloud Development Framework (SDF) Documentation — NetSuite Help Center. Covers deploying and managing integrations, scripts, and customizations as code.

What clients ask before signing

Joaquin Vigna

Joaquin Vigna

Co-Founder & CTO

Co-founder and Chief Technology Officer at BrokenRubik with 12+ years of experience in software architecture and NetSuite development. Leads technical strategy, innovation initiatives, and ensures delivery excellence across all projects.

12+ years experienceOracle NetSuite Certified +1
Technical ArchitectureSuiteScript DevelopmentNetSuite CustomizationSystem Integration+2 more

Get in Touch