Working with NetSuite's SuiteTalk REST Web Services API
how to use NetSuite SuiteTalk REST Web Services API
Also searched as
- netsuite rest record api pagination expandSubResources
- netsuite suiteql query endpoint
- netsuite rest api vs soap webservices
- netsuite rest api limit offset hasMore
Short answer
SuiteTalk REST exposes NetSuite records at https://ACCOUNTID.suitetalk.api.netsuite.com/services/rest/record/v1/{recordType}/{id} and ad hoc SQL-like queries at /services/rest/query/v1/suiteql, both authenticated with TBA or OAuth 2.0. It returns JSON, paginates large result sets with limit/offset and a hasMore flag, and needs expandSubResources or a specific fields query to pull sublist and related data efficiently.
Applies to: NetSuite SuiteTalk REST Web Services, all supported record types and SuiteQL
Call SuiteTalk REST correctly
- 1Build the base URL from the account ID: https://ACCOUNTID.suitetalk.api.netsuite.com/services/rest/record/v1/ for records, replacing dashes appropriately for sandbox accounts (ACCOUNTID-sb1, all lowercase, dash not underscore, for the REST host specifically).
- 2Authenticate every request with a TBA Authorization header or an OAuth 2.0 bearer token; there is no separate REST-specific credential beyond the standard NetSuite auth methods.
- 3GET a single record with /record/v1/{recordType}/{id}, for example /record/v1/salesorder/12345, which returns core fields and links to sublists rather than inlining them by default.
- 4Add ?expandSubResources=true to inline sublist and subrecord data directly in the response instead of requiring a follow-up call per sublist link.
- 5For search-style listing, GET /record/v1/{recordType} with q= for simple filters, or use limit and offset query parameters to page through results; the response includes totalResults, hasMore and links.next for the following page.
- 6For arbitrary joins and aggregation, POST SuiteQL to /query/v1/suiteql with the query in the request body and a Prefer: transient header, then page using the same limit/offset pattern on the response.
- 7Use PATCH for partial record updates (only the fields sent are changed) and PUT for a full replace; POST creates a new record and returns its id in the Location response header rather than the body.
- 8Handle 404 (record does not exist or the role cannot see it), 400 with INVALID_FLD_VALUE-style error bodies for bad field values, and 403/INSUFFICIENT_PERMISSION for role restrictions, all returned as a JSON error object with a 'o:errorDetails' array.
REST versus SOAP SuiteTalk
SOAP SuiteTalk (the older platform.core / platform.messages WSDL-based API) is still supported and remains common in older integrations built before the REST API matured, but new integrations are steered toward REST because it is simpler to authenticate, easier to consume from modern HTTP clients, and returns plain JSON instead of SOAP envelopes.
REST does not yet cover every corner of SOAP's functionality for every record type, so some legacy integrations (particularly around certain financial or advanced order management records) still use SOAP for operations the REST layer does not expose, and it is worth checking NetSuite's REST record catalog before assuming full parity.
Pagination and expandSubResources in practice
By default, list endpoints return a compact representation with just id and a self link for each item, which keeps payloads small but means a naive client ends up making one follow-up GET per record. Passing specific fields via the q parameter or a fields projection, and expandSubResources where sublists are needed, cuts this down significantly.
hasMore in the response tells you whether to continue paging; do not assume the absence of a 'next' link means you are done, and always check totalResults against the count of records actually retrieved when reconciling data, since some filtered views can undercount if permissions hide rows the querying role cannot see.
GET /services/rest/record/v1/salesorder?limit=100&offset=200
Authorization: Bearer <token>
{
"links": [...],
"count": 100,
"hasMore": true,
"totalResults": 4820,
"items": [ { "id": "98765", "links": [...] }, ... ]
}SuiteQL for read-heavy integrations
SuiteQL lets you write a SQL-like SELECT against NetSuite's underlying tables (transaction, transactionline, customer, item, and many more), which is far more efficient than record-by-record REST calls when you need joins, aggregation or a large filtered extract for a data warehouse or BI tool.
SuiteQL is read-only and does not support DDL or DML; use it to query, and use the record endpoints (or SuiteScript) for writes. The Prefer: transient header is required on the query POST or NetSuite rejects it, which is a common first-time integration mistake.
Common pitfalls
- !Forgetting Prefer: transient on SuiteQL POST requests and getting a confusing error instead of results.
- !Assuming REST covers every field and sublist that SOAP or the UI exposes for a given record type; some are still SOAP or SuiteScript-only.
- !Not paging past the default limit and silently processing only the first page of a large dataset.
- !Using PUT when PATCH was intended, wiping fields that were not included in the request body.
- !Hitting concurrency or rate limits on burst imports without backing off, which returns 429-style throttling errors under SuiteTalk's own governance separate from SuiteScript governance.
How an ERP-grounded AI assistant handles this
ERPray grounded on a customer's NetSuite schema can translate a plain-English data request straight into a validated SuiteQL query or the correct REST call sequence, including the expandSubResources and pagination details that usually take a few failed attempts to get right by hand. That is often the fastest path from 'I need this data out of NetSuite' to a working integration script.
Frequently asked questions
Can SuiteTalk REST create records with sublists in one call?
Yes, POST the parent record with a sublist array in the body (for example a sales order with an item sublist) and NetSuite creates the parent and its lines together, similar to how record.create with sublists works in SuiteScript.
Is SuiteQL the same as saved search formulas?
No. SuiteQL is a direct SQL-like query language against NetSuite's tables, giving you full joins and aggregation, whereas saved searches are built through NetSuite's search UI/API abstraction. SuiteQL is generally more flexible for ad hoc reporting and BI extracts.
How do I find the exact REST endpoint for a custom record type?
Custom records are exposed under /record/v1/{customRecordScriptId} once the record type has REST access enabled on its definition (Customization > Lists, Records, & Fields > Record Types > the record > Access tab), not automatically for every custom record.
Why do I get INSUFFICIENT_PERMISSION on a record that exists in the UI?
The role behind the token needs explicit view/edit permission on that record type and any restricted fields; being able to see a record as an administrator in the browser does not imply the integration role has the same access.
Related
Authenticating NetSuite RESTlets with OAuth 2.0 and Token-Based Authentication
NetSuite RESTlets can be called with either Token-Based Authentication (TBA, OAuth 1.0a signed requests) or OAuth 2.0, and both require a Setup > Integrations > Manage Integrations record before any token is issued. Machine-to-machine OAuth 2.0 uses a client credentials grant with a JWT bearer assertion signed by a certificate; TBA uses a consumer key/secret plus a per-user access token signed with HMAC-SHA256.
AdvancedSetting up NetSuite SuiteAnalytics Connect for ODBC and JDBC access
SuiteAnalytics Connect is a separately licensed feature that exposes a read-only relational view of NetSuite data over ODBC or JDBC for BI tools like Power BI, Tableau and Excel. Setup means enabling the feature, downloading the driver, configuring a DSN against the account's connect host, and using a role with the SuiteAnalytics Connect permission.
AdvancedAvoiding governance limit errors in NetSuite Map/Reduce scripts
A NetSuite Map/Reduce script gives each map or reduce invocation of a key its own fresh governance allotment instead of sharing one pool across the whole run, so most SSS_USAGE_LIMIT_EXCEEDED failures come from a single key doing too much work, not from the total record count. Fix it by moving heavy logic out of getInputData, keeping map and reduce functions idempotent and cheap per key, and checking runtime.getCurrentScript().getRemainingUsage() before expensive calls.
Error fixFix NetSuite SSS_USAGE_LIMIT_EXCEEDED Error
SSS_USAGE_LIMIT_EXCEEDED fires when a SuiteScript execution consumes all the governance units (usage points) allotted to its script type before it finishes. Fix it by checking runtime.getCurrentScript().getRemainingUsage() before expensive calls, yielding or rescheduling in Scheduled scripts, and moving heavy record-count work into Map/Reduce, which yields automatically across stages.
Error fixFix NetSuite INVALID_FLD_VALUE Error
INVALID_FLD_VALUE means NetSuite rejected a value you tried to set on a field because it does not match the field's expected type, list option, or reference record. Fix it by confirming the internal ID or text value actually exists on that field's source list and matches the field's value type (text versus list versus record reference) before setting it.
Error fixFix NetSuite SSS_MISSING_REQD_ARGUMENT Error
SSS_MISSING_REQD_ARGUMENT means a NetSuite API call, most often record.create(), record.load(), or search.create(), was called without a parameter that method requires, such as type or id. Fix it by checking the object literal you passed against the current SuiteScript 2.x API signature and confirming no required key is undefined at runtime.
AI for ERPAI for NetSuite, Beyond the Built-In Text Tools
NetSuite's built-in AI covers text generation, not grounded answers on your own data. See how a private LLM over SuiteQL adds real Q&A and controls.
AI for ERPAI agents for NetSuite manufacturing operations
AI agents for NetSuite manufacturing: WIP tracking, routing exceptions, and work order status grounded in SuiteQL, with human approval on anything that writes back.
Stuck on Oracle NetSuite?
Talk to engineers who work inside Oracle NetSuite every week, and who build private AI that answers these questions from your own ERP data.